Create codecs with dependency injection

This will allow the RSA private key to be injected in the login packet
codec.
master
Graham 2 years ago
parent af3477776c
commit 73defefef4
  1. 7
      archive/src/main/kotlin/org/openrs2/archive/cache/OsrsJs5ChannelInitializer.kt
  2. 2
      game/src/main/kotlin/org/openrs2/game/GameModule.kt
  3. 12
      game/src/main/kotlin/org/openrs2/game/net/Rs2ChannelInitializer.kt
  4. 12
      game/src/main/kotlin/org/openrs2/game/net/login/LoginChannelHandler.kt
  5. 44
      protocol/src/main/kotlin/org/openrs2/protocol/Protocol.kt
  6. 81
      protocol/src/main/kotlin/org/openrs2/protocol/ProtocolModule.kt
  7. 8
      protocol/src/main/kotlin/org/openrs2/protocol/js5/Js5RemoteDownstream.kt
  8. 4
      protocol/src/main/kotlin/org/openrs2/protocol/login/ClientOutOfDateCodec.kt
  9. 4
      protocol/src/main/kotlin/org/openrs2/protocol/login/InitCrossDomainConnectionCodec.kt
  10. 4
      protocol/src/main/kotlin/org/openrs2/protocol/login/InitGameConnectionCodec.kt
  11. 4
      protocol/src/main/kotlin/org/openrs2/protocol/login/InitJaggrabConnectionCodec.kt
  12. 4
      protocol/src/main/kotlin/org/openrs2/protocol/login/InitJs5RemoteConnectionCodec.kt
  13. 4
      protocol/src/main/kotlin/org/openrs2/protocol/login/IpLimitCodec.kt
  14. 4
      protocol/src/main/kotlin/org/openrs2/protocol/login/Js5OkCodec.kt
  15. 8
      protocol/src/main/kotlin/org/openrs2/protocol/login/LoginDownstream.kt
  16. 8
      protocol/src/main/kotlin/org/openrs2/protocol/login/LoginUpstream.kt
  17. 4
      protocol/src/main/kotlin/org/openrs2/protocol/login/RequestWorldListCodec.kt
  18. 4
      protocol/src/main/kotlin/org/openrs2/protocol/login/ServerFullCodec.kt
  19. 8
      protocol/src/main/kotlin/org/openrs2/protocol/world/WorldListDownstream.kt
  20. 20
      protocol/src/main/kotlin/org/openrs2/protocol/world/WorldListResponseCodec.kt

