mirror of
https://github.com/ViaVersion/VIAaaS.git
synced 2025-01-24 22:01:49 +01:00
update deps, some changes to coroutine code
This commit is contained in:
parent
7070b10bbb
commit
96774c621e
@ -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
|
||||
}
|
||||
|
@ -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?) {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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<InetSocketAd
|
||||
}
|
||||
}
|
||||
|
||||
fun connectBack(handler: MinecraftHandler, address: String, port: Int, state: State, extraData: String? = null, success: () -> 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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -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())
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user