update deps, some changes to coroutine code

This commit is contained in:
creeper123123321 2021-06-02 21:32:24 -03:00
parent 7070b10bbb
commit 96774c621e
9 changed files with 83 additions and 75 deletions

View File

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

View File

@ -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?) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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