1.18 packets, implement openauthmod for <1.13

This commit is contained in:
creeper123123321 2021-12-04 12:17:50 -03:00
parent 895d558852
commit cb509383c0
5 changed files with 76 additions and 15 deletions

View File

@ -32,6 +32,10 @@ public class CompressionCodec extends MessageToMessageCodec<ByteBuf, ByteBuf> {
this.threshold = threshold;
}
public int getThreshold() {
return threshold;
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) {
var level = VIAaaSConfig.INSTANCE.getCompressionLevel();

View File

@ -20,6 +20,7 @@ import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.ClientboundPacke
import com.viaversion.viaversion.protocols.protocol1_16_2to1_16_1.ClientboundPackets1_16_2
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.ClientboundPackets1_16
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.ClientboundPackets1_17
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPackets1_18
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9
import io.netty.buffer.ByteBuf
@ -59,7 +60,8 @@ object PacketRegistry {
ProtocolVersion.v1_15..ProtocolVersion.v1_15_2 to ClientboundPackets1_15.DISCONNECT.id,
ProtocolVersion.v1_16..ProtocolVersion.v1_16_1 to ClientboundPackets1_16.DISCONNECT.id,
ProtocolVersion.v1_16_2..ProtocolVersion.v1_16_4 to ClientboundPackets1_16_2.DISCONNECT.id,
ProtocolVersion.v1_17..ProtocolVersion.v1_17_1 to ClientboundPackets1_17.DISCONNECT.id
ProtocolVersion.v1_17..ProtocolVersion.v1_17_1 to ClientboundPackets1_17.DISCONNECT.id,
ProtocolVersion.v1_18.singleton to ClientboundPackets1_18.DISCONNECT.id
)
)
@ -72,7 +74,8 @@ object PacketRegistry {
ProtocolVersion.v1_15..ProtocolVersion.v1_15_2 to ClientboundPackets1_15.PLUGIN_MESSAGE.id,
ProtocolVersion.v1_16..ProtocolVersion.v1_16_1 to ClientboundPackets1_16.PLUGIN_MESSAGE.id,
ProtocolVersion.v1_16_2..ProtocolVersion.v1_16_4 to ClientboundPackets1_16_2.PLUGIN_MESSAGE.id,
ProtocolVersion.v1_17..ProtocolVersion.v1_17_1 to ClientboundPackets1_17.PLUGIN_MESSAGE.id
ProtocolVersion.v1_17..ProtocolVersion.v1_17_1 to ClientboundPackets1_17.PLUGIN_MESSAGE.id,
ProtocolVersion.v1_18.singleton to ClientboundPackets1_18.PLUGIN_MESSAGE.id
)
)

View File

@ -1,5 +1,6 @@
package com.viaversion.aas.handler
import com.viaversion.aas.codec.CompressionCodec
import com.viaversion.aas.codec.CryptoCodec
import com.viaversion.aas.handler.state.ConnectionState
import com.viaversion.aas.handler.state.HandshakeState
@ -15,4 +16,5 @@ class ConnectionData(
val frontHandler get() = frontChannel.pipeline()[MinecraftHandler::class.java]
val backHandler get() = backChannel?.pipeline()?.get(MinecraftHandler::class.java)
val frontEncrypted get() = frontChannel.pipeline()[CryptoCodec::class.java] != null
val compressionLevel get() = frontChannel.pipeline()[CompressionCodec::class.java]?.threshold ?: -1
}

View File