@ -6,13 +6,16 @@ import io.netty.handler.timeout.ReadTimeoutHandler
import org.openrs2.protocol.Protocol
import org.openrs2.protocol.Rs2Decoder
import org.openrs2.protocol.Rs2Encoder
import org.openrs2.protocol.login.ClientOutOfDateCodec
import org.openrs2.protocol.login.InitJs5RemoteConnectionCodec
import org.openrs2.protocol.login.Js5OkCodec
public class OsrsJs5ChannelInitializer(private val handler: OsrsJs5ChannelHandler) : ChannelInitializer<Channel>() {
override fun initChannel(ch: Channel) {
ch.pipeline().addLast(
ReadTimeoutHandler(30),
Rs2Encoder(Protocol.LOGIN_UPSTREAM),
Rs2Decoder(Protocol.JS5REMOTE_DOWNSTREAM)
Rs2Encoder(Protocol(InitJs5RemoteConnectionCodec())),
Rs2Decoder(Protocol(Js5OkCodec(), ClientOutOfDateCodec()))
)
ch.pipeline().addLast("handler", handler)
}

@ -18,6 +18,7 @@ import org.openrs2.game.cluster.SingleWorldCluster
import org.openrs2.game.net.NetworkService
import org.openrs2.game.net.js5.Js5Service
import org.openrs2.net.NetworkModule
import org.openrs2.protocol.ProtocolModule
public object GameModule : AbstractModule() {
override fun configure() {
@ -25,6 +26,7 @@ public object GameModule : AbstractModule() {
install(CacheModule)
install(ConfigModule)
install(NetworkModule)
install(ProtocolModule)
val binder = Multibinder.newSetBinder(binder(), Service::class.java)
binder.addBinding().to(GameService::class.java)

@ -7,6 +7,8 @@ import org.openrs2.game.net.login.LoginChannelHandler
import org.openrs2.protocol.Protocol
import org.openrs2.protocol.Rs2Decoder
import org.openrs2.protocol.Rs2Encoder
import org.openrs2.protocol.login.LoginDownstream
import org.openrs2.protocol.login.LoginUpstream
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Provider
@ -14,13 +16,17 @@ import javax.inject.Singleton
@Singleton
public class Rs2ChannelInitializer @Inject constructor(
private val handlerProvider: Provider<LoginChannelHandler>
private val handlerProvider: Provider<LoginChannelHandler>,
@LoginUpstream
private val loginUpStreamProtocol: Protocol,
@LoginDownstream
private val loginDownStreamProtocol: Protocol
) : ChannelInitializer<Channel>() {
override fun initChannel(ch: Channel) {
ch.pipeline().addLast(
IdleStateHandler(true, TIMEOUT_SECS, TIMEOUT_SECS, TIMEOUT_SECS, TimeUnit.SECONDS),
Rs2Decoder(Protocol.LOGIN_UPSTREAM),
Rs2Encoder(Protocol.LOGIN_DOWNSTREAM),
Rs2Decoder(loginUpStreamProtocol),
Rs2Encoder(loginDownStreamProtocol),
handlerProvider.get()
)
}

@ -20,11 +20,13 @@ import org.openrs2.protocol.Protocol
import org.openrs2.protocol.Rs2Decoder
import org.openrs2.protocol.Rs2Encoder
import org.openrs2.protocol.jaggrab.JaggrabRequestDecoder
import org.openrs2.protocol.js5.Js5RemoteDownstream
import org.openrs2.protocol.js5.Js5RequestDecoder
import org.openrs2.protocol.js5.Js5ResponseEncoder
import org.openrs2.protocol.js5.XorDecoder
import org.openrs2.protocol.login.LoginRequest
import org.openrs2.protocol.login.LoginResponse
import org.openrs2.protocol.world.WorldListDownstream
import org.openrs2.protocol.world.WorldListResponse
import javax.inject.Inject
import javax.inject.Provider
@ -32,7 +34,11 @@ import javax.inject.Provider
public class LoginChannelHandler @Inject constructor(
private val cluster: Cluster,
private val js5HandlerProvider: Provider<Js5ChannelHandler>,
private val jaggrabHandler: JaggrabChannelHandler
private val jaggrabHandler: JaggrabChannelHandler,
@Js5RemoteDownstream
private val js5RemoteDownstreamProtocol: Protocol,
@WorldListDownstream
private val worldListDownstreamProtocol: Protocol
) : SimpleChannelInboundHandler<LoginRequest>(LoginRequest::class.java) {
override fun channelActive(ctx: ChannelHandlerContext) {
ctx.read()
@ -50,7 +56,7 @@ public class LoginChannelHandler @Inject constructor(
private fun handleInitJs5RemoteConnection(ctx: ChannelHandlerContext, msg: LoginRequest.InitJs5RemoteConnection) {
val encoder = ctx.pipeline().get(Rs2Encoder::class.java)
encoder.protocol = Protocol.JS5REMOTE_DOWNSTREAM
encoder.protocol = js5RemoteDownstreamProtocol
if (msg.build != BUILD) {
ctx.write(LoginResponse.ClientOutOfDate).addListener(ChannelFutureListener.CLOSE)
@ -105,7 +111,7 @@ public class LoginChannelHandler @Inject constructor(
}
val encoder = ctx.pipeline().get(Rs2Encoder::class.java)
encoder.protocol = Protocol.WORLD_LIST_DOWNSTREAM
encoder.protocol = worldListDownstreamProtocol
ctx.write(WorldListResponse(worldList, players)).addListener(ChannelFutureListener.CLOSE)
}

@ -1,17 +1,12 @@
package org.openrs2.protocol
import org.openrs2.protocol.login.ClientOutOfDateCodec
import org.openrs2.protocol.login.InitCrossDomainConnectionCodec
import org.openrs2.protocol.login.InitGameConnectionCodec
import org.openrs2.protocol.login.InitJaggrabConnectionCodec
import org.openrs2.protocol.login.InitJs5RemoteConnectionCodec
import org.openrs2.protocol.login.IpLimitCodec
import org.openrs2.protocol.login.Js5OkCodec
import org.openrs2.protocol.login.RequestWorldListCodec
import org.openrs2.protocol.login.ServerFullCodec
import org.openrs2.protocol.world.WorldListResponseCodec
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
public class Protocol @Inject constructor(codecs: Set<PacketCodec<*>>) {
public constructor(vararg codecs: PacketCodec<*>) : this(codecs.toSet())
public class Protocol(vararg codecs: PacketCodec<*>) {
private val decoders = arrayOfNulls<PacketCodec<*>>(256)
private val encoders = codecs.associateBy(PacketCodec<*>::type)
@ -30,31 +25,4 @@ public class Protocol(vararg codecs: PacketCodec<*>) {
public fun <T : Packet> getEncoder(type: Class<T>): PacketCodec<T>? {
return encoders[type] as PacketCodec<T>?
}
public companion object {
public val LOGIN_UPSTREAM: Protocol = Protocol(
InitGameConnectionCodec,
InitJs5RemoteConnectionCodec,
InitJaggrabConnectionCodec,
RequestWorldListCodec,
InitCrossDomainConnectionCodec
)
public val LOGIN_DOWNSTREAM: Protocol = Protocol(
ClientOutOfDateCodec,
ServerFullCodec,
IpLimitCodec
)
public val JS5REMOTE_DOWNSTREAM: Protocol = Protocol(
Js5OkCodec,
ClientOutOfDateCodec,
ServerFullCodec,
IpLimitCodec
)
public val WORLD_LIST_DOWNSTREAM: Protocol = Protocol(
WorldListResponseCodec
)
}
}

@ -0,0 +1,81 @@
package org.openrs2.protocol
import com.google.inject.AbstractModule
import com.google.inject.PrivateModule
import com.google.inject.TypeLiteral
import com.google.inject.multibindings.Multibinder
import org.openrs2.buffer.BufferModule
import org.openrs2.crypto.CryptoModule
import org.openrs2.protocol.js5.Js5RemoteDownstream
import org.openrs2.protocol.login.ClientOutOfDateCodec
import org.openrs2.protocol.login.InitCrossDomainConnectionCodec
import org.openrs2.protocol.login.InitGameConnectionCodec
import org.openrs2.protocol.login.InitJaggrabConnectionCodec
import org.openrs2.protocol.login.InitJs5RemoteConnectionCodec
import org.openrs2.protocol.login.IpLimitCodec
import org.openrs2.protocol.login.Js5OkCodec
import org.openrs2.protocol.login.LoginDownstream
import org.openrs2.protocol.login.LoginUpstream
import org.openrs2.protocol.login.RequestWorldListCodec
import org.openrs2.protocol.login.ServerFullCodec
import org.openrs2.protocol.world.WorldListDownstream
import org.openrs2.protocol.world.WorldListResponseCodec
public object ProtocolModule : AbstractModule() {
public override fun configure() {
install(BufferModule)
install(CryptoModule)
bindProtocol(
LoginUpstream::class.java,
InitGameConnectionCodec::class.java,
InitJs5RemoteConnectionCodec::class.java,
InitJaggrabConnectionCodec::class.java,
RequestWorldListCodec::class.java,
InitCrossDomainConnectionCodec::class.java
)
bindProtocol(
LoginDownstream::class.java,
ClientOutOfDateCodec::class.java,
ServerFullCodec::class.java,
IpLimitCodec::class.java
)
bindProtocol(
Js5RemoteDownstream::class.java,
Js5OkCodec::class.java,
ClientOutOfDateCodec::class.java,
ServerFullCodec::class.java,
IpLimitCodec::class.java
)
bindProtocol(
WorldListDownstream::class.java,
WorldListResponseCodec::class.java
)
}
private fun bindProtocol(
annotation: Class<out Annotation>,
vararg codecs: Class<out PacketCodec<*>>
) {
install(object : PrivateModule() {
override fun configure() {
val binder = Multibinder.newSetBinder(binder(), PACKET_CODEC_TYPE_LITERAL)
for (codec in codecs) {
binder.addBinding().to(codec)
}
bind(Protocol::class.java)
.annotatedWith(annotation)
.to(Protocol::class.java)
expose(Protocol::class.java)
.annotatedWith(annotation)
}
})
}
private val PACKET_CODEC_TYPE_LITERAL = object : TypeLiteral<PacketCodec<*>>() {}
}

@ -0,0 +1,8 @@
package org.openrs2.protocol.js5
import javax.inject.Qualifier
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FUNCTION)
public annotation class Js5RemoteDownstream

@ -1,8 +1,10 @@
package org.openrs2.protocol.login
import org.openrs2.protocol.EmptyPacketCodec
import javax.inject.Singleton
public object ClientOutOfDateCodec : EmptyPacketCodec<LoginResponse.ClientOutOfDate>(
@Singleton
public class ClientOutOfDateCodec : EmptyPacketCodec<LoginResponse.ClientOutOfDate>(
packet = LoginResponse.ClientOutOfDate,
opcode = 6
)

@ -1,8 +1,10 @@
package org.openrs2.protocol.login
import org.openrs2.protocol.EmptyPacketCodec
import javax.inject.Singleton
public object InitCrossDomainConnectionCodec : EmptyPacketCodec<LoginRequest.InitCrossDomainConnection>(
@Singleton
public class InitCrossDomainConnectionCodec : EmptyPacketCodec<LoginRequest.InitCrossDomainConnection>(
opcode = 'G'.code,
packet = LoginRequest.InitCrossDomainConnection
)

@ -3,8 +3,10 @@ package org.openrs2.protocol.login
import io.netty.buffer.ByteBuf
import org.openrs2.crypto.StreamCipher
import org.openrs2.protocol.PacketCodec
import javax.inject.Singleton
public object InitGameConnectionCodec : PacketCodec<LoginRequest.InitGameConnection>(
@Singleton
public class InitGameConnectionCodec : PacketCodec<LoginRequest.InitGameConnection>(
opcode = 14,
length = 1,
type = LoginRequest.InitGameConnection::class.java

@ -1,8 +1,10 @@
package org.openrs2.protocol.login
import org.openrs2.protocol.EmptyPacketCodec
import javax.inject.Singleton
public object InitJaggrabConnectionCodec : EmptyPacketCodec<LoginRequest.InitJaggrabConnection>(
@Singleton
public class InitJaggrabConnectionCodec : EmptyPacketCodec<LoginRequest.InitJaggrabConnection>(
packet = LoginRequest.InitJaggrabConnection,
opcode = 17
)

@ -3,8 +3,10 @@ package org.openrs2.protocol.login
import io.netty.buffer.ByteBuf
import org.openrs2.crypto.StreamCipher
import org.openrs2.protocol.PacketCodec
import javax.inject.Singleton
public object InitJs5RemoteConnectionCodec : PacketCodec<LoginRequest.InitJs5RemoteConnection>(
@Singleton
public class InitJs5RemoteConnectionCodec : PacketCodec<LoginRequest.InitJs5RemoteConnection>(
type = LoginRequest.InitJs5RemoteConnection::class.java,
opcode = 15,
length = 4

@ -1,8 +1,10 @@
package org.openrs2.protocol.login
import org.openrs2.protocol.EmptyPacketCodec
import javax.inject.Singleton
public object IpLimitCodec : EmptyPacketCodec<LoginResponse.IpLimit>(
@Singleton
public class IpLimitCodec : EmptyPacketCodec<LoginResponse.IpLimit>(
packet = LoginResponse.IpLimit,
opcode = 9
)

@ -1,8 +1,10 @@
package org.openrs2.protocol.login
import org.openrs2.protocol.EmptyPacketCodec
import javax.inject.Singleton
public object Js5OkCodec : EmptyPacketCodec<LoginResponse.Js5Ok>(
@Singleton
public class Js5OkCodec : EmptyPacketCodec<LoginResponse.Js5Ok>(
packet = LoginResponse.Js5Ok,
opcode = 0
)

@ -0,0 +1,8 @@
package org.openrs2.protocol.login
import javax.inject.Qualifier
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FUNCTION)
public annotation class LoginDownstream

@ -0,0 +1,8 @@
package org.openrs2.protocol.login
import javax.inject.Qualifier
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FUNCTION)
public annotation class LoginUpstream

@ -3,8 +3,10 @@ package org.openrs2.protocol.login
import io.netty.buffer.ByteBuf
import org.openrs2.crypto.StreamCipher
import org.openrs2.protocol.PacketCodec
import javax.inject.Singleton
public object RequestWorldListCodec : PacketCodec<LoginRequest.RequestWorldList>(
@Singleton
public class RequestWorldListCodec : PacketCodec<LoginRequest.RequestWorldList>(
type = LoginRequest.RequestWorldList::class.java,
opcode = 23,
length = 4

@ -1,8 +1,10 @@
package org.openrs2.protocol.login
import org.openrs2.protocol.EmptyPacketCodec
import javax.inject.Singleton
public object ServerFullCodec : EmptyPacketCodec<LoginResponse.ServerFull>(
@Singleton
public class ServerFullCodec : EmptyPacketCodec<LoginResponse.ServerFull>(
packet = LoginResponse.ServerFull,
opcode = 7
)

@ -0,0 +1,8 @@
package org.openrs2.protocol.world
import javax.inject.Qualifier
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FUNCTION)
public annotation class WorldListDownstream

@ -8,19 +8,14 @@ import org.openrs2.buffer.writeVersionedString
import org.openrs2.crypto.StreamCipher
import org.openrs2.protocol.PacketCodec
import org.openrs2.protocol.PacketLength
import javax.inject.Singleton
public object WorldListResponseCodec : PacketCodec<WorldListResponse>(
@Singleton
public class WorldListResponseCodec : PacketCodec<WorldListResponse>(
type = WorldListResponse::class.java,
opcode = 0,
length = PacketLength.VARIABLE_SHORT
) {
private const val VERSION = 1
private const val FLAG_MEMBERS_ONLY = 0x1
private const val FLAG_QUICK_CHAT = 0x2
private const val FLAG_PVP = 0x4
private const val FLAG_LOOT_SHARE = 0x8
override fun decode(input: ByteBuf, cipher: StreamCipher): WorldListResponse {
val version = input.readUnsignedByte().toInt()
require(version == VERSION) {
@ -134,4 +129,13 @@ public object WorldListResponseCodec : PacketCodec<WorldListResponse>(
output.writeShort(count)
}
}
private companion object {
private const val VERSION = 1
private const val FLAG_MEMBERS_ONLY = 0x1
private const val FLAG_QUICK_CHAT = 0x2
private const val FLAG_PVP = 0x4
private const val FLAG_LOOT_SHARE = 0x8
}
}

Loading…
Cancel
Save