Fix login start packet decoding for 1.18.2 up to 1.20.2 (#421)
Signed-off-by: Fred Heinecke <fred.heinecke@yahoo.com>
This commit is contained in:
+67
-6
@@ -21,10 +21,11 @@ func DecodeHandshake(data interface{}) (*Handshake, error) {
|
||||
buffer := bytes.NewBuffer(dataBytes)
|
||||
var err error
|
||||
|
||||
handshake.ProtocolVersion, err = ReadVarInt(buffer)
|
||||
protocolVersion, err := ReadVarInt(buffer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
handshake.ProtocolVersion = ProtocolVersion(protocolVersion)
|
||||
|
||||
handshake.ServerAddress, err = ReadString(buffer)
|
||||
if err != nil {
|
||||
@@ -48,13 +49,13 @@ func DecodeHandshake(data interface{}) (*Handshake, error) {
|
||||
}
|
||||
|
||||
// DecodeLoginStart takes the Packet.Data bytes and decodes a LoginStart message from it
|
||||
func DecodeLoginStart(data interface{}) (*LoginStart, error) {
|
||||
func DecodeLoginStart(protocolVersion ProtocolVersion, data interface{}) (*LoginStart, error) {
|
||||
dataBytes, ok := data.([]byte)
|
||||
if !ok {
|
||||
return nil, errors.New(invalidPacketDataBytesMsg)
|
||||
}
|
||||
|
||||
loginStart := &LoginStart{}
|
||||
loginStart := NewLoginStart()
|
||||
buffer := bytes.NewBuffer(dataBytes)
|
||||
var err error
|
||||
|
||||
@@ -63,9 +64,69 @@ func DecodeLoginStart(data interface{}) (*LoginStart, error) {
|
||||
return loginStart, errors.Wrap(err, "failed to read username")
|
||||
}
|
||||
|
||||
loginStart.PlayerUuid, err = ReadUuid(buffer)
|
||||
if err != nil {
|
||||
return loginStart, errors.Wrap(err, "failed to read player uuid")
|
||||
// These versions can send player keypair data. Ignore it.
|
||||
// References:
|
||||
// * https://github.com/MCCTeam/Minecraft-Console-Client/blob/f785f509f228bf787c237ac139e6f666a960819a/MinecraftClient/Protocol/Handlers/Protocol18.cs#L2808-L2828
|
||||
// * https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol?oldid=2772902#Login_Start
|
||||
if protocolVersion >= ProtocolVersion1_19 && protocolVersion <= ProtocolVersion1_19_2 {
|
||||
hasSignatureData, err := ReadBoolean(buffer)
|
||||
if err != nil {
|
||||
return loginStart, errors.Wrap(err, "failed to read has signature data flag")
|
||||
}
|
||||
|
||||
if hasSignatureData {
|
||||
// Read and discard the data
|
||||
_, err = ReadLong(buffer) // Expiration time
|
||||
if err != nil {
|
||||
return loginStart, errors.Wrap(err, "failed to read expiration time")
|
||||
}
|
||||
|
||||
pubKeyLength, err := ReadVarInt(buffer) // Length of the public key
|
||||
if err != nil {
|
||||
return loginStart, errors.Wrap(err, "failed to read public key length")
|
||||
}
|
||||
|
||||
_, err = ReadByteArray(buffer, pubKeyLength) // Public key data
|
||||
if err != nil {
|
||||
return loginStart, errors.Wrap(err, "failed to read public key")
|
||||
}
|
||||
|
||||
signatureLength, err := ReadVarInt(buffer) // Length of the signature
|
||||
if err != nil {
|
||||
return loginStart, errors.Wrap(err, "failed to read signature length")
|
||||
}
|
||||
|
||||
_, err = ReadByteArray(buffer, signatureLength) // Signature data
|
||||
if err != nil {
|
||||
return loginStart, errors.Wrap(err, "failed to read signature")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// References:
|
||||
// * https://github.com/MCCTeam/Minecraft-Console-Client/blob/f785f509f228bf787c237ac139e6f666a960819a/MinecraftClient/Protocol/Handlers/Protocol18.cs#L2831-L2853
|
||||
// * https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol?oldid=2772944#Login_Start
|
||||
switch {
|
||||
case protocolVersion >= ProtocolVersion1_19_2 && protocolVersion < ProtocolVersion1_20_2:
|
||||
// Check to see if a UUID was provided at all
|
||||
hasUUID, err := ReadBoolean(buffer)
|
||||
if err != nil {
|
||||
return loginStart, errors.Wrap(err, "failed to read has uuid flag")
|
||||
}
|
||||
|
||||
if !hasUUID {
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
case protocolVersion >= ProtocolVersion1_20_2:
|
||||
// For 1.20.2 and later, the UUID is always present
|
||||
playerUuid, err := ReadUuid(buffer)
|
||||
if err != nil {
|
||||
return loginStart, errors.Wrap(err, "failed to read player uuid")
|
||||
}
|
||||
loginStart.PlayerUuid = playerUuid
|
||||
default:
|
||||
// For versions before 1.19.2, the UUID is not present
|
||||
}
|
||||
|
||||
return loginStart, nil
|
||||
|
||||
Reference in New Issue
Block a user