mirror of
https://github.com/ViaVersion/VIAaaS.git
synced 2024-11-24 12:25:39 +01:00
backend injection, fixed 'remaining bytes!!!', some cleanup, fix listening in browser
This commit is contained in:
parent
b69bf7cb1f
commit
ffb8980fb2
@ -10,6 +10,7 @@ import io.netty.handler.codec.MessageToMessageCodec
|
||||
import io.netty.handler.flow.FlowControlHandler
|
||||
import io.netty.handler.timeout.ReadTimeoutHandler
|
||||
import us.myles.ViaVersion.api.data.UserConnection
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolPipeline
|
||||
import us.myles.ViaVersion.api.type.Type
|
||||
import us.myles.ViaVersion.exception.CancelDecoderException
|
||||
import us.myles.ViaVersion.exception.CancelEncoderException
|
||||
@ -21,15 +22,27 @@ import javax.crypto.Cipher
|
||||
|
||||
object ChannelInit : ChannelInitializer<Channel>() {
|
||||
override fun initChannel(ch: Channel) {
|
||||
val user = UserConnection(ch)
|
||||
CloudPipeline(user)
|
||||
ch.pipeline().addLast("timeout", ReadTimeoutHandler(30, TimeUnit.SECONDS))
|
||||
// "crypto"
|
||||
.addLast("frame", FrameCodec())
|
||||
// "compress" / dummy "decompress"
|
||||
.addLast("flow-handler", FlowControlHandler())
|
||||
.addLast("handler", CloudMinecraftHandler(ConnectionData(
|
||||
frontChannel = ch,
|
||||
), other = null, frontEnd = true))
|
||||
}
|
||||
}
|
||||
|
||||
class BackendInit(val connectionData: ConnectionData) : ChannelInitializer<Channel>() {
|
||||
override fun initChannel(ch: Channel) {
|
||||
val user = UserConnection(ch, true)
|
||||
ProtocolPipeline(user)
|
||||
ch.pipeline().addLast("timeout", ReadTimeoutHandler(30, TimeUnit.SECONDS))
|
||||
// "crypto"
|
||||
.addLast("frame", FrameCodec())
|
||||
// compress
|
||||
.addLast("via-codec", CloudViaCodec(user))
|
||||
.addLast("handler", CloudMinecraftHandler(user, null, frontEnd = true))
|
||||
.addLast("handler", CloudMinecraftHandler(connectionData, connectionData.frontChannel, frontEnd = false))
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,16 +62,6 @@ class CloudCrypto(val cipherDecode: Cipher, var cipherEncode: Cipher) : MessageT
|
||||
}
|
||||
}
|
||||
|
||||
class BackendInit(val user: UserConnection) : ChannelInitializer<Channel>() {
|
||||
override fun initChannel(ch: Channel) {
|
||||
ch.pipeline().addLast("timeout", ReadTimeoutHandler(30, TimeUnit.SECONDS))
|
||||
// "crypto"
|
||||
.addLast("frame", FrameCodec())
|
||||
// compress
|
||||
.addLast("handler", CloudMinecraftHandler(user, null, frontEnd = false))
|
||||
}
|
||||
}
|
||||
|
||||
class CloudCompressionCodec(val threshold: Int) : MessageToMessageCodec<ByteBuf, ByteBuf>() {
|
||||
// https://github.com/Gerrygames/ClientViaVersion/blob/master/src/main/java/de/gerrygames/the5zig/clientviaversion/netty/CompressionEncoder.java
|
||||
private val inflater: Inflater =
|
||||
|
@ -3,7 +3,6 @@ package com.github.creeper123123321.viaaas
|
||||
import com.google.common.net.UrlEscapers
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonObject
|
||||
import de.gerrygames.viarewind.netty.EmptyChannelHandler
|
||||
import io.ktor.client.request.*
|
||||
import io.netty.bootstrap.Bootstrap
|
||||
import io.netty.buffer.ByteBuf
|
||||
@ -17,8 +16,6 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.slf4j.LoggerFactory
|
||||
import us.myles.ViaVersion.api.data.StoredObject
|
||||
import us.myles.ViaVersion.api.data.UserConnection
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion
|
||||
import us.myles.ViaVersion.api.type.Type
|
||||
import us.myles.ViaVersion.exception.CancelCodecException
|
||||
@ -39,29 +36,34 @@ import javax.naming.directory.InitialDirContext
|
||||
|
||||
val chLogger = LoggerFactory.getLogger("VIAaaS MC Handler")
|
||||
|
||||
class HandlerData(
|
||||
userConnection: UserConnection,
|
||||
var state: MinecraftConnectionState,
|
||||
var protocolId: Int? = null,
|
||||
class ConnectionData(
|
||||
val frontChannel: Channel,
|
||||
var backChannel: Channel? = null,
|
||||
var state: MinecraftConnectionState = HandshakeState(),
|
||||
var frontOnline: Boolean? = null, // todo
|
||||
var frontName: String? = null,
|
||||
var backName: String? = null,
|
||||
var backServerId: String? = null,
|
||||
var backPublicKey: PublicKey? = null,
|
||||
var backToken: ByteArray? = null,
|
||||
var frontToken: ByteArray? = null,
|
||||
var frontId: String? = null
|
||||
) : StoredObject(userConnection)
|
||||
var frontServerId: String? = null,
|
||||
var backServerId: String? = null,
|
||||
var frontVer: Int? = null,
|
||||
var backVer: Int? = null,
|
||||
) {
|
||||
val frontHandler get() = frontChannel.pipeline().get(CloudMinecraftHandler::class.java)
|
||||
val backHandler get() = backChannel?.pipeline()?.get(CloudMinecraftHandler::class.java)
|
||||
}
|
||||
|
||||
class CloudMinecraftHandler(
|
||||
val user: UserConnection,
|
||||
val data: ConnectionData,
|
||||
var other: Channel?,
|
||||
val frontEnd: Boolean
|
||||
) : SimpleChannelInboundHandler<ByteBuf>() {
|
||||
val data get() = user.get(HandlerData::class.java)!!
|
||||
var address: SocketAddress? = null
|
||||
var remoteAddress: SocketAddress? = null
|
||||
|
||||
override fun channelRead0(ctx: ChannelHandlerContext, msg: ByteBuf) {
|
||||
if (ctx.channel().isActive && !user.isPendingDisconnect && msg.isReadable) {
|
||||
if (ctx.channel().isActive && msg.isReadable) {
|
||||
data.state.handleMessage(this, ctx, msg)
|
||||
if (msg.isReadable) throw IllegalStateException("Remaining bytes!!!")
|
||||
//other?.write(msg.retain())
|
||||
@ -69,10 +71,7 @@ class CloudMinecraftHandler(
|
||||
}
|
||||
|
||||
override fun channelActive(ctx: ChannelHandlerContext) {
|
||||
address = ctx.channel().remoteAddress()
|
||||
if (user.get(HandlerData::class.java) == null) {
|
||||
user.put(HandlerData(user, HandshakeState()))
|
||||
}
|
||||
remoteAddress = ctx.channel().remoteAddress()
|
||||
}
|
||||
|
||||
override fun channelInactive(ctx: ChannelHandlerContext) {
|
||||
@ -106,12 +105,11 @@ interface MinecraftConnectionState {
|
||||
)
|
||||
|
||||
fun disconnect(handler: CloudMinecraftHandler, msg: String) {
|
||||
chLogger.info("Disconnected ${handler.address}: $msg")
|
||||
handler.user.isPendingDisconnect = true
|
||||
chLogger.info("Disconnected ${handler.remoteAddress}: $msg")
|
||||
}
|
||||
|
||||
fun onInactivated(handler: CloudMinecraftHandler) {
|
||||
chLogger.info(handler.address?.toString() + " inactivated")
|
||||
chLogger.info(handler.remoteAddress?.toString() + " inactivated")
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,76 +117,80 @@ class HandshakeState : MinecraftConnectionState {
|
||||
override fun handleMessage(handler: CloudMinecraftHandler, ctx: ChannelHandlerContext, msg: ByteBuf) {
|
||||
val packet = PacketRegistry.decode(
|
||||
msg,
|
||||
ProtocolVersion.getProtocol(handler.user.protocolInfo!!.serverProtocolVersion),
|
||||
ProtocolVersion.v1_8, // we still dont know what protocol it is
|
||||
State.HANDSHAKE,
|
||||
handler.frontEnd
|
||||
)
|
||||
if (packet !is HandshakePacket) throw IllegalArgumentException("Invalid packet!")
|
||||
handler.data.protocolId = packet.protocolId
|
||||
|
||||
handler.data.frontVer = packet.protocolId
|
||||
when (packet.nextState.ordinal) {
|
||||
1 -> handler.data.state = StatusState
|
||||
2 -> handler.data.state = LoginState
|
||||
else -> throw IllegalStateException("Invalid next state")
|
||||
}
|
||||
|
||||
if (!handler.user.get(CloudData::class.java)!!.hadHostname && VIAaaSConfig.requireHostName) {
|
||||
val parsed = VIAaaSAddress().parse(packet.address.substringBefore(0.toChar()), VIAaaSConfig.hostName)
|
||||
val backProto = parsed.protocol ?: 47 // todo autodetection
|
||||
val hadHostname = parsed.viaSuffix != null
|
||||
|
||||
packet.address = parsed.realAddress!!
|
||||
packet.port = parsed.port ?: if (VIAaaSConfig.defaultBackendPort == -1) {
|
||||
packet.port
|
||||
} else {
|
||||
VIAaaSConfig.defaultBackendPort
|
||||
}
|
||||
|
||||
handler.data.backVer = backProto
|
||||
handler.data.frontOnline = parsed.online
|
||||
handler.data.backName = parsed.altUsername
|
||||
|
||||
val playerAddr = handler.data.frontHandler.remoteAddress
|
||||
chLogger.info("Connecting $playerAddr (${handler.data.frontVer}) -> ${packet.address}:${packet.port} ($backProto)")
|
||||
|
||||
if (!hadHostname && VIAaaSConfig.requireHostName) {
|
||||
throw UnsupportedOperationException("This VIAaaS instance requires you to use the hostname")
|
||||
}
|
||||
|
||||
handler.user.channel!!.setAutoRead(false)
|
||||
handler.data.frontChannel.setAutoRead(false)
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
val frontHandler = handler.user.channel!!.pipeline().get(CloudMinecraftHandler::class.java)
|
||||
val frontHandler = handler.data.frontHandler
|
||||
try {
|
||||
var srvResolvedAddr = packet.address
|
||||
var srvResolvedPort = packet.port
|
||||
if (srvResolvedPort == 25565) {
|
||||
try {
|
||||
// https://github.com/GeyserMC/Geyser/blob/99e72f35b308542cf0dbfb5b58816503c3d6a129/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
|
||||
val attr = InitialDirContext()
|
||||
.getAttributes("dns:///_minecraft._tcp.$srvResolvedAddr", arrayOf("SRV"))["SRV"]
|
||||
if (attr != null && attr.size() > 0) {
|
||||
val record = (attr.get(0) as String).split(" ")
|
||||
srvResolvedAddr = record[3]
|
||||
srvResolvedPort = record[2].toInt()
|
||||
}
|
||||
} catch (ignored: NameNotFoundException) {
|
||||
}
|
||||
}
|
||||
val socketAddr = InetSocketAddress(InetAddress.getByName(srvResolvedAddr), srvResolvedPort)
|
||||
val addrInfo = socketAddr.address
|
||||
if (VIAaaSConfig.blockLocalAddress && (addrInfo.isSiteLocalAddress
|
||||
|| addrInfo.isLoopbackAddress
|
||||
|| addrInfo.isLinkLocalAddress
|
||||
|| addrInfo.isAnyLocalAddress)
|
||||
) throw SecurityException("Local addresses aren't allowed")
|
||||
val srvResolved = resolveSrv(packet.address, packet.port)
|
||||
packet.address = srvResolved.first
|
||||
packet.port = srvResolved.second
|
||||
|
||||
val bootstrap = Bootstrap().handler(BackendInit(handler.user))
|
||||
val socketAddr = InetSocketAddress(InetAddress.getByName(packet.address), packet.port)
|
||||
|
||||
if (checkLocalAddress(socketAddr.address)) {
|
||||
throw SecurityException("Local addresses aren't allowed")
|
||||
}
|
||||
|
||||
val bootstrap = Bootstrap().handler(BackendInit(handler.data))
|
||||
.channelFactory(channelSocketFactory())
|
||||
.group(handler.user.channel!!.eventLoop())
|
||||
.group(handler.data.frontChannel.eventLoop())
|
||||
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 15_000) // Half of mc timeout
|
||||
.connect(socketAddr)
|
||||
|
||||
bootstrap.addListener {
|
||||
if (it.isSuccess) {
|
||||
CloudHeadProtocol.logger.info("Connected ${frontHandler.address} -> $socketAddr")
|
||||
chLogger.info("Connected ${frontHandler.remoteAddress} -> $socketAddr")
|
||||
|
||||
val backChan = bootstrap.channel() as SocketChannel
|
||||
backChan.pipeline().get(CloudMinecraftHandler::class.java).other = handler.user.channel
|
||||
handler.data.backChannel = backChan
|
||||
frontHandler.other = backChan
|
||||
|
||||
packet.address = srvResolvedAddr
|
||||
packet.port = srvResolvedPort
|
||||
forward(handler, packet)
|
||||
backChan.flush()
|
||||
|
||||
handler.user.channel!!.setAutoRead(true)
|
||||
handler.data.frontChannel.setAutoRead(true)
|
||||
} else {
|
||||
// We're in the event loop
|
||||
frontHandler.disconnect("Couldn't connect: " + it.cause().toString())
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
handler.user.channel!!.eventLoop().submit {
|
||||
handler.data.frontChannel.eventLoop().submit {
|
||||
frontHandler.disconnect("Couldn't connect: $e")
|
||||
}
|
||||
}
|
||||
@ -196,7 +198,7 @@ class HandshakeState : MinecraftConnectionState {
|
||||
}
|
||||
|
||||
override fun disconnect(handler: CloudMinecraftHandler, msg: String) {
|
||||
handler.user.channel?.close() // Not worth logging
|
||||
handler.data.frontChannel.close() // Not worth logging
|
||||
}
|
||||
|
||||
override fun onInactivated(handler: CloudMinecraftHandler) {
|
||||
@ -208,7 +210,7 @@ object LoginState : MinecraftConnectionState {
|
||||
override fun handleMessage(handler: CloudMinecraftHandler, ctx: ChannelHandlerContext, msg: ByteBuf) {
|
||||
val packet = PacketRegistry.decode(
|
||||
msg,
|
||||
ProtocolVersion.getProtocol(handler.user.protocolInfo!!.serverProtocolVersion),
|
||||
ProtocolVersion.getProtocol(handler.data.frontVer!!),
|
||||
State.LOGIN,
|
||||
handler.frontEnd
|
||||
)
|
||||
@ -232,16 +234,24 @@ object LoginState : MinecraftConnectionState {
|
||||
}
|
||||
|
||||
private fun handleCompression(handler: CloudMinecraftHandler, setCompression: SetCompression) {
|
||||
val pipe = handler.user.channel!!.pipeline()
|
||||
val pipe = handler.data.frontChannel.pipeline()
|
||||
val threshold = setCompression.threshold
|
||||
|
||||
val backPipe = pipe.get(CloudMinecraftHandler::class.java).other!!.pipeline()
|
||||
backPipe.addAfter("frame", "compress", CloudCompressionCodec(threshold))
|
||||
if (threshold != -1) {
|
||||
backPipe.addAfter("frame", "compress", CloudCompressionCodec(threshold))
|
||||
} else if (backPipe.get("compress") != null) {
|
||||
backPipe.remove("compress")
|
||||
}
|
||||
|
||||
forward(handler, setCompression)
|
||||
|
||||
pipe.addAfter("frame", "compress", CloudCompressionCodec(threshold))
|
||||
pipe.addAfter("frame", "decompress", EmptyChannelHandler()) // ViaRewind compat workaround
|
||||
if (threshold != -1) {
|
||||
pipe.addAfter("frame", "compress", CloudCompressionCodec(threshold))
|
||||
// todo viarewind backend compression
|
||||
} else if (pipe.get("compress") != null) {
|
||||
pipe.remove("compress")
|
||||
}
|
||||
}
|
||||
|
||||
fun handleCryptoRequest(handler: CloudMinecraftHandler, cryptoRequest: CryptoRequest) {
|
||||
@ -261,7 +271,7 @@ object LoginState : MinecraftConnectionState {
|
||||
it
|
||||
}
|
||||
data.frontToken = token
|
||||
data.frontId = id
|
||||
data.frontServerId = id
|
||||
|
||||
cryptoRequest.serverId = id
|
||||
cryptoRequest.publicKey = mcCryptoKey.public
|
||||
@ -281,9 +291,9 @@ object LoginState : MinecraftConnectionState {
|
||||
val aesEn = mcCfb8(frontKey, Cipher.ENCRYPT_MODE)
|
||||
val aesDe = mcCfb8(frontKey, Cipher.DECRYPT_MODE)
|
||||
|
||||
handler.user.channel!!.pipeline().addBefore("frame", "crypto", CloudCrypto(aesDe, aesEn))
|
||||
handler.data.frontChannel.pipeline().addBefore("frame", "crypto", CloudCrypto(aesDe, aesEn))
|
||||
|
||||
generateServerHash(handler.data.frontId!!, frontKey, mcCryptoKey.public)
|
||||
generateServerHash(handler.data.frontServerId!!, frontKey, mcCryptoKey.public)
|
||||
}
|
||||
|
||||
val backKey = ByteArray(16).let {
|
||||
@ -293,14 +303,13 @@ object LoginState : MinecraftConnectionState {
|
||||
|
||||
val backHash = generateServerHash(handler.data.backServerId!!, backKey, handler.data.backPublicKey!!)
|
||||
|
||||
handler.user.channel!!.setAutoRead(false)
|
||||
handler.data.frontChannel.setAutoRead(false)
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val profile = httpClient.get<JsonObject?>(
|
||||
"https://sessionserver.mojang.com/session/minecraft/hasJoined?username=" +
|
||||
"${
|
||||
UrlEscapers.urlFormParameterEscaper().escape(handler.data.frontName!!)
|
||||
}&serverId=$frontHash"
|
||||
UrlEscapers.urlFormParameterEscaper().escape(handler.data.frontName!!) +
|
||||
"&serverId=$frontHash"
|
||||
)
|
||||
?: throw IllegalArgumentException("Couldn't authenticate with session servers")
|
||||
|
||||
@ -308,7 +317,7 @@ object LoginState : MinecraftConnectionState {
|
||||
fromUndashed(profile.get("id")!!.asString),
|
||||
handler.data.backName!!,
|
||||
backHash,
|
||||
handler.address!!, // Frontend handler
|
||||
handler.remoteAddress!!, // Frontend handler
|
||||
handler.data.backPublicKey!!
|
||||
)
|
||||
|
||||
@ -331,13 +340,13 @@ object LoginState : MinecraftConnectionState {
|
||||
} catch (e: Exception) {
|
||||
handler.disconnect("Online mode error: $e")
|
||||
}
|
||||
handler.user.channel!!.setAutoRead(true)
|
||||
handler.data.frontChannel.setAutoRead(true)
|
||||
}
|
||||
}
|
||||
|
||||
fun handleLoginStart(handler: CloudMinecraftHandler, loginStart: LoginStart) {
|
||||
handler.data.frontName = loginStart.username
|
||||
handler.data.backName = handler.user.get(CloudData::class.java)!!.altName ?: handler.data.frontName
|
||||
handler.data.backName = handler.data.backName ?: handler.data.frontName
|
||||
|
||||
loginStart.username = handler.data.backName!!
|
||||
forward(handler, loginStart)
|
||||
@ -350,9 +359,9 @@ object LoginState : MinecraftConnectionState {
|
||||
try {
|
||||
packet.writeByte(0) // id 0 disconnect
|
||||
Type.STRING.write(packet, Gson().toJson("[VIAaaS] §c$msg"))
|
||||
handler.user
|
||||
.sendRawPacketFuture(packet.retain())
|
||||
.addListener { handler.user.channel?.close() }
|
||||
handler.data.frontChannel
|
||||
.writeAndFlush(packet.retain())
|
||||
.addListener { handler.data.frontChannel.close() }
|
||||
} finally {
|
||||
packet.release()
|
||||
}
|
||||
@ -364,7 +373,8 @@ object StatusState : MinecraftConnectionState {
|
||||
val i = msg.readerIndex()
|
||||
if (Type.VAR_INT.readPrimitive(msg) !in 0..1) throw IllegalArgumentException("Invalid packet id!")
|
||||
msg.readerIndex(i)
|
||||
handler.other!!.write(msg.retain())
|
||||
handler.other!!.write(msg.retainedSlice())
|
||||
msg.clear()
|
||||
}
|
||||
|
||||
override fun disconnect(handler: CloudMinecraftHandler, msg: String) {
|
||||
@ -377,8 +387,8 @@ object StatusState : MinecraftConnectionState {
|
||||
packet, """{"version": {"name": "VIAaaS", "protocol": -1}, "players":
|
||||
| {"max": 0, "online": 0, "sample": []}, "description": {"text": ${Gson().toJson("§c$msg")}}}""".trimMargin()
|
||||
)
|
||||
handler.user.sendRawPacketFuture(packet.retain())
|
||||
.addListener { handler.user.channel?.close() }
|
||||
handler.data.frontChannel.writeAndFlush(packet.retain())
|
||||
.addListener { handler.data.frontChannel.close() }
|
||||
} finally {
|
||||
packet.release()
|
||||
}
|
||||
@ -390,12 +400,13 @@ object PlayState : MinecraftConnectionState {
|
||||
val i = msg.readerIndex()
|
||||
if (Type.VAR_INT.readPrimitive(msg) !in 0..127) throw IllegalArgumentException("Invalid packet id!")
|
||||
msg.readerIndex(i)
|
||||
handler.other!!.write(msg.retain())
|
||||
handler.other!!.write(msg.retainedSlice())
|
||||
msg.clear()
|
||||
}
|
||||
|
||||
override fun disconnect(handler: CloudMinecraftHandler, msg: String) {
|
||||
super.disconnect(handler, msg)
|
||||
handler.user.channel?.close()
|
||||
handler.data.frontChannel.close()
|
||||
}
|
||||
}
|
||||
|
||||
@ -440,9 +451,32 @@ fun generateServerHash(serverId: String, sharedSecret: ByteArray?, key: PublicKe
|
||||
private fun forward(handler: CloudMinecraftHandler, packet: Packet) {
|
||||
val msg = ByteBufAllocator.DEFAULT.buffer()
|
||||
try {
|
||||
PacketRegistry.encode(packet, msg, ProtocolVersion.getProtocol(handler.data.protocolId!!))
|
||||
PacketRegistry.encode(packet, msg, ProtocolVersion.getProtocol(handler.data.frontVer!!))
|
||||
handler.other!!.write(msg.retain())
|
||||
} finally {
|
||||
msg.release()
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveSrv(address: String, port: Int): Pair<String, Int> {
|
||||
if (port == 25565) {
|
||||
try {
|
||||
// https://github.com/GeyserMC/Geyser/blob/99e72f35b308542cf0dbfb5b58816503c3d6a129/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
|
||||
val attr = InitialDirContext()
|
||||
.getAttributes("dns:///_minecraft._tcp.$address", arrayOf("SRV"))["SRV"]
|
||||
if (attr != null && attr.size() > 0) {
|
||||
val record = (attr.get(0) as String).split(" ")
|
||||
return record[3] to record[2].toInt()
|
||||
}
|
||||
} catch (ignored: NameNotFoundException) {
|
||||
}
|
||||
}
|
||||
return address to port
|
||||
}
|
||||
|
||||
private fun checkLocalAddress(inetAddress: InetAddress): Boolean {
|
||||
return VIAaaSConfig.blockLocalAddress && (inetAddress.isSiteLocalAddress
|
||||
|| inetAddress.isLoopbackAddress
|
||||
|| inetAddress.isLinkLocalAddress
|
||||
|| inetAddress.isAnyLocalAddress)
|
||||
}
|
@ -185,8 +185,7 @@ class CloudTask(val obj: Future<*>) : TaskId {
|
||||
|
||||
object CloudVersionProvider : VersionProvider() {
|
||||
override fun getServerProtocol(connection: UserConnection): Int {
|
||||
val data = connection.get(CloudData::class.java)
|
||||
val ver = data?.backendVer
|
||||
val ver = connection.channel!!.pipeline().get(CloudMinecraftHandler::class.java).data.backVer
|
||||
if (ver != null) return ver
|
||||
return super.getServerProtocol(connection)
|
||||
}
|
||||
|
@ -1,76 +0,0 @@
|
||||
package com.github.creeper123123321.viaaas
|
||||
|
||||
import org.slf4j.LoggerFactory
|
||||
import us.myles.ViaVersion.api.PacketWrapper
|
||||
import us.myles.ViaVersion.api.data.StoredObject
|
||||
import us.myles.ViaVersion.api.data.UserConnection
|
||||
import us.myles.ViaVersion.api.protocol.Protocol
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolPipeline
|
||||
import us.myles.ViaVersion.api.protocol.SimpleProtocol
|
||||
import us.myles.ViaVersion.api.remapper.PacketRemapper
|
||||
import us.myles.ViaVersion.api.type.Type
|
||||
import us.myles.ViaVersion.packets.State
|
||||
|
||||
class CloudPipeline(userConnection: UserConnection) : ProtocolPipeline(userConnection) {
|
||||
override fun registerPackets() {
|
||||
super.registerPackets()
|
||||
add(CloudHeadProtocol) // add() will add tail protocol
|
||||
}
|
||||
|
||||
override fun add(protocol: Protocol<*, *, *, *>?) {
|
||||
super.add(protocol)
|
||||
pipes().removeIf { it == CloudHeadProtocol }
|
||||
pipes().add(0, CloudHeadProtocol)
|
||||
}
|
||||
}
|
||||
|
||||
object CloudHeadProtocol : SimpleProtocol() {
|
||||
val logger = LoggerFactory.getLogger("CloudHandlerProtocol")
|
||||
override fun registerPackets() {
|
||||
this.registerIncoming(State.HANDSHAKE, 0, 0, object : PacketRemapper() {
|
||||
override fun registerMap() {
|
||||
handler { wrapper: PacketWrapper ->
|
||||
val playerVer = wrapper.passthrough(Type.VAR_INT)
|
||||
val addr = wrapper.read(Type.STRING) // Server Address
|
||||
val receivedPort = wrapper.read(Type.UNSIGNED_SHORT)
|
||||
|
||||
val parsed = VIAaaSAddress().parse(addr.substringBefore(0.toChar()), VIAaaSConfig.hostName)
|
||||
val backPort = parsed.port ?: if (VIAaaSConfig.defaultBackendPort == -1) {
|
||||
receivedPort
|
||||
} else {
|
||||
VIAaaSConfig.defaultBackendPort
|
||||
}
|
||||
val backAddr = parsed.realAddress
|
||||
val backProto = parsed.protocol ?: 47
|
||||
|
||||
wrapper.write(Type.STRING, backAddr)
|
||||
wrapper.write(Type.UNSIGNED_SHORT, backPort)
|
||||
|
||||
val playerAddr = wrapper.user().channel!!.pipeline()
|
||||
.get(CloudMinecraftHandler::class.java)!!.address
|
||||
logger.info("Connecting $playerAddr ($playerVer) -> $backAddr:$backPort ($backProto)")
|
||||
|
||||
wrapper.user().put(
|
||||
CloudData(
|
||||
userConnection = wrapper.user(),
|
||||
backendVer = backProto,
|
||||
frontOnline = parsed.online,
|
||||
altName = parsed.altUsername,
|
||||
hadHostname = parsed.viaSuffix != null
|
||||
)
|
||||
)
|
||||
|
||||
wrapper.passthrough(Type.VAR_INT) // Next state
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
data class CloudData(
|
||||
val userConnection: UserConnection,
|
||||
var backendVer: Int,
|
||||
var frontOnline: Boolean,
|
||||
var altName: String?,
|
||||
var hadHostname: Boolean
|
||||
) : StoredObject(userConnection)
|
@ -105,7 +105,7 @@ fun main(args: Array<String>) {
|
||||
MappingDataLoader.enableMappingsCache()
|
||||
Via.getManager().init()
|
||||
CloudRewind.init(ViaRewindConfigImpl(File("config/viarewind.yml")))
|
||||
CloudBackwards.init(File("config/viabackwards.yml"))
|
||||
CloudBackwards.init(File("config/viabackwards"))
|
||||
|
||||
val parent = eventLoopGroup()
|
||||
val child = eventLoopGroup()
|
||||
|
@ -38,9 +38,6 @@ import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.TimeoutException
|
||||
import kotlin.collections.set
|
||||
|
||||
|
||||
// todo https://minecraft.id/documentation
|
||||
|
||||
val viaWebServer = WebDashboardServer()
|
||||
val webLogger = LoggerFactory.getLogger("VIAaaS Web")
|
||||
|
||||
|
@ -221,11 +221,11 @@ function renderActions() {
|
||||
add.innerText = "Listen to " + username;
|
||||
add.href = "#";
|
||||
add.onclick = () => {
|
||||
mcauth_code = null;
|
||||
socket.send(JSON.stringify({
|
||||
"action": "minecraft_id_login",
|
||||
"username": username,
|
||||
"code": mcauth_code}));
|
||||
mcauth_code = null;
|
||||
};
|
||||
actions.appendChild(p);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user