mirror of
https://github.com/ViaVersion/VIAaaS.git
synced 2025-02-19 02:11:50 +01:00
fixed mojang account refresh, code cleanup, parse status packets
This commit is contained in:
parent
e966a45540
commit
764f849d79
@ -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>) {
|
override fun encode(ctx: ChannelHandlerContext, msg: Packet, out: MutableList<Any>) {
|
||||||
if (!ctx.channel().isActive) return
|
if (!ctx.channel().isActive) return
|
||||||
val buf = ByteBufAllocator.DEFAULT.buffer()
|
val buf = ByteBufAllocator.DEFAULT.buffer()
|
||||||
@ -67,9 +67,13 @@ class CloudMinecraftCodec: MessageToMessageCodec<ByteBuf, Packet>() {
|
|||||||
override fun decode(ctx: ChannelHandlerContext, msg: ByteBuf, out: MutableList<Any>) {
|
override fun decode(ctx: ChannelHandlerContext, msg: ByteBuf, out: MutableList<Any>) {
|
||||||
if (!ctx.channel().isActive || !msg.isReadable) return
|
if (!ctx.channel().isActive || !msg.isReadable) return
|
||||||
val handler = ctx.pipeline().get(CloudMinecraftHandler::class.java)
|
val handler = ctx.pipeline().get(CloudMinecraftHandler::class.java)
|
||||||
out.add(PacketRegistry.decode(msg,
|
out.add(
|
||||||
|
PacketRegistry.decode(
|
||||||
|
msg,
|
||||||
handler.data.frontVer ?: 0,
|
handler.data.frontVer ?: 0,
|
||||||
handler.data.state.state, handler.frontEnd))
|
handler.data.state.state, handler.frontEnd
|
||||||
|
)
|
||||||
|
)
|
||||||
if (msg.isReadable) throw IllegalStateException("Remaining bytes!!!")
|
if (msg.isReadable) throw IllegalStateException("Remaining bytes!!!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,31 +201,17 @@ class FrameCodec : ByteToMessageCodec<ByteBuf>() {
|
|||||||
class CloudViaCodec(val info: UserConnection) : MessageToMessageCodec<ByteBuf, ByteBuf>() {
|
class CloudViaCodec(val info: UserConnection) : MessageToMessageCodec<ByteBuf, ByteBuf>() {
|
||||||
override fun decode(ctx: ChannelHandlerContext, bytebuf: ByteBuf, out: MutableList<Any>) {
|
override fun decode(ctx: ChannelHandlerContext, bytebuf: ByteBuf, out: MutableList<Any>) {
|
||||||
if (!info.checkIncomingPacket()) throw CancelDecoderException.generate(null)
|
if (!info.checkIncomingPacket()) throw CancelDecoderException.generate(null)
|
||||||
if (!info.shouldTransformPacket()) {
|
if (info.shouldTransformPacket()) {
|
||||||
|
info.transformIncoming(bytebuf, CancelDecoderException::generate)
|
||||||
|
}
|
||||||
out.add(bytebuf.retain())
|
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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun encode(ctx: ChannelHandlerContext, bytebuf: ByteBuf, out: MutableList<Any>) {
|
override fun encode(ctx: ChannelHandlerContext, bytebuf: ByteBuf, out: MutableList<Any>) {
|
||||||
if (!info.checkOutgoingPacket()) throw CancelEncoderException.generate(null)
|
if (!info.checkOutgoingPacket()) throw CancelEncoderException.generate(null)
|
||||||
if (!info.shouldTransformPacket()) {
|
if (info.shouldTransformPacket()) {
|
||||||
|
info.transformOutgoing(bytebuf, CancelEncoderException::generate)
|
||||||
|
}
|
||||||
out.add(bytebuf.retain())
|
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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,12 @@ import com.google.gson.Gson
|
|||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import io.ktor.client.request.*
|
import io.ktor.client.request.*
|
||||||
import io.netty.bootstrap.Bootstrap
|
import io.netty.bootstrap.Bootstrap
|
||||||
import io.netty.buffer.ByteBufAllocator
|
|
||||||
import io.netty.channel.*
|
import io.netty.channel.*
|
||||||
import io.netty.channel.socket.SocketChannel
|
import io.netty.channel.socket.SocketChannel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import us.myles.ViaVersion.api.type.Type
|
|
||||||
import us.myles.ViaVersion.exception.CancelCodecException
|
import us.myles.ViaVersion.exception.CancelCodecException
|
||||||
import us.myles.ViaVersion.packets.State
|
import us.myles.ViaVersion.packets.State
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
@ -270,7 +268,7 @@ class LoginState : MinecraftConnectionState {
|
|||||||
cryptoRequest.publicKey = mcCryptoKey.public
|
cryptoRequest.publicKey = mcCryptoKey.public
|
||||||
cryptoRequest.token = token
|
cryptoRequest.token = token
|
||||||
|
|
||||||
frontHandler.data.frontChannel.writeAndFlush(cryptoRequest)
|
sendPacket(frontHandler.data.frontChannel, cryptoRequest, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleCryptoRequest(handler: CloudMinecraftHandler, cryptoRequest: CryptoRequest) {
|
fun handleCryptoRequest(handler: CloudMinecraftHandler, cryptoRequest: CryptoRequest) {
|
||||||
@ -386,16 +384,9 @@ class LoginState : MinecraftConnectionState {
|
|||||||
override fun disconnect(handler: CloudMinecraftHandler, msg: String) {
|
override fun disconnect(handler: CloudMinecraftHandler, msg: String) {
|
||||||
super.disconnect(handler, msg)
|
super.disconnect(handler, msg)
|
||||||
|
|
||||||
val packet = ByteBufAllocator.DEFAULT.buffer()
|
val packet = LoginDisconnect()
|
||||||
try {
|
packet.msg = Gson().toJson("[VIAaaS] §c$msg")
|
||||||
packet.writeByte(0) // id 0 disconnect
|
sendFlushPacketClose(handler.data.frontChannel, packet)
|
||||||
Type.STRING.write(packet, Gson().toJson("[VIAaaS] §c$msg"))
|
|
||||||
handler.data.frontChannel
|
|
||||||
.writeAndFlush(packet.retain())
|
|
||||||
.addListener { handler.data.frontChannel.close() }
|
|
||||||
} finally {
|
|
||||||
packet.release()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,25 +395,17 @@ object StatusState : MinecraftConnectionState {
|
|||||||
get() = State.STATUS
|
get() = State.STATUS
|
||||||
|
|
||||||
override fun handlePacket(handler: CloudMinecraftHandler, ctx: ChannelHandlerContext, packet: Packet) {
|
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)
|
forward(handler, packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun disconnect(handler: CloudMinecraftHandler, msg: String) {
|
override fun disconnect(handler: CloudMinecraftHandler, msg: String) {
|
||||||
super.disconnect(handler, msg)
|
super.disconnect(handler, msg)
|
||||||
|
|
||||||
val packet = ByteBufAllocator.DEFAULT.buffer()
|
val packet = StatusResponse()
|
||||||
try {
|
packet.json = """{"version": {"name": "VIAaaS", "protocol": -1}, "players": {"max": 0, "online": 0,
|
||||||
packet.writeByte(0) // id 0 disconnect
|
| "sample": []}, "description": {"text": ${Gson().toJson("§c$msg")}}}""".trimMargin()
|
||||||
Type.STRING.write(
|
sendFlushPacketClose(handler.data.frontChannel, packet)
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,18 +462,20 @@ fun generateServerHash(serverId: String, sharedSecret: ByteArray?, key: PublicKe
|
|||||||
return twosComplementHexdigest(digest.digest())
|
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) {
|
private fun forward(handler: CloudMinecraftHandler, packet: Packet, flush: Boolean = false) {
|
||||||
val msg = ByteBufAllocator.DEFAULT.buffer()
|
sendPacket(handler.other!!, packet, flush)
|
||||||
try {
|
}
|
||||||
val ch = handler.other!!
|
|
||||||
|
private fun sendPacket(ch: Channel, packet: Packet, flush: Boolean = false) {
|
||||||
if (flush) {
|
if (flush) {
|
||||||
ch.writeAndFlush(packet, ch.voidPromise())
|
ch.writeAndFlush(packet, ch.voidPromise())
|
||||||
} else {
|
} else {
|
||||||
ch.write(packet, ch.voidPromise())
|
ch.write(packet, ch.voidPromise())
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
msg.release()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveSrv(address: String, port: Int): Pair<String, Int> {
|
private fun resolveSrv(address: String, port: Int): Pair<String, Int> {
|
||||||
|
@ -24,40 +24,29 @@ object PacketRegistry {
|
|||||||
val entries = mutableListOf<RegistryEntry>()
|
val entries = mutableListOf<RegistryEntry>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
entries.add(
|
register(Range.all(), State.HANDSHAKE, 0, true, ::HandshakePacket)
|
||||||
RegistryEntry(Range.all(), State.HANDSHAKE, 0, true, ::HandshakePacket, HandshakePacket::class.java)
|
register(Range.all(), State.LOGIN, 0, true, ::LoginStart)
|
||||||
)
|
register(Range.all(), State.LOGIN, 1, true, ::CryptoResponse)
|
||||||
entries.add(
|
register(Range.atLeast(ProtocolVersion.v1_13.version), State.LOGIN, 2, true, ::PluginResponse)
|
||||||
RegistryEntry(Range.all(), State.LOGIN, 0, true, ::LoginStart, LoginStart::class.java)
|
register(Range.all(), State.LOGIN, 0, false, ::LoginDisconnect)
|
||||||
)
|
register(Range.all(), State.LOGIN, 1, false, ::CryptoRequest)
|
||||||
entries.add(
|
register(Range.all(), State.LOGIN, 2, false, ::LoginSuccess)
|
||||||
RegistryEntry(Range.all(), State.LOGIN, 1, true, ::CryptoResponse, CryptoResponse::class.java)
|
register(Range.all(), State.LOGIN, 3, false, ::SetCompression)
|
||||||
)
|
register(Range.all(), State.LOGIN, 4, false, ::PluginRequest)
|
||||||
entries.add(
|
register(Range.all(), State.STATUS, 0, true, ::StatusRequest)
|
||||||
RegistryEntry(
|
register(Range.all(), State.STATUS, 1, true, ::StatusPing)
|
||||||
Range.atLeast(ProtocolVersion.v1_13.version),
|
register(Range.all(), State.STATUS, 0, false, ::StatusResponse)
|
||||||
State.LOGIN,
|
register(Range.all(), State.STATUS, 1, false, ::StatusPong)
|
||||||
2,
|
}
|
||||||
true,
|
|
||||||
::PluginResponse,
|
inline fun <reified P : Packet> register(
|
||||||
PluginResponse::class.java
|
protocol: Range<Int>,
|
||||||
)
|
state: State,
|
||||||
)
|
id: Int,
|
||||||
entries.add(
|
serverBound: Boolean,
|
||||||
RegistryEntry(Range.all(), State.LOGIN, 0, false, ::LoginDisconnect, LoginDisconnect::class.java)
|
constructor: Supplier<P>
|
||||||
)
|
) {
|
||||||
entries.add(
|
entries.add(RegistryEntry(protocol, state, id, serverBound, constructor, P::class.java))
|
||||||
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)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class RegistryEntry(
|
data class RegistryEntry(
|
||||||
@ -65,7 +54,7 @@ object PacketRegistry {
|
|||||||
val state: State,
|
val state: State,
|
||||||
val id: Int,
|
val id: Int,
|
||||||
val serverBound: Boolean,
|
val serverBound: Boolean,
|
||||||
val constructor: Supplier<Packet>,
|
val constructor: Supplier<out Packet>,
|
||||||
val packetClass: Class<out Packet>
|
val packetClass: Class<out Packet>
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -304,3 +293,44 @@ class PluginRequest : Packet {
|
|||||||
byteBuf.writeBytes(data)
|
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)
|
||||||
|
}
|
||||||
|
}
|
@ -179,9 +179,9 @@ function refreshMojangAccount(it) {
|
|||||||
headers: {"content-type": "application/json"},
|
headers: {"content-type": "application/json"},
|
||||||
}).then(data => {
|
}).then(data => {
|
||||||
if (!isSuccess(data.status)) throw "not success";
|
if (!isSuccess(data.status)) throw "not success";
|
||||||
console.log("refreshed " + data.selectedProfile.id);
|
|
||||||
return data.json();
|
return data.json();
|
||||||
}).then((json) => {
|
}).then((json) => {
|
||||||
|
console.log("refreshed " + json.selectedProfile.id);
|
||||||
removeMcAccount(data.selectedProfile.id);
|
removeMcAccount(data.selectedProfile.id);
|
||||||
return storeMcAccount(json.accessToken, json.clientToken, json.selectedProfile.name, json.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);
|
actions.appendChild(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findAccountByMcName(name) {
|
||||||
|
return getMcAccounts().reverse().find(it => it.name.toLowerCase() == name.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
function onSocketMsg(event) {
|
function onSocketMsg(event) {
|
||||||
console.log(event.data.toString());
|
console.log(event.data.toString());
|
||||||
let parsed = JSON.parse(event.data);
|
let parsed = JSON.parse(event.data);
|
||||||
@ -275,7 +279,7 @@ function onSocketMsg(event) {
|
|||||||
}
|
}
|
||||||
} else if (parsed.action == "session_hash_request") {
|
} else if (parsed.action == "session_hash_request") {
|
||||||
if (confirm("Allow auth impersonation from VIAaaS instance? info: " + JSON.stringify(parsed))) {
|
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) {
|
if (account) {
|
||||||
getMcUserToken(account).then((data) => {
|
getMcUserToken(account).then((data) => {
|
||||||
return joinGame(data.accessToken, data.id, parsed.session_hash);
|
return joinGame(data.accessToken, data.id, parsed.session_hash);
|
||||||
|
Loading…
Reference in New Issue
Block a user