This commit is contained in:
BruceChen 2022-09-02 20:22:33 +08:00
parent da02f8004f
commit f4ab4997c8
3 changed files with 53 additions and 33 deletions

View file

@ -1115,30 +1115,39 @@ namespace MinecraftClient.Protocol.Handlers
/// Write LastSeenMessageList /// Write LastSeenMessageList
/// </summary> /// </summary>
/// <param name="msgList">Message.LastSeenMessageList</param> /// <param name="msgList">Message.LastSeenMessageList</param>
/// <param name="isOnlineMode">Whether the server is in online mode</param>
/// <returns>Message.LastSeenMessageList Packet Data</returns> /// <returns>Message.LastSeenMessageList Packet Data</returns>
public byte[] GetLastSeenMessageList(Message.LastSeenMessageList msgList) public byte[] GetLastSeenMessageList(Message.LastSeenMessageList msgList, bool isOnlineMode)
{ {
List<byte> fields = new List<byte>(); if (!isOnlineMode)
fields.AddRange(GetVarInt(msgList.entries.Length));
foreach (Message.LastSeenMessageList.Entry entry in msgList.entries)
{ {
fields.AddRange(entry.profileId.ToBigEndianBytes()); return GetVarInt(0);
fields.AddRange(GetVarInt(entry.lastSignature.Length)); }
fields.AddRange(entry.lastSignature); else
{
List<byte> fields = new List<byte>();
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();
} }
/// <summary> /// <summary>
/// Write LastSeenMessageList.Acknowledgment /// Write LastSeenMessageList.Acknowledgment
/// </summary> /// </summary>
/// <param name="ack">Acknowledgment</param> /// <param name="ack">Acknowledgment</param>
/// <param name="isOnlineMode">Whether the server is in online mode</param>
/// <returns>Acknowledgment Packet Data</returns> /// <returns>Acknowledgment Packet Data</returns>
public byte[] GetAcknowledgment(Message.LastSeenMessageList.Acknowledgment ack) public byte[] GetAcknowledgment(Message.LastSeenMessageList.Acknowledgment ack, bool isOnlineMode)
{ {
List<byte> fields = new List<byte>(); List<byte> fields = new List<byte>();
fields.AddRange(GetLastSeenMessageList(ack.lastSeen)); fields.AddRange(GetLastSeenMessageList(ack.lastSeen, isOnlineMode));
if (ack.lastReceived == null) if (!isOnlineMode || ack.lastReceived == null)
fields.AddRange(GetBool(false)); fields.AddRange(GetBool(false));
else else
{ {

View file

@ -66,6 +66,7 @@ namespace MinecraftClient.Protocol.Handlers
private bool login_phase = true; private bool login_phase = true;
private int protocolVersion; private int protocolVersion;
private int currentDimension; private int currentDimension;
private bool isOnlineMode = false;
private int pendingAcknowledgments = 0; private int pendingAcknowledgments = 0;
private LastSeenMessagesCollector lastSeenMessagesCollector = new(5); private LastSeenMessagesCollector lastSeenMessagesCollector = new(5);
@ -470,7 +471,9 @@ namespace MinecraftClient.Protocol.Handlers
byte[] messageSignature = dataTypes.ReadNextByteArray(packetData); byte[] messageSignature = dataTypes.ReadNextByteArray(packetData);
bool verifyResult; bool verifyResult;
if (senderUUID == handler.GetUserUuid()) if (!isOnlineMode)
verifyResult = false;
else if (senderUUID == handler.GetUserUuid())
verifyResult = true; verifyResult = true;
else else
{ {
@ -512,8 +515,18 @@ namespace MinecraftClient.Protocol.Handlers
string chatName = dataTypes.ReadNextString(packetData); string chatName = dataTypes.ReadNextString(packetData);
string? targetName = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextString(packetData) : null; string? targetName = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextString(packetData) : null;
Dictionary<string, Json.JSONData> 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; bool verifyResult;
if (senderUUID == handler.GetUserUuid()) if (!isOnlineMode)
verifyResult = false;
else if (senderUUID == handler.GetUserUuid())
verifyResult = true; verifyResult = true;
else else
{ {
@ -525,20 +538,12 @@ namespace MinecraftClient.Protocol.Handlers
bool lastVerifyResult = player.IsMessageChainLegal(); bool lastVerifyResult = player.IsMessageChainLegal();
verifyResult = player.VerifyMessage(signedChat, timestamp, salt, ref headerSignature, ref precedingSignature, lastSeenMessages); verifyResult = player.VerifyMessage(signedChat, timestamp, salt, ref headerSignature, ref precedingSignature, lastSeenMessages);
if (lastVerifyResult && !verifyResult) if (lastVerifyResult && !verifyResult)
log.Warn("Player " + player.DisplayName + "'s message chain is broken!"); log.Warn(Translations.Get("chat.message_chain_broken", senderDisplayName));
} }
} }
Dictionary<string, Json.JSONData> 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); ChatMessage chat = new(signedChat, false, chatTypeId, senderUUID, unsignedChatContent, senderDisplayName, senderTeamName, timestamp, headerSignature, verifyResult);
if (!chat.lacksSender()) if (isOnlineMode && !chat.lacksSender())
this.acknowledge(chat); this.acknowledge(chat);
handler.OnTextReceived(chat); handler.OnTextReceived(chat);
} }
@ -552,7 +557,9 @@ namespace MinecraftClient.Protocol.Handlers
byte[] bodyDigest = dataTypes.ReadNextByteArray(packetData); byte[] bodyDigest = dataTypes.ReadNextByteArray(packetData);
bool verifyResult; bool verifyResult;
if (senderUUID == handler.GetUserUuid()) if (!isOnlineMode)
verifyResult = false;
else if (senderUUID == handler.GetUserUuid())
verifyResult = true; verifyResult = true;
else else
{ {
@ -1692,6 +1699,7 @@ namespace MinecraftClient.Protocol.Handlers
} }
else if (packetID == 0x01) //Encryption request else if (packetID == 0x01) //Encryption request
{ {
this.isOnlineMode = true;
string serverID = dataTypes.ReadNextString(packetData); string serverID = dataTypes.ReadNextString(packetData);
byte[] serverPublicKey = dataTypes.ReadNextByteArray(packetData); byte[] serverPublicKey = dataTypes.ReadNextByteArray(packetData);
byte[] token = dataTypes.ReadNextByteArray(packetData); byte[] token = dataTypes.ReadNextByteArray(packetData);
@ -1986,7 +1994,7 @@ namespace MinecraftClient.Protocol.Handlers
{ {
try try
{ {
byte[] fields = dataTypes.GetAcknowledgment(acknowledgment); byte[] fields = dataTypes.GetAcknowledgment(acknowledgment, isOnlineMode);
SendPacket(PacketTypesOut.MessageAcknowledgment, fields); SendPacket(PacketTypesOut.MessageAcknowledgment, fields);
@ -2027,11 +2035,11 @@ namespace MinecraftClient.Protocol.Handlers
/// </summary> /// </summary>
/// <param name="command">Command</param> /// <param name="command">Command</param>
/// <returns> List< Argument Name, Argument Value > </returns> /// <returns> List< Argument Name, Argument Value > </returns>
private static List<Tuple<string, string>> CollectCommandArguments(string command) private List<Tuple<string, string>> CollectCommandArguments(string command)
{ {
List<Tuple<string, string>> needSigned = new(); List<Tuple<string, string>> needSigned = new();
if (!Settings.SignMessageInCommand) if (!isOnlineMode || !Settings.SignMessageInCommand)
return needSigned; return needSigned;
string[] argStage1 = command.Split(' ', 2, StringSplitOptions.None); string[] argStage1 = command.Split(' ', 2, StringSplitOptions.None);
@ -2086,7 +2094,8 @@ namespace MinecraftClient.Protocol.Handlers
try 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<byte> fields = new(); List<byte> fields = new();
@ -2098,7 +2107,7 @@ namespace MinecraftClient.Protocol.Handlers
fields.AddRange(dataTypes.GetLong(timeNow.ToUnixTimeMilliseconds())); fields.AddRange(dataTypes.GetLong(timeNow.ToUnixTimeMilliseconds()));
List<Tuple<string, string>> needSigned = CollectCommandArguments(command); // List< Argument Name, Argument Value > List<Tuple<string, string>> 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.GetLong(0)); // Salt: Long
fields.AddRange(dataTypes.GetVarInt(0)); // Signature Length: VarInt fields.AddRange(dataTypes.GetVarInt(0)); // Signature Length: VarInt
@ -2126,7 +2135,7 @@ namespace MinecraftClient.Protocol.Handlers
if (protocolVersion >= MC_1_19_2_Version) if (protocolVersion >= MC_1_19_2_Version)
{ {
// Message Acknowledgment // Message Acknowledgment
fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!)); fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!, isOnlineMode));
} }
SendPacket(PacketTypesOut.ChatCommand, fields); SendPacket(PacketTypesOut.ChatCommand, fields);
@ -2154,7 +2163,8 @@ namespace MinecraftClient.Protocol.Handlers
try 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<byte> fields = new(); List<byte> fields = new();
@ -2167,7 +2177,7 @@ namespace MinecraftClient.Protocol.Handlers
DateTimeOffset timeNow = DateTimeOffset.UtcNow; DateTimeOffset timeNow = DateTimeOffset.UtcNow;
fields.AddRange(dataTypes.GetLong(timeNow.ToUnixTimeMilliseconds())); 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.GetLong(0)); // Salt: Long
fields.AddRange(dataTypes.GetVarInt(0)); // Signature Length: VarInt fields.AddRange(dataTypes.GetVarInt(0)); // Signature Length: VarInt
@ -2193,7 +2203,7 @@ namespace MinecraftClient.Protocol.Handlers
if (protocolVersion >= MC_1_19_2_Version) if (protocolVersion >= MC_1_19_2_Version)
{ {
// Message Acknowledgment // Message Acknowledgment
fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!)); fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!, isOnlineMode));
} }
} }
SendPacket(PacketTypesOut.ChatMessage, fields); SendPacket(PacketTypesOut.ChatMessage, fields);

View file

@ -205,6 +205,7 @@ chat.fail=§8Failed to download the file.
chat.from_dir=§8Defaulting to en_GB.lang from your Minecraft directory. chat.from_dir=§8Defaulting to en_GB.lang from your Minecraft directory.
chat.loaded=§8Translations file loaded. chat.loaded=§8Translations file loaded.
chat.not_found=§8Translations file not found: '{0}'\nSome messages won't be properly printed without this file. 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]
# General message/information (i.e. Done) # General message/information (i.e. Done)