From e8ba09d7c087fd4050aec2caa031d0d81b909fd1 Mon Sep 17 00:00:00 2001 From: creeper123123321 <7974274+creeper123123321@users.noreply.github.com> Date: Tue, 13 Jul 2021 07:57:24 -0300 Subject: [PATCH] protocol detector cache config closes #171 --- .../com/viaversion/aas/config/VIAaaSConfig.kt | 2 + .../handler/autoprotocol/ProtocolDetector.kt | 95 +++++++++---------- src/main/resources/viaaas.yml | 2 + 3 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/main/kotlin/com/viaversion/aas/config/VIAaaSConfig.kt b/src/main/kotlin/com/viaversion/aas/config/VIAaaSConfig.kt index 9dd7a80..cff2e33 100644 --- a/src/main/kotlin/com/viaversion/aas/config/VIAaaSConfig.kt +++ b/src/main/kotlin/com/viaversion/aas/config/VIAaaSConfig.kt @@ -68,4 +68,6 @@ object VIAaaSConfig : Config(File("config/viaaas.yml")) { val maxPlayers: Int? get() = this.getInt("max-players", 20).let { if (it == -1) null else it } val backendProxy: URI? get() = this.getString("backend-proxy", "").let { if (it.isNullOrEmpty()) null else URI.create(it) } + val protocolDetectorCache: Int + get() = this.getInt("protocol-detector-cache", 30) } diff --git a/src/main/kotlin/com/viaversion/aas/handler/autoprotocol/ProtocolDetector.kt b/src/main/kotlin/com/viaversion/aas/handler/autoprotocol/ProtocolDetector.kt index d6dc132..4571249 100644 --- a/src/main/kotlin/com/viaversion/aas/handler/autoprotocol/ProtocolDetector.kt +++ b/src/main/kotlin/com/viaversion/aas/handler/autoprotocol/ProtocolDetector.kt @@ -23,63 +23,62 @@ import io.netty.channel.ChannelInitializer import io.netty.channel.ChannelOption import io.netty.handler.timeout.ReadTimeoutHandler import io.netty.resolver.NoopAddressResolverGroup -import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.net.InetSocketAddress import java.util.concurrent.CompletableFuture import java.util.concurrent.TimeUnit object ProtocolDetector { - private val SERVER_VER = CacheBuilder.newBuilder() - .expireAfterWrite(30, TimeUnit.SECONDS) - .build>(CacheLoader.from { address -> - val future = CompletableFuture() - GlobalScope.launch { - try { - val proxyUri = VIAaaSConfig.backendProxy - val proxySocket = if (proxyUri == null) null else { - InetSocketAddress(AspirinServer.dnsResolver.resolve(proxyUri.host).suspendAwait(), proxyUri.port) - } - val ch = Bootstrap() - .group(AspirinServer.childLoop) - .resolver(NoopAddressResolverGroup.INSTANCE) - .channelFactory(channelSocketFactory(AspirinServer.childLoop)) - .option(ChannelOption.TCP_NODELAY, true) - .option(ChannelOption.IP_TOS, 0x18) - .handler(object : ChannelInitializer() { - override fun initChannel(channel: Channel) { - val data = ConnectionData( - channel, - state = ProtocolDetectionState(future), - frontVer = -1 - ) - channel.pipeline().also { addProxyHandler(it, proxyUri, proxySocket) } - .addLast("timeout", ReadTimeoutHandler(30, TimeUnit.SECONDS)) - .addLast("frame", FrameCodec()) - .addLast("mc", MinecraftCodec()) - .addLast("handler", MinecraftHandler(data, frontEnd = false)) - } - }) - .connect(address!!) - ch.addListener(ChannelFutureListener { - if (!it.isSuccess) { - future.completeExceptionally(it.cause()) - } else { - val handshake = Handshake() - handshake.address = address.hostString - handshake.port = address.port - handshake.protocolId = -1 - handshake.nextState = State.STATUS - send(ch.channel(), handshake) - send(ch.channel(), StatusRequest(), flush = true) + private val loader = CacheLoader.from> { address -> + val future = CompletableFuture() + CoroutineScope(Dispatchers.Default).launch { + try { + val proxyUri = VIAaaSConfig.backendProxy + val proxySocket = if (proxyUri == null) null else { + InetSocketAddress(AspirinServer.dnsResolver.resolve(proxyUri.host).suspendAwait(), proxyUri.port) + } + val ch = Bootstrap() + .group(AspirinServer.childLoop) + .resolver(NoopAddressResolverGroup.INSTANCE) + .channelFactory(channelSocketFactory(AspirinServer.childLoop)) + .option(ChannelOption.TCP_NODELAY, true) + .option(ChannelOption.IP_TOS, 0x18) + .handler(object : ChannelInitializer() { + override fun initChannel(channel: Channel) { + val data = ConnectionData(channel, state = ProtocolDetectionState(future), frontVer = -1) + channel.pipeline().also { addProxyHandler(it, proxyUri, proxySocket) } + .addLast("timeout", ReadTimeoutHandler(30, TimeUnit.SECONDS)) + .addLast("frame", FrameCodec()) + .addLast("mc", MinecraftCodec()) + .addLast("handler", MinecraftHandler(data, frontEnd = false)) } }) - } catch (throwable: Throwable) { - future.completeExceptionally(throwable) - } + .connect(address!!) + ch.addListener(ChannelFutureListener { + if (!it.isSuccess) { + future.completeExceptionally(it.cause()) + } else { + val handshake = Handshake() + handshake.address = address.hostString + handshake.port = address.port + handshake.protocolId = -1 + handshake.nextState = State.STATUS + send(ch.channel(), handshake) + send(ch.channel(), StatusRequest(), flush = true) + } + }) + } catch (throwable: Throwable) { + future.completeExceptionally(throwable) } - future - }) + } + future + } + + private val SERVER_VER = CacheBuilder.newBuilder() + .expireAfterWrite(VIAaaSConfig.protocolDetectorCache.toLong(), TimeUnit.SECONDS) + .build(loader) fun detectVersion(address: InetSocketAddress): CompletableFuture = SERVER_VER[address] } diff --git a/src/main/resources/viaaas.yml b/src/main/resources/viaaas.yml index b0c74d4..dd27a3d 100644 --- a/src/main/resources/viaaas.yml +++ b/src/main/resources/viaaas.yml @@ -81,6 +81,8 @@ favicon-url: '' force-online-mode: false # Max players to allow connection. Use -1 to not limit max-players: 20 +# Time to cache server protocol detection in seconds +protocol-detector-cache: 30 # ##### # SECRETS - DO NOT SHARE