From 96774c621e0e5e695eacda66ae5cd411616a7b4a Mon Sep 17 00:00:00 2001 From: creeper123123321 <7974274+creeper123123321@users.noreply.github.com> Date: Wed, 2 Jun 2021 21:32:24 -0300 Subject: [PATCH] update deps, some changes to coroutine code --- build.gradle.kts | 2 +- .../aas/handler/MinecraftHandler.kt | 7 +++- .../aas/handler/state/HandshakeState.kt | 37 +++++++++++++------ .../aas/handler/state/LoginState.kt | 14 +++---- .../com/viaversion/aas/handler/state/Util.kt | 29 +++++++-------- .../id47toid5/packets/EntityPackets.kt | 18 +++------ .../id47toid5/packets/PlayerPackets.kt | 18 +++------ .../protocol/id5toid4/Protocol1_7_6to1_7_2.kt | 2 +- .../viaversion/aas/web/WebDashboardServer.kt | 31 +++++++++------- 9 files changed, 83 insertions(+), 75 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index bdfe854..aad69bb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ plugins { kotlin("jvm") version "1.5.10" id("maven-publish") id("com.github.johnrengelman.shadow") version "7.0.0" - id("com.github.ben-manes.versions") version "0.38.0" + id("com.github.ben-manes.versions") version "0.39.0" id("com.palantir.git-version") version "0.12.3" id("org.gradlewebtools.minify") version "1.1.1" apply false } diff --git a/src/main/kotlin/com/viaversion/aas/handler/MinecraftHandler.kt b/src/main/kotlin/com/viaversion/aas/handler/MinecraftHandler.kt index 723f9b3..1adce3d 100644 --- a/src/main/kotlin/com/viaversion/aas/handler/MinecraftHandler.kt +++ b/src/main/kotlin/com/viaversion/aas/handler/MinecraftHandler.kt @@ -1,13 +1,16 @@ package com.viaversion.aas.handler -import com.viaversion.aas.mcLogger import com.viaversion.aas.codec.packet.Packet +import com.viaversion.aas.mcLogger import com.viaversion.aas.setAutoRead import com.viaversion.viaversion.exception.CancelCodecException import io.netty.channel.Channel import io.netty.channel.ChannelHandlerContext import io.netty.channel.SimpleChannelInboundHandler import io.netty.handler.proxy.Socks5ProxyHandler +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel import java.net.SocketAddress import java.nio.channels.ClosedChannelException @@ -18,6 +21,7 @@ class MinecraftHandler( lateinit var endRemoteAddress: SocketAddress val other: Channel? get() = if (frontEnd) data.backChannel else data.frontChannel var loggedDc = false + val coroutineScope = CoroutineScope(Dispatchers.Default) override fun channelRead0(ctx: ChannelHandlerContext, packet: Packet) { if (ctx.channel().isActive) { @@ -33,6 +37,7 @@ class MinecraftHandler( override fun channelInactive(ctx: ChannelHandlerContext) { other?.close() data.state.onInactivated(this) + coroutineScope.cancel() } override fun channelReadComplete(ctx: ChannelHandlerContext?) { diff --git a/src/main/kotlin/com/viaversion/aas/handler/state/HandshakeState.kt b/src/main/kotlin/com/viaversion/aas/handler/state/HandshakeState.kt index bfcefed..76272b7 100644 --- a/src/main/kotlin/com/viaversion/aas/handler/state/HandshakeState.kt +++ b/src/main/kotlin/com/viaversion/aas/handler/state/HandshakeState.kt @@ -5,14 +5,16 @@ import com.google.common.cache.CacheLoader import com.google.common.net.HostAndPort import com.google.common.util.concurrent.RateLimiter import com.viaversion.aas.VIAaaSAddress +import com.viaversion.aas.codec.packet.Packet +import com.viaversion.aas.codec.packet.handshake.Handshake import com.viaversion.aas.config.VIAaaSConfig import com.viaversion.aas.handler.MinecraftHandler import com.viaversion.aas.mcLogger -import com.viaversion.aas.codec.packet.Packet -import com.viaversion.aas.codec.packet.handshake.Handshake import com.viaversion.aas.util.StacklessException import com.viaversion.viaversion.api.protocol.packet.State import io.netty.channel.ChannelHandlerContext +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import java.net.InetAddress import java.net.InetSocketAddress import java.util.concurrent.TimeUnit @@ -29,21 +31,24 @@ class HandshakeState : MinecraftConnectionState { override val state: State get() = State.HANDSHAKE - override fun handlePacket(handler: MinecraftHandler, ctx: ChannelHandlerContext, packet: Packet) { - if (packet !is Handshake) throw StacklessException("Invalid packet!") + private fun checkRateLimit(handler: MinecraftHandler) { + if (!RateLimit.rateLimitByIp.get((handler.endRemoteAddress as InetSocketAddress).address).tryAcquire()) { + throw StacklessException("Rate-limited") + } + } + private fun handleNextState(handler: MinecraftHandler, packet: Handshake) { handler.data.frontVer = packet.protocolId when (packet.nextState.ordinal) { 1 -> handler.data.state = StatusState 2 -> handler.data.state = LoginState() else -> throw StacklessException("Invalid next state") } + } - if (!RateLimit.rateLimitByIp.get((handler.endRemoteAddress as InetSocketAddress).address).tryAcquire()) { - throw StacklessException("Rate-limited") - } + private fun handleVirtualHost(handler: MinecraftHandler, packet: Handshake) { val virtualPort = packet.port - val extraData = packet.address.substringAfter(0.toChar(), missingDelimiterValue = "").ifEmpty { null } // todo + val extraData = packet.address.substringAfter(0.toChar(), missingDelimiterValue = "").ifEmpty { null } val virtualHostNoExtra = packet.address.substringBefore(0.toChar()) val parsed = VIAaaSConfig.hostName.map { @@ -58,10 +63,10 @@ class HandshakeState : MinecraftConnectionState { packet.address = parsed.serverAddress!! packet.port = parsed.port ?: VIAaaSConfig.defaultBackendPort ?: virtualPort - handler.data.viaBackServerVer = backProto var frontOnline = parsed.online if (VIAaaSConfig.forceOnlineMode) frontOnline = true + handler.data.viaBackServerVer = backProto (handler.data.state as? LoginState)?.also { it.frontOnline = frontOnline it.backName = parsed.username @@ -78,9 +83,19 @@ class HandshakeState : MinecraftConnectionState { if (!hadHostname && VIAaaSConfig.requireHostName) { throw StacklessException("Missing parts in hostname") } + } - if (packet.nextState == State.STATUS) { - connectBack(handler, packet.address, packet.port, packet.nextState) {} + override fun handlePacket(handler: MinecraftHandler, ctx: ChannelHandlerContext, packet: Packet) { + if (packet !is Handshake) throw StacklessException("Invalid packet!") + + handleNextState(handler, packet) + checkRateLimit(handler) + handleVirtualHost(handler, packet) + + if (packet.nextState == State.STATUS) { // see LoginState for LOGIN + handler.coroutineScope.launch(Dispatchers.IO) { + connectBack(handler, packet.address, packet.port, packet.nextState) + } } } diff --git a/src/main/kotlin/com/viaversion/aas/handler/state/LoginState.kt b/src/main/kotlin/com/viaversion/aas/handler/state/LoginState.kt index be14fd0..5ac7152 100644 --- a/src/main/kotlin/com/viaversion/aas/handler/state/LoginState.kt +++ b/src/main/kotlin/com/viaversion/aas/handler/state/LoginState.kt @@ -14,7 +14,6 @@ import com.viaversion.viaversion.api.protocol.packet.State import io.netty.channel.Channel import io.netty.channel.ChannelHandlerContext import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.future.await import kotlinx.coroutines.launch import java.util.* @@ -99,7 +98,7 @@ class LoginState : MinecraftConnectionState { val frontHandler = handler.data.frontHandler val backChan = handler.data.backChannel!! - GlobalScope.launch(Dispatchers.IO) { + handler.coroutineScope.launch(Dispatchers.IO) { try { val playerId = callbackPlayerId.await() @@ -145,7 +144,7 @@ class LoginState : MinecraftConnectionState { } handler.data.frontChannel.setAutoRead(false) - GlobalScope.launch(Dispatchers.IO) { + handler.coroutineScope.launch(Dispatchers.IO) { try { val profile = hasJoined(frontName, frontHash) val id = profile.get("id")!!.asString @@ -166,7 +165,7 @@ class LoginState : MinecraftConnectionState { frontName = loginStart.username backName = backName ?: frontName - GlobalScope.launch { + handler.coroutineScope.launch(Dispatchers.IO) { try { if (frontOnline != null) { when (frontOnline) { @@ -176,10 +175,9 @@ class LoginState : MinecraftConnectionState { val id = callbackPlayerId.await() mcLogger.info("Login: ${handler.endRemoteAddress} $frontName $id") } - connectBack(handler, backAddress.host, backAddress.port, State.LOGIN, extraData) { - loginStart.username = backName!! - send(handler.data.backChannel!!, loginStart, true) - } + connectBack(handler, backAddress.host, backAddress.port, State.LOGIN, extraData) + loginStart.username = backName!! + send(handler.data.backChannel!!, loginStart, true) } catch (e: Exception) { handler.data.frontChannel.pipeline().fireExceptionCaught(StacklessException("Login error: $e", e)) } diff --git a/src/main/kotlin/com/viaversion/aas/handler/state/Util.kt b/src/main/kotlin/com/viaversion/aas/handler/state/Util.kt index 642d4f7..44efccc 100644 --- a/src/main/kotlin/com/viaversion/aas/handler/state/Util.kt +++ b/src/main/kotlin/com/viaversion/aas/handler/state/Util.kt @@ -16,8 +16,6 @@ import io.netty.channel.ChannelFutureListener import io.netty.channel.ChannelOption import io.netty.channel.socket.SocketChannel import io.netty.resolver.NoopAddressResolverGroup -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.future.await import kotlinx.coroutines.launch import kotlinx.coroutines.withTimeoutOrNull @@ -51,7 +49,7 @@ private fun createBackChannel( mcLogger.info("+ ${handler.endRemoteAddress} -> $socketAddr") handler.data.backChannel = it.channel() as SocketChannel - GlobalScope.launch { + handler.coroutineScope.launch { if (handler.data.viaBackServerVer == null) { try { val detectedProtocol = withTimeoutOrNull(10_000) { @@ -129,20 +127,21 @@ private fun resolveBackendAddresses(hostAndPort: HostAndPort): List Unit) { +suspend fun connectBack( + handler: MinecraftHandler, + address: String, + port: Int, + state: State, + extraData: String? = null +) { handler.data.frontChannel.setAutoRead(false) - GlobalScope.launch(Dispatchers.IO) { - try { - val addresses = resolveBackendAddresses(HostAndPort.fromParts(address, port)) + try { + val addresses = resolveBackendAddresses(HostAndPort.fromParts(address, port)) - if (addresses.isEmpty()) throw StacklessException("Hostname has no IP address") + if (addresses.isEmpty()) throw StacklessException("Hostname has no IP address") - tryBackAddresses(handler, addresses, state, extraData) - success() - } catch (e: Exception) { - handler.data.frontChannel.eventLoop().submit { - handler.disconnect("Couldn't connect: $e") - } - } + tryBackAddresses(handler, addresses, state, extraData) + } catch (e: Exception) { + throw StacklessException("Couldn't connect", e) } } diff --git a/src/main/kotlin/com/viaversion/aas/protocol/id47toid5/packets/EntityPackets.kt b/src/main/kotlin/com/viaversion/aas/protocol/id47toid5/packets/EntityPackets.kt index 55827ef..5e8a028 100644 --- a/src/main/kotlin/com/viaversion/aas/protocol/id47toid5/packets/EntityPackets.kt +++ b/src/main/kotlin/com/viaversion/aas/protocol/id47toid5/packets/EntityPackets.kt @@ -227,9 +227,7 @@ fun Protocol1_8To1_7_6.registerEntityPackets() { map(Type.BYTE) //x map(Type.BYTE) //y map(Type.BYTE) //z - create { packetWrapper -> - packetWrapper.write(Type.BOOLEAN, true) //OnGround - } + create(Type.BOOLEAN, true) //OnGround } }) @@ -239,9 +237,7 @@ fun Protocol1_8To1_7_6.registerEntityPackets() { map(Type.INT, Type.VAR_INT) //Entity Id map(Type.BYTE) //yaw map(Type.BYTE) //pitch - create { packetWrapper -> - packetWrapper.write(Type.BOOLEAN, true) //OnGround - } + create(Type.BOOLEAN, true) //OnGround } }) @@ -254,9 +250,7 @@ fun Protocol1_8To1_7_6.registerEntityPackets() { map(Type.BYTE) //z map(Type.BYTE) //yaw map(Type.BYTE) //pitch - create { packetWrapper -> - packetWrapper.write(Type.BOOLEAN, true) //OnGround - } + create(Type.BOOLEAN, true) //OnGround } }) @@ -269,9 +263,7 @@ fun Protocol1_8To1_7_6.registerEntityPackets() { map(Type.INT) //z map(Type.BYTE) //yaw map(Type.BYTE) //pitch - create { packetWrapper -> - packetWrapper.write(Type.BOOLEAN, true) //OnGround - } + create(Type.BOOLEAN, true) //OnGround } }) @@ -310,7 +302,7 @@ fun Protocol1_8To1_7_6.registerEntityPackets() { map(Type.BYTE) //Effect Id map(Type.BYTE) //Amplifier map(Type.SHORT, Type.VAR_INT) //Duration - create { packetWrapper -> packetWrapper.write(Type.BOOLEAN, false) } //Hide Particles + create(Type.BOOLEAN, false) //Hide Particles } }) diff --git a/src/main/kotlin/com/viaversion/aas/protocol/id47toid5/packets/PlayerPackets.kt b/src/main/kotlin/com/viaversion/aas/protocol/id47toid5/packets/PlayerPackets.kt index 8553d8f..15c65d1 100644 --- a/src/main/kotlin/com/viaversion/aas/protocol/id47toid5/packets/PlayerPackets.kt +++ b/src/main/kotlin/com/viaversion/aas/protocol/id47toid5/packets/PlayerPackets.kt @@ -47,9 +47,7 @@ fun Protocol1_8To1_7_6.registerPlayerPackets() { map(Type.UNSIGNED_BYTE) //Difficulty map(Type.UNSIGNED_BYTE) //Max players map(Type.STRING) //Level Type - create { packetWrapper -> - packetWrapper.write(Type.BOOLEAN, false) //Reduced Debug Info - } + create(Type.BOOLEAN, false) //Reduced Debug Info } }) @@ -57,9 +55,7 @@ fun Protocol1_8To1_7_6.registerPlayerPackets() { this.registerClientbound(State.PLAY, 0x02, 0x02, object : PacketRemapper() { override fun registerMap() { map(Type.STRING) //Chat Message - create { packetWrapper -> - packetWrapper.write(Type.BYTE, 0.toByte()) //Position (chat box) - } + create(Type.BYTE, 0.toByte()) //Position (chat box) } }) @@ -427,7 +423,7 @@ fun Protocol1_8To1_7_6.registerPlayerPackets() { val newWrapper = PacketWrapper.create(0x17, newPacketBuf, packetWrapper.user()) newWrapper.passthrough(Type.STRING) newWrapper.write(Type.SHORT, newPacketBuf.readableBytes().toShort()) - newWrapper.sendToServer(Protocol1_8To1_7_6::class.java, true, true) + newWrapper.sendToServer(Protocol1_8To1_7_6::class.java) } } }) @@ -463,10 +459,8 @@ fun Protocol1_8To1_7_6.registerPlayerPackets() { //Animation this.registerServerbound(State.PLAY, 0x0A, 0x0A, object : PacketRemapper() { override fun registerMap() { - create { packetWrapper -> - packetWrapper.write(Type.INT, 0) //Entity Id, hopefully 0 is ok - packetWrapper.write(Type.BYTE, 1.toByte()) //Animation - } + create(Type.INT, 0) //Entity Id, hopefully 0 is ok + create(Type.BYTE, 1.toByte()) //Animation } }) @@ -478,7 +472,7 @@ fun Protocol1_8To1_7_6.registerPlayerPackets() { map(Type.BYTE) map(Type.BYTE) map(Type.BOOLEAN) - create { packetWrapper -> packetWrapper.write(Type.BYTE, 0.toByte()) } + create(Type.BYTE, 0.toByte()) handler { packetWrapper -> val flags = packetWrapper.read(Type.UNSIGNED_BYTE) packetWrapper.write(Type.BOOLEAN, flags and 1 == 1.toShort()) diff --git a/src/main/kotlin/com/viaversion/aas/protocol/id5toid4/Protocol1_7_6to1_7_2.kt b/src/main/kotlin/com/viaversion/aas/protocol/id5toid4/Protocol1_7_6to1_7_2.kt index e7fdd35..4f3d801 100644 --- a/src/main/kotlin/com/viaversion/aas/protocol/id5toid4/Protocol1_7_6to1_7_2.kt +++ b/src/main/kotlin/com/viaversion/aas/protocol/id5toid4/Protocol1_7_6to1_7_2.kt @@ -23,7 +23,7 @@ object Protocol1_7_6to1_7_2 : AbstractSimpleProtocol() { map(Type.VAR_INT) map(Type.STRING, INSERT_DASHES) map(Type.STRING) - create { packetWrapper -> packetWrapper.write(Type.VAR_INT, 0) } + create(Type.VAR_INT, 0) } }) } diff --git a/src/main/kotlin/com/viaversion/aas/web/WebDashboardServer.kt b/src/main/kotlin/com/viaversion/aas/web/WebDashboardServer.kt index d1185dc..0bf808e 100644 --- a/src/main/kotlin/com/viaversion/aas/web/WebDashboardServer.kt +++ b/src/main/kotlin/com/viaversion/aas/web/WebDashboardServer.kt @@ -19,7 +19,6 @@ import io.ktor.http.cio.websocket.* import io.ktor.websocket.* import kotlinx.coroutines.* import kotlinx.coroutines.future.asCompletableFuture -import kotlinx.coroutines.time.delay import java.net.InetSocketAddress import java.net.SocketAddress import java.time.Duration @@ -97,19 +96,25 @@ class WebDashboardServer { val msg = """Requester: $id $address (${info?.org}, ${info?.city}, ${info?.region}, ${info?.countryCode}) Backend: $backAddress""" listeners[id]?.forEach { - it.ws.send( - JsonObject().also { - it.addProperty("action", "session_hash_request") - it.addProperty("user", name) - it.addProperty("session_hash", hash) - it.addProperty("message", msg) - }.toString() - ) - it.ws.flush() + coroutineScope { + launch { + it.ws.send( + JsonObject().also { + it.addProperty("action", "session_hash_request") + it.addProperty("user", name) + it.addProperty("session_hash", hash) + it.addProperty("message", msg) + }.toString() + ) + it.ws.flush() + } + } } - GlobalScope.launch { - delay(Duration.ofSeconds(20)) - future.completeExceptionally(StacklessException("No response from browser")) + coroutineScope { + launch { + delay(20_000) + future.completeExceptionally(StacklessException("No response from browser")) + } } } return future