protocol detector cache config

closes #171
This commit is contained in:
creeper123123321 2021-07-13 07:57:24 -03:00
parent 30d7d584c4
commit e8ba09d7c0
3 changed files with 51 additions and 48 deletions

View File

@ -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)
}

View File

@ -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<InetSocketAddress, CompletableFuture<ProtocolVersion>>(CacheLoader.from { address ->
val future = CompletableFuture<ProtocolVersion>()
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<Channel>() {
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<InetSocketAddress, CompletableFuture<ProtocolVersion>> { address ->
val future = CompletableFuture<ProtocolVersion>()
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<Channel>() {
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<ProtocolVersion> = SERVER_VER[address]
}

View File

@ -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