diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 937e6c22..6030e81e 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -79,6 +79,8 @@ namespace MinecraftClient.Protocol.Handlers private int pendingAcknowledgments = 0; private readonly LastSeenMessagesCollector lastSeenMessagesCollector = new(5); private LastSeenMessageList.Entry? lastReceivedMessage = null; + private Guid playerSessionUuid = Guid.NewGuid(); + private int messageCount = 0; readonly Protocol18Forge pForge; readonly Protocol18Terrain pTerrain; readonly IMinecraftComHandler handler; @@ -2437,14 +2439,27 @@ namespace MinecraftClient.Protocol.Handlers } } - // Signed Preview: Boolean - fields.AddRange(dataTypes.GetBool(false)); - - if (protocolVersion >= MC_1_19_2_Version) + if (protocolVersion < MC_1_19_3_Version) { - // Message Acknowledgment + // Signed Preview: Boolean (1.19.2) + fields.AddRange(dataTypes.GetBool(false)); + } + else + { + fields.AddRange(dataTypes.GetVarInt(messageCount)); // Message count (1.19.3) + } + + if (protocolVersion == MC_1_19_2_Version) + { + // Message Acknowledgment (1.19.2) fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!, isOnlineMode && Config.Signature.LoginWithSecureProfile)); } + else if (protocolVersion >= MC_1_19_3_Version) + { + // 1.19.3 + // Acknowledged: BitSet (no idea what is this) + fields.AddRange(new byte[3] { 0, 0, 0 }); + } SendPacket(PacketTypesOut.ChatCommand, fields); return true; @@ -2502,12 +2517,21 @@ namespace MinecraftClient.Protocol.Handlers // Signature Length & Signature: (VarInt) and Byte Array Guid uuid = handler.GetUserUuid(); byte[] sign; - if (protocolVersion < MC_1_19_2_Version) // 1.19.1 or lower + if (protocolVersion < MC_1_19_2_Version) + { + // 1.19.1 or lower sign = playerKeyPair.PrivateKey.SignMessage(message, uuid, timeNow, ref salt); - else if (protocolVersion < MC_1_19_3_Version) // 1.19.2 + } + else if (protocolVersion < MC_1_19_3_Version) + { + // 1.19.2 sign = playerKeyPair.PrivateKey.SignMessage(message, uuid, timeNow, ref salt, acknowledgment!.lastSeen); - else // 1.19.3 - sign = playerKeyPair.PrivateKey.SignMessage(message, uuid, timeNow, ref salt); // TODO? + } + else + { + // 1.19.3 + sign = playerKeyPair.PrivateKey.SignMessage(message, timeNow, ref salt, messageCount, uuid, playerSessionUuid); + } if (protocolVersion >= MC_1_19_3_Version) fields.AddRange(dataTypes.GetBool(true)); @@ -2516,11 +2540,14 @@ namespace MinecraftClient.Protocol.Handlers fields.AddRange(sign); } - // Signed Preview: Boolean + if (protocolVersion >= MC_1_19_3_Version) - fields.AddRange(dataTypes.GetVarInt(1)); // message count + fields.AddRange(dataTypes.GetVarInt(messageCount)); // Message count (1.19.3) else - fields.AddRange(dataTypes.GetBool(false)); + fields.AddRange(dataTypes.GetBool(false)); // Signed Preview: Boolean (1.19.2) + + //if (protocolVersion >= MC_1_19_3_Version) + // messageCount++; if (protocolVersion >= MC_1_19_2_Version) { @@ -3196,13 +3223,11 @@ namespace MinecraftClient.Protocol.Handlers { List packet = new(); - var uuid = Guid.NewGuid(); - byte[] timestampByte = BitConverter.GetBytes(playerKeyPair.GetExpirationMilliseconds()); Array.Reverse(timestampByte); var signature = KeyUtils.ComputeHash(timestampByte.Concat(playerKeyPair.PublicKey.Key).ToArray()); - packet.AddRange(dataTypes.GetUUID(uuid)); + packet.AddRange(dataTypes.GetUUID(playerSessionUuid)); packet.AddRange(dataTypes.GetLong(playerKeyPair.GetExpirationMilliseconds())); packet.AddRange(dataTypes.GetVarInt(playerKeyPair.PublicKey.Key.Length)); packet.AddRange(playerKeyPair.PublicKey.Key); @@ -3222,6 +3247,27 @@ namespace MinecraftClient.Protocol.Handlers else { return false; } } + public bool SendMessageAcknowledgment(int messageCount) + { + if (protocolVersion >= MC_1_19_3_Version) + { + try + { + List packet = new(); + + packet.AddRange(dataTypes.GetVarInt(messageCount)); + + SendPacket(PacketTypesOut.MessageAcknowledgment, packet); + + return true; + } + catch (SocketException) { return false; } + catch (System.IO.IOException) { return false; } + catch (ObjectDisposedException) { return false; } + } + else { return false; } + } + private byte[] GenerateSalt() { byte[] salt = new byte[8]; diff --git a/MinecraftClient/Protocol/ProfileKey/KeyUtils.cs b/MinecraftClient/Protocol/ProfileKey/KeyUtils.cs index 12889fac..b7f31c77 100644 --- a/MinecraftClient/Protocol/ProfileKey/KeyUtils.cs +++ b/MinecraftClient/Protocol/ProfileKey/KeyUtils.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Security.Cryptography; using System.Text; +using ImageMagick; using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol.Keys @@ -124,11 +125,36 @@ namespace MinecraftClient.Protocol.Keys return data.ToArray(); } - public static byte[] GetSignatureData(string message, DateTimeOffset timestamp, ref byte[] salt, Guid sender, Guid sessionUuid) + public static byte[] GetSignatureData(string message, DateTimeOffset timestamp, ref byte[] salt, int messageCount, Guid sender, Guid sessionUuid) { List data = new(); // TODO! + byte[] unknownInt1 = BitConverter.GetBytes(1); + Array.Reverse(unknownInt1); + data.AddRange(unknownInt1); + + data.AddRange(sender.ToBigEndianBytes()); + data.AddRange(sessionUuid.ToBigEndianBytes()); + + byte[] msgCountByte = BitConverter.GetBytes(messageCount); + Array.Reverse(msgCountByte); + data.AddRange(msgCountByte); + data.AddRange(salt); + + byte[] timestampByte = BitConverter.GetBytes(timestamp.ToUnixTimeSeconds()); + Array.Reverse(timestampByte); + data.AddRange(timestampByte); + + byte[] msgByte = Encoding.UTF8.GetBytes(message); + byte[] msgLengthByte = BitConverter.GetBytes(msgByte.Length); + Array.Reverse(msgLengthByte); + data.AddRange(msgLengthByte); + data.AddRange(msgByte); + + byte[] unknownInt2 = BitConverter.GetBytes(0); + Array.Reverse(unknownInt2); + data.AddRange(unknownInt2); return data.ToArray(); } diff --git a/MinecraftClient/Protocol/ProfileKey/PrivateKey.cs b/MinecraftClient/Protocol/ProfileKey/PrivateKey.cs index b3dd4093..65c569c6 100644 --- a/MinecraftClient/Protocol/ProfileKey/PrivateKey.cs +++ b/MinecraftClient/Protocol/ProfileKey/PrivateKey.cs @@ -64,5 +64,10 @@ namespace MinecraftClient.Protocol.Keys return msgSign; } + public byte[] SignMessage(string message, DateTimeOffset timestamp, ref byte[] salt, int messageCount, Guid sender, Guid sessionUuid) + { + byte[] data = KeyUtils.GetSignatureData(message, timestamp, ref salt, messageCount, sender, sessionUuid); + return SignData(data); + } } }