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.Protocol
import org.openrs2.protocol.Rs2Decoder import org.openrs2.protocol.Rs2Decoder
import org.openrs2.protocol.Rs2Encoder 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>() { public class OsrsJs5ChannelInitializer(private val handler: OsrsJs5ChannelHandler) : ChannelInitializer<Channel>() {
override fun initChannel(ch: Channel) { override fun initChannel(ch: Channel) {
ch.pipeline().addLast( ch.pipeline().addLast(
ReadTimeoutHandler(30), ReadTimeoutHandler(30),
Rs2Encoder(Protocol.LOGIN_UPSTREAM), Rs2Encoder(Protocol(InitJs5RemoteConnectionCodec())),
Rs2Decoder(Protocol.JS5REMOTE_DOWNSTREAM) Rs2Decoder(Protocol(Js5OkCodec(), ClientOutOfDateCodec()))
) )
ch.pipeline().addLast("handler", handler) 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.NetworkService
import org.openrs2.game.net.js5.Js5Service import org.openrs2.game.net.js5.Js5Service
import org.openrs2.net.NetworkModule import org.openrs2.net.NetworkModule
import org.openrs2.protocol.ProtocolModule
public object GameModule : AbstractModule() { public object GameModule : AbstractModule() {
override fun configure() { override fun configure() {
@ -25,6 +26,7 @@ public object GameModule : AbstractModule() {
install(CacheModule) install(CacheModule)
install(ConfigModule) install(ConfigModule)
install(NetworkModule) install(NetworkModule)
install(ProtocolModule)
val binder = Multibinder.newSetBinder(binder(), Service::class.java) val binder = Multibinder.newSetBinder(binder(), Service::class.java)
binder.addBinding().to(GameService::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.Protocol
import org.openrs2.protocol.Rs2Decoder import org.openrs2.protocol.Rs2Decoder
import org.openrs2.protocol.Rs2Encoder import org.openrs2.protocol.Rs2Encoder
import org.openrs2.protocol.login.LoginDownstream
import org.openrs2.protocol.login.LoginUpstream
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Provider import javax.inject.Provider
@ -14,13 +16,17 @@ import javax.inject.Singleton
@Singleton @Singleton
public class Rs2ChannelInitializer @Inject constructor( 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>() { ) : ChannelInitializer<Channel>() {
override fun initChannel(ch: Channel) { override fun initChannel(ch: Channel) {
ch.pipeline().addLast( ch.pipeline().addLast(
IdleStateHandler(true, TIMEOUT_SECS, TIMEOUT_SECS, TIMEOUT_SECS, TimeUnit.SECONDS), IdleStateHandler(true, TIMEOUT_SECS, TIMEOUT_SECS, TIMEOUT_SECS, TimeUnit.SECONDS),
Rs2Decoder(Protocol.LOGIN_UPSTREAM), Rs2Decoder(loginUpStreamProtocol),
Rs2Encoder(Protocol.LOGIN_DOWNSTREAM), Rs2Encoder(loginDownStreamProtocol),
handlerProvider.get() handlerProvider.get()
) )
} }

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

@ -1,17 +1,12 @@
package org.openrs2.protocol package org.openrs2.protocol
import org.openrs2.protocol.login.ClientOutOfDateCodec import javax.inject.Inject
import org.openrs2.protocol.login.InitCrossDomainConnectionCodec import javax.inject.Singleton
import org.openrs2.protocol.login.InitGameConnectionCodec
import org.openrs2.protocol.login.InitJaggrabConnectionCodec @Singleton
import org.openrs2.protocol.login.InitJs5RemoteConnectionCodec public class Protocol @Inject constructor(codecs: Set<PacketCodec<*>>) {
import org.openrs2.protocol.login.IpLimitCodec public constructor(vararg codecs: PacketCodec<*>) : this(codecs.toSet())
import org.openrs2.protocol.login.Js5OkCodec
import org.openrs2.protocol.login.RequestWorldListCodec
import org.openrs2.protocol.login.ServerFullCodec
import org.openrs2.protocol.world.WorldListResponseCodec
public class Protocol(vararg codecs: PacketCodec<*>) {
private val decoders = arrayOfNulls<PacketCodec<*>>(256) private val decoders = arrayOfNulls<PacketCodec<*>>(256)
private val encoders = codecs.associateBy(PacketCodec<*>::type) 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>? { public fun <T : Packet> getEncoder(type: Class<T>): PacketCodec<T>? {
return encoders[type] as 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 package org.openrs2.protocol.login
import org.openrs2.protocol.EmptyPacketCodec 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, packet = LoginResponse.ClientOutOfDate,
opcode = 6 opcode = 6
) )

@ -1,8 +1,10 @@
package org.openrs2.protocol.login package org.openrs2.protocol.login
import org.openrs2.protocol.EmptyPacketCodec 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, opcode = 'G'.code,
packet = LoginRequest.InitCrossDomainConnection packet = LoginRequest.InitCrossDomainConnection
) )

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

@ -1,8 +1,10 @@
package org.openrs2.protocol.login package org.openrs2.protocol.login
import org.openrs2.protocol.EmptyPacketCodec 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, packet = LoginRequest.InitJaggrabConnection,
opcode = 17 opcode = 17
) )

@ -3,8 +3,10 @@ package org.openrs2.protocol.login
import io.netty.buffer.ByteBuf import io.netty.buffer.ByteBuf
import org.openrs2.crypto.StreamCipher import org.openrs2.crypto.StreamCipher
import org.openrs2.protocol.PacketCodec 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, type = LoginRequest.InitJs5RemoteConnection::class.java,
opcode = 15, opcode = 15,
length = 4 length = 4

@ -1,8 +1,10 @@
package org.openrs2.protocol.login package org.openrs2.protocol.login
import org.openrs2.protocol.EmptyPacketCodec 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, packet = LoginResponse.IpLimit,
opcode = 9 opcode = 9
) )

@ -1,8 +1,10 @@
package org.openrs2.protocol.login package org.openrs2.protocol.login
import org.openrs2.protocol.EmptyPacketCodec 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, packet = LoginResponse.Js5Ok,
opcode = 0 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 io.netty.buffer.ByteBuf
import org.openrs2.crypto.StreamCipher import org.openrs2.crypto.StreamCipher
import org.openrs2.protocol.PacketCodec 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, type = LoginRequest.RequestWorldList::class.java,
opcode = 23, opcode = 23,
length = 4 length = 4

@ -1,8 +1,10 @@
package org.openrs2.protocol.login package org.openrs2.protocol.login
import org.openrs2.protocol.EmptyPacketCodec 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, packet = LoginResponse.ServerFull,
opcode = 7 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.crypto.StreamCipher
import org.openrs2.protocol.PacketCodec import org.openrs2.protocol.PacketCodec
import org.openrs2.protocol.PacketLength import org.openrs2.protocol.PacketLength
import javax.inject.Singleton
public object WorldListResponseCodec : PacketCodec<WorldListResponse>( @Singleton
public class WorldListResponseCodec : PacketCodec<WorldListResponse>(
type = WorldListResponse::class.java, type = WorldListResponse::class.java,
opcode = 0, opcode = 0,
length = PacketLength.VARIABLE_SHORT 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 { override fun decode(input: ByteBuf, cipher: StreamCipher): WorldListResponse {
val version = input.readUnsignedByte().toInt() val version = input.readUnsignedByte().toInt()
require(version == VERSION) { require(version == VERSION) {
@ -134,4 +129,13 @@ public object WorldListResponseCodec : PacketCodec<WorldListResponse>(
output.writeShort(count) 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