@ -18,6 +18,7 @@ import io.netty.buffer.ByteBufAllocator
import io.netty.channel.Channel
import io.netty.channel.ChannelHandlerContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.future.await
import kotlinx.coroutines.launch
import java.security.KeyPair
@ -98,25 +99,40 @@ class LoginState : ConnectionState {
fun reauthMessage(handler: MinecraftHandler, backName: String, backHash: String): CompletableFuture<Boolean> {
if (!handler.data.frontEncrypted
|| handler.data.frontVer!! < ProtocolVersion.v1_13.version
|| !frontName.equals(backName, ignoreCase = true)
) {
callbackPluginReauth.complete(false)
return callbackPluginReauth
}
val buf = ByteBufAllocator.DEFAULT.buffer()
try {
Type.STRING.write(buf, backHash)
if (handler.data.frontVer!! < ProtocolVersion.v1_13.version) {
encodeOpenAuth(backHash).forEach { data ->
send(handler.data.frontChannel, SetCompression().also { it.threshold = data })
}
send(
handler.data.frontChannel,
SetCompression().also { it.threshold = handler.data.compressionLevel },
flush = true
)
val packet = PluginRequest()
packet.id = ThreadLocalRandom.current().nextInt()
packet.channel = "openauthmod:join"
packet.data = readRemainingBytes(buf)
send(handler.data.frontChannel, packet, true)
pendingReauth = packet.id
} finally {
buf.release()
handler.coroutineScope.launch {
delay(5000)
callbackPluginReauth.complete(false)
}
} else {
val buf = ByteBufAllocator.DEFAULT.buffer()
try {
Type.STRING.write(buf, backHash)
val packet = PluginRequest()
packet.id = ThreadLocalRandom.current().nextInt()
packet.channel = "openauthmod:join"
packet.data = readRemainingBytes(buf)
send(handler.data.frontChannel, packet, true)
pendingReauth = packet.id
} finally {
buf.release()
}
}
return callbackPluginReauth
}
@ -192,7 +208,13 @@ class LoginState : ConnectionState {
}
fun handleLoginStart(handler: MinecraftHandler, loginStart: LoginStart) {
if (started) throw StacklessException("Login already started")
if (started) {
if (loginStart.username.startsWith(OPENAUTH_MAGIC_PREFIX)) {
callbackPluginReauth.complete(loginStart.username.removePrefix(OPENAUTH_MAGIC_PREFIX).toBoolean())
return
}
throw StacklessException("Login already started")
}
started = true
VIAaaSConfig.maxPlayers?.let {

View File

@ -13,6 +13,7 @@ import com.viaversion.viaversion.api.protocol.packet.State
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion
import io.ktor.server.netty.*
import io.netty.bootstrap.Bootstrap
import io.netty.buffer.Unpooled
import io.netty.channel.Channel
import io.netty.channel.ChannelOption
import io.netty.channel.socket.SocketChannel
@ -20,9 +21,11 @@ import io.netty.handler.proxy.ProxyHandler
import io.netty.resolver.NoopAddressResolverGroup
import kotlinx.coroutines.future.await
import kotlinx.coroutines.withTimeout
import java.math.BigInteger
import java.net.Inet4Address
import java.net.InetSocketAddress
import java.net.URI
import kotlin.math.ceil
private suspend fun createBackChannel(
handler: MinecraftHandler,
@ -151,3 +154,30 @@ suspend fun connectBack(
tryBackAddresses(handler, addresses, state, extraData)
}
// https://github.com/RaphiMC/OpenAuthMod/blob/fa66e78fe5c0e748c1b8c61624bf283fb8bc06dd/src/main/java/com/github/oam/utils/IntTo3ByteCodec.java#L16
fun encodeOpenAuth(hash: String): IntArray {
val buffer = Unpooled.wrappedBuffer(BigInteger(hash, 16).toByteArray())
val out = IntArray(2 + ceil(buffer.readableBytes().toDouble() / 3.0).toInt())
val magic = 0xfdebf3fd.toInt()
out[0] = magic
out[out.size - 1] = magic
for (i in 1 until out.size - 1) {
var int = 1.shl(31)
.or(1.shl(30)).or(buffer.readUnsignedByte().toInt().shl(16))
if (buffer.isReadable) {
int = int.or(1.shl(29)).or(buffer.readUnsignedByte().toInt().shl(8))
}
if (buffer.isReadable) {
int = int.or(1.shl(28)).or(buffer.readUnsignedByte().toInt())
}
out[i] = int
}
return out
}
val OPENAUTH_MAGIC_PREFIX = String(byteArrayOf(2, 20, 12, 3), Charsets.UTF_8)