From f4ab4997c889aaa2f9359288f973b122f8346b04 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 2 Sep 2022 20:22:33 +0800 Subject: [PATCH] Bug fix. --- .../Protocol/Handlers/DataTypes.cs | 31 +++++++---- .../Protocol/Handlers/Protocol18.cs | 54 +++++++++++-------- MinecraftClient/Resources/lang/en.ini | 1 + 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index 6907484e..c7f84f57 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -1115,30 +1115,39 @@ namespace MinecraftClient.Protocol.Handlers /// Write LastSeenMessageList /// /// Message.LastSeenMessageList + /// Whether the server is in online mode /// Message.LastSeenMessageList Packet Data - public byte[] GetLastSeenMessageList(Message.LastSeenMessageList msgList) + public byte[] GetLastSeenMessageList(Message.LastSeenMessageList msgList, bool isOnlineMode) { - List fields = new List(); - fields.AddRange(GetVarInt(msgList.entries.Length)); - foreach (Message.LastSeenMessageList.Entry entry in msgList.entries) + if (!isOnlineMode) { - fields.AddRange(entry.profileId.ToBigEndianBytes()); - fields.AddRange(GetVarInt(entry.lastSignature.Length)); - fields.AddRange(entry.lastSignature); + return GetVarInt(0); + } + else + { + List fields = new List(); + fields.AddRange(GetVarInt(msgList.entries.Length)); + foreach (Message.LastSeenMessageList.Entry entry in msgList.entries) + { + fields.AddRange(entry.profileId.ToBigEndianBytes()); + fields.AddRange(GetVarInt(entry.lastSignature.Length)); + fields.AddRange(entry.lastSignature); + } + return fields.ToArray(); } - return fields.ToArray(); } /// /// Write LastSeenMessageList.Acknowledgment /// /// Acknowledgment + /// Whether the server is in online mode /// Acknowledgment Packet Data - public byte[] GetAcknowledgment(Message.LastSeenMessageList.Acknowledgment ack) + public byte[] GetAcknowledgment(Message.LastSeenMessageList.Acknowledgment ack, bool isOnlineMode) { List fields = new List(); - fields.AddRange(GetLastSeenMessageList(ack.lastSeen)); - if (ack.lastReceived == null) + fields.AddRange(GetLastSeenMessageList(ack.lastSeen, isOnlineMode)); + if (!isOnlineMode || ack.lastReceived == null) fields.AddRange(GetBool(false)); else { diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 6870a6e2..0a50a925 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -66,6 +66,7 @@ namespace MinecraftClient.Protocol.Handlers private bool login_phase = true; private int protocolVersion; private int currentDimension; + private bool isOnlineMode = false; private int pendingAcknowledgments = 0; private LastSeenMessagesCollector lastSeenMessagesCollector = new(5); @@ -470,7 +471,9 @@ namespace MinecraftClient.Protocol.Handlers byte[] messageSignature = dataTypes.ReadNextByteArray(packetData); bool verifyResult; - if (senderUUID == handler.GetUserUuid()) + if (!isOnlineMode) + verifyResult = false; + else if (senderUUID == handler.GetUserUuid()) verifyResult = true; else { @@ -512,8 +515,18 @@ namespace MinecraftClient.Protocol.Handlers string chatName = dataTypes.ReadNextString(packetData); string? targetName = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextString(packetData) : null; + Dictionary chatInfo = Json.ParseJson(chatName).Properties; + string senderDisplayName = (chatInfo.ContainsKey("insertion") ? chatInfo["insertion"] : chatInfo["text"]).StringValue; + string? senderTeamName = null; + ChatParser.MessageType messageTypeEnum = ChatParser.ChatId2Type![chatTypeId]; + if (targetName != null && + (messageTypeEnum == ChatParser.MessageType.TEAM_MSG_COMMAND_INCOMING || messageTypeEnum == ChatParser.MessageType.TEAM_MSG_COMMAND_OUTGOING)) + senderTeamName = Json.ParseJson(targetName).Properties["with"].DataArray[0].Properties["text"].StringValue; + bool verifyResult; - if (senderUUID == handler.GetUserUuid()) + if (!isOnlineMode) + verifyResult = false; + else if (senderUUID == handler.GetUserUuid()) verifyResult = true; else { @@ -525,20 +538,12 @@ namespace MinecraftClient.Protocol.Handlers bool lastVerifyResult = player.IsMessageChainLegal(); verifyResult = player.VerifyMessage(signedChat, timestamp, salt, ref headerSignature, ref precedingSignature, lastSeenMessages); if (lastVerifyResult && !verifyResult) - log.Warn("Player " + player.DisplayName + "'s message chain is broken!"); + log.Warn(Translations.Get("chat.message_chain_broken", senderDisplayName)); } } - Dictionary chatInfo = Json.ParseJson(chatName).Properties; - string senderDisplayName = (chatInfo.ContainsKey("insertion") ? chatInfo["insertion"] : chatInfo["text"]).StringValue; - string? senderTeamName = null; - ChatParser.MessageType messageTypeEnum = ChatParser.ChatId2Type![chatTypeId]; - if (targetName != null && - (messageTypeEnum == ChatParser.MessageType.TEAM_MSG_COMMAND_INCOMING || messageTypeEnum == ChatParser.MessageType.TEAM_MSG_COMMAND_OUTGOING)) - senderTeamName = Json.ParseJson(targetName).Properties["with"].DataArray[0].Properties["text"].StringValue; - ChatMessage chat = new(signedChat, false, chatTypeId, senderUUID, unsignedChatContent, senderDisplayName, senderTeamName, timestamp, headerSignature, verifyResult); - if (!chat.lacksSender()) + if (isOnlineMode && !chat.lacksSender()) this.acknowledge(chat); handler.OnTextReceived(chat); } @@ -552,7 +557,9 @@ namespace MinecraftClient.Protocol.Handlers byte[] bodyDigest = dataTypes.ReadNextByteArray(packetData); bool verifyResult; - if (senderUUID == handler.GetUserUuid()) + if (!isOnlineMode) + verifyResult = false; + else if (senderUUID == handler.GetUserUuid()) verifyResult = true; else { @@ -1692,6 +1699,7 @@ namespace MinecraftClient.Protocol.Handlers } else if (packetID == 0x01) //Encryption request { + this.isOnlineMode = true; string serverID = dataTypes.ReadNextString(packetData); byte[] serverPublicKey = dataTypes.ReadNextByteArray(packetData); byte[] token = dataTypes.ReadNextByteArray(packetData); @@ -1986,7 +1994,7 @@ namespace MinecraftClient.Protocol.Handlers { try { - byte[] fields = dataTypes.GetAcknowledgment(acknowledgment); + byte[] fields = dataTypes.GetAcknowledgment(acknowledgment, isOnlineMode); SendPacket(PacketTypesOut.MessageAcknowledgment, fields); @@ -2027,11 +2035,11 @@ namespace MinecraftClient.Protocol.Handlers /// /// Command /// List< Argument Name, Argument Value > - private static List> CollectCommandArguments(string command) + private List> CollectCommandArguments(string command) { List> needSigned = new(); - if (!Settings.SignMessageInCommand) + if (!isOnlineMode || !Settings.SignMessageInCommand) return needSigned; string[] argStage1 = command.Split(' ', 2, StringSplitOptions.None); @@ -2086,7 +2094,8 @@ namespace MinecraftClient.Protocol.Handlers try { - LastSeenMessageList.Acknowledgment? acknowledgment = (protocolVersion >= MC_1_19_2_Version) ? this.consumeAcknowledgment() : null; + LastSeenMessageList.Acknowledgment? acknowledgment = + (protocolVersion >= MC_1_19_2_Version) ? this.consumeAcknowledgment() : null; List fields = new(); @@ -2098,7 +2107,7 @@ namespace MinecraftClient.Protocol.Handlers fields.AddRange(dataTypes.GetLong(timeNow.ToUnixTimeMilliseconds())); List> needSigned = CollectCommandArguments(command); // List< Argument Name, Argument Value > - if (needSigned.Count == 0 || playerKeyPair == null || !Settings.SignMessageInCommand) + if (!isOnlineMode || needSigned.Count == 0 || playerKeyPair == null || !Settings.SignMessageInCommand) { fields.AddRange(dataTypes.GetLong(0)); // Salt: Long fields.AddRange(dataTypes.GetVarInt(0)); // Signature Length: VarInt @@ -2126,7 +2135,7 @@ namespace MinecraftClient.Protocol.Handlers if (protocolVersion >= MC_1_19_2_Version) { // Message Acknowledgment - fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!)); + fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!, isOnlineMode)); } SendPacket(PacketTypesOut.ChatCommand, fields); @@ -2154,7 +2163,8 @@ namespace MinecraftClient.Protocol.Handlers try { - LastSeenMessageList.Acknowledgment? acknowledgment = (protocolVersion >= MC_1_19_2_Version) ? this.consumeAcknowledgment() : null; + LastSeenMessageList.Acknowledgment? acknowledgment = + (protocolVersion >= MC_1_19_2_Version) ? this.consumeAcknowledgment() : null; List fields = new(); @@ -2167,7 +2177,7 @@ namespace MinecraftClient.Protocol.Handlers DateTimeOffset timeNow = DateTimeOffset.UtcNow; fields.AddRange(dataTypes.GetLong(timeNow.ToUnixTimeMilliseconds())); - if (playerKeyPair == null || !Settings.SignChat) + if (!isOnlineMode || playerKeyPair == null || !Settings.SignChat) { fields.AddRange(dataTypes.GetLong(0)); // Salt: Long fields.AddRange(dataTypes.GetVarInt(0)); // Signature Length: VarInt @@ -2193,7 +2203,7 @@ namespace MinecraftClient.Protocol.Handlers if (protocolVersion >= MC_1_19_2_Version) { // Message Acknowledgment - fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!)); + fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!, isOnlineMode)); } } SendPacket(PacketTypesOut.ChatMessage, fields); diff --git a/MinecraftClient/Resources/lang/en.ini b/MinecraftClient/Resources/lang/en.ini index c006d112..49bbfd8f 100644 --- a/MinecraftClient/Resources/lang/en.ini +++ b/MinecraftClient/Resources/lang/en.ini @@ -205,6 +205,7 @@ chat.fail=§8Failed to download the file. chat.from_dir=§8Defaulting to en_GB.lang from your Minecraft directory. chat.loaded=§8Translations file loaded. chat.not_found=§8Translations file not found: '{0}'\nSome messages won't be properly printed without this file. +chat.message_chain_broken=Player {0}'s message chain is broken! [general] # General message/information (i.e. Done)