fixed mojang account refresh, code cleanup, parse status packets

This commit is contained in:
creeper123123321 2021-02-06 20:09:51 -03:00
parent e966a45540
commit 764f849d79
4 changed files with 106 additions and 97 deletions

View File

@ -51,7 +51,7 @@ class BackendInit(val connectionData: ConnectionData) : ChannelInitializer<Chann
}
}
class CloudMinecraftCodec: MessageToMessageCodec<ByteBuf, Packet>() {
class CloudMinecraftCodec : MessageToMessageCodec<ByteBuf, Packet>() {
override fun encode(ctx: ChannelHandlerContext, msg: Packet, out: MutableList<Any>) {
if (!ctx.channel().isActive) return
val buf = ByteBufAllocator.DEFAULT.buffer()
@ -67,9 +67,13 @@ class CloudMinecraftCodec: MessageToMessageCodec<ByteBuf, Packet>() {
override fun decode(ctx: ChannelHandlerContext, msg: ByteBuf, out: MutableList<Any>) {
if (!ctx.channel().isActive || !msg.isReadable) return
val handler = ctx.pipeline().get(CloudMinecraftHandler::class.java)
out.add(PacketRegistry.decode(msg,
handler.data.frontVer ?: 0,
handler.data.state.state, handler.frontEnd))
out.add(
PacketRegistry.decode(
msg,
handler.data.frontVer ?: 0,
handler.data.state.state, handler.frontEnd
)
)
if (msg.isReadable) throw IllegalStateException("Remaining bytes!!!")
}
}
@ -197,31 +201,17 @@ class FrameCodec : ByteToMessageCodec<ByteBuf>() {
class CloudViaCodec(val info: UserConnection) : MessageToMessageCodec<ByteBuf, ByteBuf>() {
override fun decode(ctx: ChannelHandlerContext, bytebuf: ByteBuf, out: MutableList<Any>) {
if (!info.checkIncomingPacket()) throw CancelDecoderException.generate(null)
if (!info.shouldTransformPacket()) {
out.add(bytebuf.retain())
return
}
val transformedBuf: ByteBuf = ctx.alloc().buffer().writeBytes(bytebuf)
try {
info.transformIncoming(transformedBuf, CancelDecoderException::generate)
out.add(transformedBuf.retain())
} finally {
transformedBuf.release()
if (info.shouldTransformPacket()) {
info.transformIncoming(bytebuf, CancelDecoderException::generate)
}
out.add(bytebuf.retain())
}
override fun encode(ctx: ChannelHandlerContext, bytebuf: ByteBuf, out: MutableList<Any>) {
if (!info.checkOutgoingPacket()) throw CancelEncoderException.generate(null)
if (!info.shouldTransformPacket()) {
out.add(bytebuf.retain())
return
}
val transformedBuf: ByteBuf = ctx.alloc().buffer().writeBytes(bytebuf)
try {
info.transformOutgoing(transformedBuf, CancelEncoderException::generate)
out.add(transformedBuf.retain())
} finally {
transformedBuf.release()
if (info.shouldTransformPacket()) {
info.transformOutgoing(bytebuf, CancelEncoderException::generate)
}
out.add(bytebuf.retain())
}
}

View File

@ -6,14 +6,12 @@ import com.google.gson.Gson
import com.google.gson.JsonObject
import io.ktor.client.request.*
import io.netty.bootstrap.Bootstrap
import io.netty.buffer.ByteBufAllocator
import io.netty.channel.*
import io.netty.channel.socket.SocketChannel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.slf4j.LoggerFactory
import us.myles.ViaVersion.api.type.Type
import us.myles.ViaVersion.exception.CancelCodecException
import us.myles.ViaVersion.packets.State
import java.math.BigInteger
@ -270,7 +268,7 @@ class LoginState : MinecraftConnectionState {
cryptoRequest.publicKey = mcCryptoKey.public
cryptoRequest.token = token
frontHandler.data.frontChannel.writeAndFlush(cryptoRequest)
sendPacket(frontHandler.data.frontChannel, cryptoRequest, true)
}
fun handleCryptoRequest(handler: CloudMinecraftHandler, cryptoRequest: CryptoRequest) {
@ -386,16 +384,9 @@ class LoginState : MinecraftConnectionState {
override fun disconnect(handler: CloudMinecraftHandler, msg: String) {
super.disconnect(handler, msg)
val packet = ByteBufAllocator.DEFAULT.buffer()
try {
packet.writeByte(0) // id 0 disconnect
Type.STRING.write(packet, Gson().toJson("[VIAaaS] §c$msg"))
handler.data.frontChannel
.writeAndFlush(packet.retain())
.addListener { handler.data.frontChannel.close() }
} finally {
packet.release()
}
val packet = LoginDisconnect()
packet.msg = Gson().toJson("[VIAaaS] §c$msg")
sendFlushPacketClose(handler.data.frontChannel, packet)
}
}
@ -404,25 +395,17 @@ object StatusState : MinecraftConnectionState {
get() = State.STATUS
override fun handlePacket(handler: CloudMinecraftHandler, ctx: ChannelHandlerContext, packet: Packet) {
if ((packet as UnknownPacket).id !in 0..1) throw IllegalArgumentException("Invalid packet id!")
if (packet is UnknownPacket) throw IllegalArgumentException("Invalid packet")
forward(handler, packet)
}
override fun disconnect(handler: CloudMinecraftHandler, msg: String) {
super.disconnect(handler, msg)
val packet = ByteBufAllocator.DEFAULT.buffer()
try {
packet.writeByte(0) // id 0 disconnect
Type.STRING.write(
packet, """{"version": {"name": "VIAaaS", "protocol": -1}, "players":
| {"max": 0, "online": 0, "sample": []}, "description": {"text": ${Gson().toJson("§c$msg")}}}""".trimMargin()
)
handler.data.frontChannel.writeAndFlush(packet.retain())
.addListener { handler.data.frontChannel.close() }
} finally {
packet.release()
}
val packet = StatusResponse()
packet.json = """{"version": {"name": "VIAaaS", "protocol": -1}, "players": {"max": 0, "online": 0,
| "sample": []}, "description": {"text": ${Gson().toJson("§c$msg")}}}""".trimMargin()
sendFlushPacketClose(handler.data.frontChannel, packet)
}
}
@ -479,17 +462,19 @@ fun generateServerHash(serverId: String, sharedSecret: ByteArray?, key: PublicKe
return twosComplementHexdigest(digest.digest())
}
private fun sendFlushPacketClose(ch: Channel, packet: Packet) {
ch.writeAndFlush(packet).addListener { ch.close() }
}
private fun forward(handler: CloudMinecraftHandler, packet: Packet, flush: Boolean = false) {
val msg = ByteBufAllocator.DEFAULT.buffer()
try {
val ch = handler.other!!
if (flush) {
ch.writeAndFlush(packet, ch.voidPromise())
} else {
ch.write(packet, ch.voidPromise())
}
} finally {
msg.release()
sendPacket(handler.other!!, packet, flush)
}
private fun sendPacket(ch: Channel, packet: Packet, flush: Boolean = false) {
if (flush) {
ch.writeAndFlush(packet, ch.voidPromise())
} else {
ch.write(packet, ch.voidPromise())
}
}

View File

@ -24,40 +24,29 @@ object PacketRegistry {
val entries = mutableListOf<RegistryEntry>()
init {
entries.add(
RegistryEntry(Range.all(), State.HANDSHAKE, 0, true, ::HandshakePacket, HandshakePacket::class.java)
)
entries.add(
RegistryEntry(Range.all(), State.LOGIN, 0, true, ::LoginStart, LoginStart::class.java)
)
entries.add(
RegistryEntry(Range.all(), State.LOGIN, 1, true, ::CryptoResponse, CryptoResponse::class.java)
)
entries.add(
RegistryEntry(
Range.atLeast(ProtocolVersion.v1_13.version),
State.LOGIN,
2,
true,
::PluginResponse,
PluginResponse::class.java
)
)
entries.add(
RegistryEntry(Range.all(), State.LOGIN, 0, false, ::LoginDisconnect, LoginDisconnect::class.java)
)
entries.add(
RegistryEntry(Range.all(), State.LOGIN, 1, false, ::CryptoRequest, CryptoRequest::class.java)
)
entries.add(
RegistryEntry(Range.all(), State.LOGIN, 2, false, ::LoginSuccess, LoginSuccess::class.java)
)
entries.add(
RegistryEntry(Range.all(), State.LOGIN, 3, false, ::SetCompression, SetCompression::class.java)
)
entries.add(
RegistryEntry(Range.all(), State.LOGIN, 4, false, ::PluginRequest, PluginRequest::class.java)
)
register(Range.all(), State.HANDSHAKE, 0, true, ::HandshakePacket)
register(Range.all(), State.LOGIN, 0, true, ::LoginStart)
register(Range.all(), State.LOGIN, 1, true, ::CryptoResponse)
register(Range.atLeast(ProtocolVersion.v1_13.version), State.LOGIN, 2, true, ::PluginResponse)
register(Range.all(), State.LOGIN, 0, false, ::LoginDisconnect)
register(Range.all(), State.LOGIN, 1, false, ::CryptoRequest)
register(Range.all(), State.LOGIN, 2, false, ::LoginSuccess)
register(Range.all(), State.LOGIN, 3, false, ::SetCompression)
register(Range.all(), State.LOGIN, 4, false, ::PluginRequest)
register(Range.all(), State.STATUS, 0, true, ::StatusRequest)
register(Range.all(), State.STATUS, 1, true, ::StatusPing)
register(Range.all(), State.STATUS, 0, false, ::StatusResponse)
register(Range.all(), State.STATUS, 1, false, ::StatusPong)
}
inline fun <reified P : Packet> register(
protocol: Range<Int>,
state: State,
id: Int,
serverBound: Boolean,
constructor: Supplier<P>
) {
entries.add(RegistryEntry(protocol, state, id, serverBound, constructor, P::class.java))
}
data class RegistryEntry(
@ -65,7 +54,7 @@ object PacketRegistry {
val state: State,
val id: Int,
val serverBound: Boolean,
val constructor: Supplier<Packet>,
val constructor: Supplier<out Packet>,
val packetClass: Class<out Packet>
)
@ -303,4 +292,45 @@ class PluginRequest : Packet {
Type.STRING.write(byteBuf, channel)
byteBuf.writeBytes(data)
}
}
class StatusResponse : Packet {
lateinit var json: String
override fun decode(byteBuf: ByteBuf, protocolVersion: Int) {
json = Type.STRING.read(byteBuf)
}
override fun encode(byteBuf: ByteBuf, protocolVersion: Int) {
Type.STRING.write(byteBuf, json)
}
}
class StatusRequest: Packet {
override fun decode(byteBuf: ByteBuf, protocolVersion: Int) {
}
override fun encode(byteBuf: ByteBuf, protocolVersion: Int) {
}
}
class StatusPing: Packet {
var number by Delegates.notNull<Long>()
override fun decode(byteBuf: ByteBuf, protocolVersion: Int) {
number = byteBuf.readLong()
}
override fun encode(byteBuf: ByteBuf, protocolVersion: Int) {
byteBuf.writeLong(number)
}
}
class StatusPong: Packet {
var number by Delegates.notNull<Long>()
override fun decode(byteBuf: ByteBuf, protocolVersion: Int) {
number = byteBuf.readLong()
}
override fun encode(byteBuf: ByteBuf, protocolVersion: Int) {
byteBuf.writeLong(number)
}
}

View File

@ -179,9 +179,9 @@ function refreshMojangAccount(it) {
headers: {"content-type": "application/json"},
}).then(data => {
if (!isSuccess(data.status)) throw "not success";
console.log("refreshed " + data.selectedProfile.id);
return data.json();
}).then((json) => {
console.log("refreshed " + json.selectedProfile.id);
removeMcAccount(data.selectedProfile.id);
return storeMcAccount(json.accessToken, json.clientToken, json.selectedProfile.name, json.selectedProfile.id);
});
@ -252,6 +252,10 @@ function addAction(text, onClick) {
actions.appendChild(p);
}
function findAccountByMcName(name) {
return getMcAccounts().reverse().find(it => it.name.toLowerCase() == name.toLowerCase());
}
function onSocketMsg(event) {
console.log(event.data.toString());
let parsed = JSON.parse(event.data);
@ -275,7 +279,7 @@ function onSocketMsg(event) {
}
} else if (parsed.action == "session_hash_request") {
if (confirm("Allow auth impersonation from VIAaaS instance? info: " + JSON.stringify(parsed))) {
let account = getMcAccounts().reverse().find(it => it.name.toLowerCase() == parsed.user.toLowerCase());
let account = findAccountByMcName(parsed.user);
if (account) {
getMcUserToken(account).then((data) => {
return joinGame(data.accessToken, data.id, parsed.session_hash);