mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
1.19.3 Chat command signing support & Update chat paser
This commit is contained in:
parent
fe0b268878
commit
0ce9690778
6 changed files with 164 additions and 103 deletions
|
|
@ -64,6 +64,7 @@ namespace MinecraftClient
|
||||||
private double motionY;
|
private double motionY;
|
||||||
public enum MovementType { Sneak, Walk, Sprint }
|
public enum MovementType { Sneak, Walk, Sprint }
|
||||||
private int sequenceId; // User for player block synchronization (Aka. digging, placing blocks, etc..)
|
private int sequenceId; // User for player block synchronization (Aka. digging, placing blocks, etc..)
|
||||||
|
private bool CanSendMessage = false;
|
||||||
|
|
||||||
private readonly string host;
|
private readonly string host;
|
||||||
private readonly int port;
|
private readonly int port;
|
||||||
|
|
@ -286,6 +287,9 @@ namespace MinecraftClient
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void TrySendMessageToServer()
|
private void TrySendMessageToServer()
|
||||||
{
|
{
|
||||||
|
if (!CanSendMessage)
|
||||||
|
return;
|
||||||
|
|
||||||
while (chatQueue.Count > 0 && nextMessageSendTime < DateTime.Now)
|
while (chatQueue.Count > 0 && nextMessageSendTime < DateTime.Now)
|
||||||
{
|
{
|
||||||
string text = chatQueue.Dequeue();
|
string text = chatQueue.Dequeue();
|
||||||
|
|
@ -2411,7 +2415,7 @@ namespace MinecraftClient
|
||||||
if (protocolversion >= Protocol18Handler.MC_1_19_3_Version
|
if (protocolversion >= Protocol18Handler.MC_1_19_3_Version
|
||||||
&& playerKeyPair != null)
|
&& playerKeyPair != null)
|
||||||
handler.SendPlayerSession(playerKeyPair);
|
handler.SendPlayerSession(playerKeyPair);
|
||||||
|
CanSendMessage = true;
|
||||||
|
|
||||||
if (inventoryHandlingRequested)
|
if (inventoryHandlingRequested)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
case 0x02: ReadData(1); ReadNextString(); ReadNextString(); ReadData(4); break;
|
case 0x02: ReadData(1); ReadNextString(); ReadNextString(); ReadData(4); break;
|
||||||
case 0x03:
|
case 0x03:
|
||||||
string message = ReadNextString();
|
string message = ReadNextString();
|
||||||
handler.OnTextReceived(new ChatMessage(message, protocolversion >= 72, 0, Guid.Empty)); break;
|
handler.OnTextReceived(new ChatMessage(message, null, protocolversion >= 72, -1, Guid.Empty)); break;
|
||||||
case 0x04: ReadData(16); break;
|
case 0x04: ReadData(16); break;
|
||||||
case 0x05: ReadData(6); ReadNextItemSlot(); break;
|
case 0x05: ReadData(6); ReadNextItemSlot(); break;
|
||||||
case 0x06: ReadData(12); break;
|
case 0x06: ReadData(12); break;
|
||||||
|
|
|
||||||
|
|
@ -377,6 +377,8 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
for (int i = 0; i < worldCount; i++)
|
for (int i = 0; i < worldCount; i++)
|
||||||
dataTypes.ReadNextString(packetData); // Dimension Names (World Names) - 1.16 and above
|
dataTypes.ReadNextString(packetData); // Dimension Names (World Names) - 1.16 and above
|
||||||
var registryCodec = dataTypes.ReadNextNbt(packetData); // Registry Codec (Dimension Codec) - 1.16 and above
|
var registryCodec = dataTypes.ReadNextNbt(packetData); // Registry Codec (Dimension Codec) - 1.16 and above
|
||||||
|
if (protocolVersion >= MC_1_19_Version)
|
||||||
|
ChatParser.ReadChatType(registryCodec);
|
||||||
if (handler.GetTerrainEnabled())
|
if (handler.GetTerrainEnabled())
|
||||||
World.StoreDimensionList(registryCodec);
|
World.StoreDimensionList(registryCodec);
|
||||||
}
|
}
|
||||||
|
|
@ -455,9 +457,6 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (protocolVersion >= MC_1_19_3_Version)
|
|
||||||
SendPlayerSession(handler.GetPlayerKeyPair());
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PacketTypesIn.DeclareCommands:
|
case PacketTypesIn.DeclareCommands:
|
||||||
if (protocolVersion >= MC_1_19_Version)
|
if (protocolVersion >= MC_1_19_Version)
|
||||||
|
|
@ -486,7 +485,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
else
|
else
|
||||||
senderUUID = Guid.Empty;
|
senderUUID = Guid.Empty;
|
||||||
|
|
||||||
handler.OnTextReceived(new(message, true, messageType, senderUUID));
|
handler.OnTextReceived(new(message, null, true, messageType, senderUUID));
|
||||||
}
|
}
|
||||||
else if (protocolVersion == MC_1_19_Version) // 1.19
|
else if (protocolVersion == MC_1_19_Version) // 1.19
|
||||||
{
|
{
|
||||||
|
|
@ -608,25 +607,31 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
{
|
{
|
||||||
// 1.19.3+
|
// 1.19.3+
|
||||||
// Header section
|
// Header section
|
||||||
|
// net.minecraft.network.packet.s2c.play.ChatMessageS2CPacket#write
|
||||||
Guid senderUUID = dataTypes.ReadNextUUID(packetData);
|
Guid senderUUID = dataTypes.ReadNextUUID(packetData);
|
||||||
int index = dataTypes.ReadNextVarInt(packetData);
|
int index = dataTypes.ReadNextVarInt(packetData);
|
||||||
// Signature is fixed size of 256 bytes
|
// Signature is fixed size of 256 bytes
|
||||||
byte[]? messageSignature = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextByteArray(packetData, 256) : null;
|
byte[]? messageSignature = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextByteArray(packetData, 256) : null;
|
||||||
|
|
||||||
// Body
|
// Body
|
||||||
|
// net.minecraft.network.message.MessageBody.Serialized#write
|
||||||
string message = dataTypes.ReadNextString(packetData);
|
string message = dataTypes.ReadNextString(packetData);
|
||||||
long timestamp = dataTypes.ReadNextLong(packetData);
|
long timestamp = dataTypes.ReadNextLong(packetData);
|
||||||
long salt = dataTypes.ReadNextLong(packetData);
|
long salt = dataTypes.ReadNextLong(packetData);
|
||||||
|
|
||||||
// Previous Messages
|
// Previous Messages
|
||||||
|
// net.minecraft.network.message.LastSeenMessageList.Indexed#write
|
||||||
|
// net.minecraft.network.message.MessageSignatureData.Indexed#write
|
||||||
int totalPreviousMessages = dataTypes.ReadNextVarInt(packetData);
|
int totalPreviousMessages = dataTypes.ReadNextVarInt(packetData);
|
||||||
List<Tuple<int, byte[]>> previousMessageSignatures = new();
|
Tuple<int, byte[]?>[] previousMessageSignatures = new Tuple<int, byte[]?>[totalPreviousMessages];
|
||||||
|
|
||||||
for (int i = 0; i < totalPreviousMessages; i++)
|
for (int i = 0; i < totalPreviousMessages; i++)
|
||||||
{
|
{
|
||||||
int messageId = dataTypes.ReadNextVarInt(packetData);
|
// net.minecraft.network.message.MessageSignatureData.Indexed#fromBuf
|
||||||
if (messageId == 0) // from botcraft implementation. Only read if id is 0. Byte array is fixed size of 256 bytes
|
int messageId = dataTypes.ReadNextVarInt(packetData) - 1;
|
||||||
previousMessageSignatures.Add(new Tuple<int, byte[]>(messageId, dataTypes.ReadNextByteArray(packetData, 256)));
|
if (messageId == -1)
|
||||||
|
previousMessageSignatures[i] = new Tuple<int, byte[]?>(messageId, dataTypes.ReadNextByteArray(packetData, 256));
|
||||||
|
else
|
||||||
|
previousMessageSignatures[i] = new Tuple<int, byte[]?>(messageId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
|
|
@ -638,14 +643,16 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
dataTypes.ReadNextULongArray(packetData);
|
dataTypes.ReadNextULongArray(packetData);
|
||||||
|
|
||||||
// Network Target
|
// Network Target
|
||||||
|
// net.minecraft.network.message.MessageType.Serialized#write
|
||||||
int chatTypeId = dataTypes.ReadNextVarInt(packetData);
|
int chatTypeId = dataTypes.ReadNextVarInt(packetData);
|
||||||
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;
|
ChatParser.MessageType messageTypeEnum = ChatParser.ChatId2Type!.GetValueOrDefault(chatTypeId, ChatParser.MessageType.CHAT);
|
||||||
|
|
||||||
|
Dictionary<string, Json.JSONData> chatInfo = Json.ParseJson(targetName ?? chatName).Properties;
|
||||||
string senderDisplayName = (chatInfo.ContainsKey("insertion") ? chatInfo["insertion"] : chatInfo["text"]).StringValue;
|
string senderDisplayName = (chatInfo.ContainsKey("insertion") ? chatInfo["insertion"] : chatInfo["text"]).StringValue;
|
||||||
string? senderTeamName = null;
|
string? senderTeamName = null;
|
||||||
ChatParser.MessageType messageTypeEnum = ChatParser.ChatId2Type!.GetValueOrDefault(chatTypeId, ChatParser.MessageType.CHAT);
|
|
||||||
if (targetName != null &&
|
if (targetName != null &&
|
||||||
(messageTypeEnum == ChatParser.MessageType.TEAM_MSG_COMMAND_INCOMING || messageTypeEnum == ChatParser.MessageType.TEAM_MSG_COMMAND_OUTGOING))
|
(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;
|
senderTeamName = Json.ParseJson(targetName).Properties["with"].DataArray[0].Properties["text"].StringValue;
|
||||||
|
|
@ -663,13 +670,68 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Verify the message
|
// Todo: verify message
|
||||||
ChatMessage chat = new(message, false, chatTypeId, senderUUID, unsignedChatContent, senderDisplayName, senderTeamName, timestamp, messageSignature, false);
|
bool verifyResult;
|
||||||
|
if (!isOnlineMode)
|
||||||
|
verifyResult = false;
|
||||||
|
else if (senderUUID == handler.GetUserUuid())
|
||||||
|
verifyResult = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlayerInfo? player = handler.GetPlayerInfo(senderUUID);
|
||||||
|
if (player == null || !player.IsMessageChainLegal())
|
||||||
|
verifyResult = false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
verifyResult = false;
|
||||||
|
//bool lastVerifyResult = player.IsMessageChainLegal();
|
||||||
|
//verifyResult = player.VerifyMessage(message, timestamp, salt, ref headerSignature, ref precedingSignature, lastSeenMessages);
|
||||||
|
//if (lastVerifyResult && !verifyResult)
|
||||||
|
// log.Warn(string.Format(Translations.chat_message_chain_broken, senderDisplayName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatMessage chat = new(message, false, chatTypeId, senderUUID, unsignedChatContent, senderDisplayName, senderTeamName, timestamp, messageSignature, verifyResult);
|
||||||
if (isOnlineMode && !chat.LacksSender() && messageSignature != null)
|
if (isOnlineMode && !chat.LacksSender() && messageSignature != null)
|
||||||
Acknowledge(chat);
|
Acknowledge(chat);
|
||||||
handler.OnTextReceived(chat);
|
handler.OnTextReceived(chat);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PacketTypesIn.SystemChat:
|
||||||
|
string systemMessage = dataTypes.ReadNextString(packetData);
|
||||||
|
if (protocolVersion >= MC_1_19_3_Version)
|
||||||
|
{
|
||||||
|
bool isOverlay = dataTypes.ReadNextBool(packetData);
|
||||||
|
if (isOverlay)
|
||||||
|
{
|
||||||
|
if (!Config.Main.Advanced.ShowXPBarMessages)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!Config.Main.Advanced.ShowSystemMessages)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
handler.OnTextReceived(new(systemMessage, null, true, -1, Guid.Empty, true));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int msgType = dataTypes.ReadNextVarInt(packetData);
|
||||||
|
if ((msgType == 1 && !Config.Main.Advanced.ShowSystemMessages))
|
||||||
|
break;
|
||||||
|
handler.OnTextReceived(new(systemMessage, null, true, msgType, Guid.Empty, true));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PacketTypesIn.ProfilelessChatMessage:
|
||||||
|
string message_ = dataTypes.ReadNextString(packetData);
|
||||||
|
int messageType_ = dataTypes.ReadNextVarInt(packetData);
|
||||||
|
string messageName = dataTypes.ReadNextString(packetData);
|
||||||
|
string? targetName_ = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextString(packetData) : null;
|
||||||
|
ChatMessage profilelessChat = new(message_, messageName, true, messageType_, Guid.Empty, true);
|
||||||
|
profilelessChat.isSenderJson = true;
|
||||||
|
profilelessChat.teamName = targetName_;
|
||||||
|
handler.OnTextReceived(profilelessChat);
|
||||||
|
break;
|
||||||
case PacketTypesIn.CombatEvent:
|
case PacketTypesIn.CombatEvent:
|
||||||
// 1.8 - 1.16.5
|
// 1.8 - 1.16.5
|
||||||
if (protocolVersion >= MC_1_8_Version && protocolVersion <= MC_1_16_5_Version)
|
if (protocolVersion >= MC_1_8_Version && protocolVersion <= MC_1_16_5_Version)
|
||||||
|
|
@ -1214,14 +1276,6 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
break;
|
break;
|
||||||
case PacketTypesIn.ChatSuggestions:
|
case PacketTypesIn.ChatSuggestions:
|
||||||
break;
|
break;
|
||||||
case PacketTypesIn.ProfilelessChatMessage:
|
|
||||||
string message_ = dataTypes.ReadNextString(packetData);
|
|
||||||
int messageType_ = dataTypes.ReadNextVarInt(packetData);
|
|
||||||
string messageName = dataTypes.ReadNextString(packetData);
|
|
||||||
string? targetName_ = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextString(packetData) : null;
|
|
||||||
|
|
||||||
// Not clear for what this is used for as the time of writing
|
|
||||||
break;
|
|
||||||
case PacketTypesIn.MapChunkBulk:
|
case PacketTypesIn.MapChunkBulk:
|
||||||
if (protocolVersion < MC_1_9_Version && handler.GetTerrainEnabled())
|
if (protocolVersion < MC_1_9_Version && handler.GetTerrainEnabled())
|
||||||
{
|
{
|
||||||
|
|
@ -1296,14 +1350,13 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
case PacketTypesIn.PlayerInfo:
|
case PacketTypesIn.PlayerInfo:
|
||||||
if (protocolVersion >= MC_1_19_3_Version)
|
if (protocolVersion >= MC_1_19_3_Version)
|
||||||
{
|
{
|
||||||
// int actions = dataTypes.ReadNextVarInt(packetData);
|
byte actionBitset = dataTypes.ReadNextByte(packetData);
|
||||||
ulong actionBitset = dataTypes.ReadNextByte(packetData);
|
|
||||||
int numberOfActions = dataTypes.ReadNextVarInt(packetData);
|
int numberOfActions = dataTypes.ReadNextVarInt(packetData);
|
||||||
for (int i = 0; i < numberOfActions; i++)
|
for (int i = 0; i < numberOfActions; i++)
|
||||||
{
|
{
|
||||||
Guid playerUuid = dataTypes.ReadNextUUID(packetData);
|
Guid playerUuid = dataTypes.ReadNextUUID(packetData);
|
||||||
|
|
||||||
if ((actionBitset & (1ul << 0)) > 0) // Actions bit 0: add player
|
if ((actionBitset & (1 << 0)) > 0) // Actions bit 0: add player
|
||||||
{
|
{
|
||||||
string name = dataTypes.ReadNextString(packetData);
|
string name = dataTypes.ReadNextString(packetData);
|
||||||
int numberOfProperties = dataTypes.ReadNextVarInt(packetData);
|
int numberOfProperties = dataTypes.ReadNextVarInt(packetData);
|
||||||
|
|
@ -1318,7 +1371,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerInfo player = handler.GetPlayerInfo(playerUuid)!;
|
PlayerInfo player = handler.GetPlayerInfo(playerUuid)!;
|
||||||
if ((actionBitset & (1ul << 1)) > 0) // Actions bit 1: initialize chat
|
if ((actionBitset & (1 << 1)) > 0) // Actions bit 1: initialize chat
|
||||||
{
|
{
|
||||||
bool hasSignatureData = dataTypes.ReadNextBool(packetData);
|
bool hasSignatureData = dataTypes.ReadNextBool(packetData);
|
||||||
if (hasSignatureData)
|
if (hasSignatureData)
|
||||||
|
|
@ -1334,20 +1387,20 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
player.ClearPublicKey();
|
player.ClearPublicKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((actionBitset & (1ul << 2)) > 0) // Actions bit 2: update gamemode
|
if ((actionBitset & 1 << 2) > 0) // Actions bit 2: update gamemode
|
||||||
{
|
{
|
||||||
handler.OnGamemodeUpdate(playerUuid, dataTypes.ReadNextVarInt(packetData));
|
handler.OnGamemodeUpdate(playerUuid, dataTypes.ReadNextVarInt(packetData));
|
||||||
}
|
}
|
||||||
if ((actionBitset & (1ul << 3)) > 0) // Actions bit 3: update listed
|
if ((actionBitset & (1 << 3)) > 0) // Actions bit 3: update listed
|
||||||
{
|
{
|
||||||
player.Listed = dataTypes.ReadNextBool(packetData);
|
player.Listed = dataTypes.ReadNextBool(packetData);
|
||||||
}
|
}
|
||||||
if ((actionBitset & (1ul << 4)) > 0) // Actions bit 4: update latency
|
if ((actionBitset & (1 << 4)) > 0) // Actions bit 4: update latency
|
||||||
{
|
{
|
||||||
int latency = dataTypes.ReadNextVarInt(packetData);
|
int latency = dataTypes.ReadNextVarInt(packetData);
|
||||||
handler.OnLatencyUpdate(playerUuid, latency); //Update latency;
|
handler.OnLatencyUpdate(playerUuid, latency); //Update latency;
|
||||||
}
|
}
|
||||||
if ((actionBitset & (1ul << 5)) > 0) // Actions bit 5: update display name
|
if ((actionBitset & (1 << 5)) > 0) // Actions bit 5: update display name
|
||||||
{
|
{
|
||||||
if (dataTypes.ReadNextBool(packetData))
|
if (dataTypes.ReadNextBool(packetData))
|
||||||
player.DisplayName = dataTypes.ReadNextString(packetData);
|
player.DisplayName = dataTypes.ReadNextString(packetData);
|
||||||
|
|
@ -1811,13 +1864,6 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
long TimeOfday = dataTypes.ReadNextLong(packetData);
|
long TimeOfday = dataTypes.ReadNextLong(packetData);
|
||||||
handler.OnTimeUpdate(WorldAge, TimeOfday);
|
handler.OnTimeUpdate(WorldAge, TimeOfday);
|
||||||
break;
|
break;
|
||||||
case PacketTypesIn.SystemChat:
|
|
||||||
string systemMessage = dataTypes.ReadNextString(packetData);
|
|
||||||
int msgType = dataTypes.ReadNextVarInt(packetData);
|
|
||||||
if ((msgType == 1 && !Config.Main.Advanced.ShowSystemMessages))
|
|
||||||
break;
|
|
||||||
handler.OnTextReceived(new(systemMessage, true, msgType, Guid.Empty, true));
|
|
||||||
break;
|
|
||||||
case PacketTypesIn.EntityTeleport:
|
case PacketTypesIn.EntityTeleport:
|
||||||
if (handler.GetEntityHandlingEnabled())
|
if (handler.GetEntityHandlingEnabled())
|
||||||
{
|
{
|
||||||
|
|
@ -2498,9 +2544,12 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LastSeenMessageList.Acknowledgment? acknowledgment =
|
LastSeenMessageList.Acknowledgment? acknowledgment_1_19_2 =
|
||||||
(protocolVersion >= MC_1_19_2_Version) ? ConsumeAcknowledgment() : null;
|
(protocolVersion == MC_1_19_2_Version) ? ConsumeAcknowledgment() : null;
|
||||||
|
|
||||||
|
(LastSeenMessageList.AcknowledgedMessage[] acknowledgment_1_19_3, byte[] bitset_1_19_3, int messageCount_1_19_3) =
|
||||||
|
(protocolVersion >= MC_1_19_3_Version) ? lastSeenMessagesCollector.Collect_1_19_3() : new(Array.Empty<LastSeenMessageList.AcknowledgedMessage>(), Array.Empty<byte>(), 0);
|
||||||
|
|
||||||
List<byte> fields = new();
|
List<byte> fields = new();
|
||||||
|
|
||||||
// Command: String
|
// Command: String
|
||||||
|
|
@ -2529,34 +2578,37 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
foreach ((string argName, string message) in needSigned)
|
foreach ((string argName, string message) in needSigned)
|
||||||
{
|
{
|
||||||
fields.AddRange(dataTypes.GetString(argName)); // Argument name: String
|
fields.AddRange(dataTypes.GetString(argName)); // Argument name: String
|
||||||
byte[] sign = (protocolVersion >= MC_1_19_2_Version) ?
|
|
||||||
playerKeyPair!.PrivateKey.SignMessage(message, uuid, timeNow, ref salt, acknowledgment!.lastSeen) :
|
byte[] sign;
|
||||||
playerKeyPair!.PrivateKey.SignMessage(message, uuid, timeNow, ref salt);
|
if (protocolVersion == MC_1_19_Version)
|
||||||
fields.AddRange(DataTypes.GetVarInt(sign.Length)); // Signature length: VarInt
|
sign = playerKeyPair!.PrivateKey.SignMessage(message, uuid, timeNow, ref salt);
|
||||||
fields.AddRange(sign); // Signature: Byte Array
|
else if (protocolVersion == MC_1_19_2_Version)
|
||||||
|
sign = playerKeyPair!.PrivateKey.SignMessage(message, uuid, timeNow, ref salt, acknowledgment_1_19_2!.lastSeen);
|
||||||
|
else // protocolVersion >= MC_1_19_3_Version
|
||||||
|
sign = playerKeyPair!.PrivateKey.SignMessage(message, uuid, chatUuid, messageIndex++, timeNow, ref salt, acknowledgment_1_19_3);
|
||||||
|
|
||||||
|
if (protocolVersion <= MC_1_19_2_Version)
|
||||||
|
fields.AddRange(DataTypes.GetVarInt(sign.Length)); // Signature length: VarInt
|
||||||
|
|
||||||
|
fields.AddRange(sign); // Signature: Byte Array
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (protocolVersion < MC_1_19_3_Version)
|
if (protocolVersion <= MC_1_19_2_Version)
|
||||||
{
|
fields.AddRange(dataTypes.GetBool(false)); // Signed Preview: Boolean
|
||||||
// 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)
|
if (protocolVersion == MC_1_19_2_Version)
|
||||||
{
|
{
|
||||||
// Message Acknowledgment (1.19.2)
|
// Message Acknowledgment (1.19.2)
|
||||||
fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment!, isOnlineMode && Config.Signature.LoginWithSecureProfile));
|
fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment_1_19_2!, isOnlineMode && Config.Signature.LoginWithSecureProfile));
|
||||||
}
|
}
|
||||||
else if (protocolVersion >= MC_1_19_3_Version)
|
else if (protocolVersion >= MC_1_19_3_Version)
|
||||||
{
|
{
|
||||||
// 1.19.3
|
// message count
|
||||||
// Acknowledged: BitSet (no idea what is this)
|
fields.AddRange(DataTypes.GetVarInt(messageCount_1_19_3));
|
||||||
fields.AddRange(new byte[3] { 0, 0, 0 });
|
|
||||||
|
// Acknowledged: BitSet
|
||||||
|
fields.AddRange(bitset_1_19_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendPacket(PacketTypesOut.ChatCommand, fields);
|
SendPacket(PacketTypesOut.ChatCommand, fields);
|
||||||
|
|
@ -2575,7 +2627,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
/// <returns>True if properly sent</returns>
|
/// <returns>True if properly sent</returns>
|
||||||
public bool SendChatMessage(string message, PlayerKeyPair? playerKeyPair)
|
public bool SendChatMessage(string message, PlayerKeyPair? playerKeyPair)
|
||||||
{
|
{
|
||||||
if (String.IsNullOrEmpty(message))
|
if (string.IsNullOrEmpty(message))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Process Chat Command - 1.19 and above
|
// Process Chat Command - 1.19 and above
|
||||||
|
|
@ -2622,8 +2674,8 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
sign = playerKeyPair.PrivateKey.SignMessage(message, playerUuid, timeNow, ref salt);
|
sign = playerKeyPair.PrivateKey.SignMessage(message, playerUuid, timeNow, ref salt);
|
||||||
else if (protocolVersion == MC_1_19_2_Version) // 1.19.2
|
else if (protocolVersion == MC_1_19_2_Version) // 1.19.2
|
||||||
sign = playerKeyPair.PrivateKey.SignMessage(message, playerUuid, timeNow, ref salt, acknowledgment_1_19_2!.lastSeen);
|
sign = playerKeyPair.PrivateKey.SignMessage(message, playerUuid, timeNow, ref salt, acknowledgment_1_19_2!.lastSeen);
|
||||||
else // 1.19.3+
|
else // protocolVersion >= MC_1_19_3_Version
|
||||||
sign = playerKeyPair.PrivateKey.SignMessage(message, playerUuid, handler.GetPlayerInfo(playerUuid)!.ChatUuid, messageIndex++, timeNow, ref salt, acknowledgment_1_19_3);
|
sign = playerKeyPair.PrivateKey.SignMessage(message, playerUuid, chatUuid, messageIndex++, timeNow, ref salt, acknowledgment_1_19_3);
|
||||||
|
|
||||||
if (protocolVersion >= MC_1_19_3_Version)
|
if (protocolVersion >= MC_1_19_3_Version)
|
||||||
fields.AddRange(dataTypes.GetBool(true));
|
fields.AddRange(dataTypes.GetBool(true));
|
||||||
|
|
@ -3317,28 +3369,6 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
packet.AddRange(playerKeyPair.PublicKey.SignatureV2);
|
packet.AddRange(playerKeyPair.PublicKey.SignatureV2);
|
||||||
|
|
||||||
SendPacket(PacketTypesOut.PlayerSession, packet);
|
SendPacket(PacketTypesOut.PlayerSession, packet);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (SocketException) { return false; }
|
|
||||||
catch (System.IO.IOException) { return false; }
|
|
||||||
catch (ObjectDisposedException) { return false; }
|
|
||||||
}
|
|
||||||
else { return false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SendMessageAcknowledgment(int messageCount)
|
|
||||||
{
|
|
||||||
if (protocolVersion >= MC_1_19_3_Version)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
List<byte> packet = new();
|
|
||||||
|
|
||||||
packet.AddRange(dataTypes.GetVarInt(messageCount));
|
|
||||||
|
|
||||||
SendPacket(PacketTypesOut.MessageAcknowledgment, packet);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (SocketException) { return false; }
|
catch (SocketException) { return false; }
|
||||||
|
|
|
||||||
|
|
@ -5,31 +5,31 @@ namespace MinecraftClient.Protocol.Message
|
||||||
public class ChatMessage
|
public class ChatMessage
|
||||||
{
|
{
|
||||||
// in 1.19 and above, isSignedChat = true
|
// in 1.19 and above, isSignedChat = true
|
||||||
public readonly bool isSignedChat;
|
public bool isSignedChat;
|
||||||
|
|
||||||
public readonly string content;
|
public string content;
|
||||||
|
|
||||||
public readonly bool isJson;
|
public bool isJson, isSenderJson;
|
||||||
|
|
||||||
// 0: chat (chat box), 1: system message (chat box), 2: game info (above hotbar), 3: say command,
|
// 0: chat (chat box), 1: system message (chat box), 2: game info (above hotbar), 3: say command,
|
||||||
// 4: msg command, 5: team msg command, 6: emote command, 7: tellraw command
|
// 4: msg command, 5: team msg command, 6: emote command, 7: tellraw command
|
||||||
public readonly int chatTypeId;
|
public int chatTypeId;
|
||||||
|
|
||||||
public readonly Guid senderUUID;
|
public Guid senderUUID;
|
||||||
|
|
||||||
public readonly bool isSystemChat;
|
public bool isSystemChat;
|
||||||
|
|
||||||
public readonly string? unsignedContent;
|
public string? unsignedContent;
|
||||||
|
|
||||||
public readonly string? displayName;
|
public string? displayName;
|
||||||
|
|
||||||
public readonly string? teamName;
|
public string? teamName;
|
||||||
|
|
||||||
public readonly DateTime? timestamp;
|
public DateTime? timestamp;
|
||||||
|
|
||||||
public readonly byte[]? signature;
|
public byte[]? signature;
|
||||||
|
|
||||||
public readonly bool? isSignatureLegal;
|
public bool? isSignatureLegal;
|
||||||
|
|
||||||
public ChatMessage(string content, bool isJson, int chatType, Guid senderUUID, string? unsignedContent, string displayName, string? teamName, long timestamp, byte[] signature, bool isSignatureLegal)
|
public ChatMessage(string content, bool isJson, int chatType, Guid senderUUID, string? unsignedContent, string displayName, string? teamName, long timestamp, byte[] signature, bool isSignatureLegal)
|
||||||
{
|
{
|
||||||
|
|
@ -47,11 +47,12 @@ namespace MinecraftClient.Protocol.Message
|
||||||
this.isSignatureLegal = isSignatureLegal;
|
this.isSignatureLegal = isSignatureLegal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChatMessage(string content, bool isJson, int chatType, Guid senderUUID, bool isSystemChat = false)
|
public ChatMessage(string content, string? displayName, bool isJson, int chatType, Guid senderUUID, bool isSystemChat = false)
|
||||||
{
|
{
|
||||||
isSignedChat = isSystemChat;
|
isSignedChat = isSystemChat;
|
||||||
this.isSystemChat = isSystemChat;
|
this.isSystemChat = isSystemChat;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
|
this.displayName = displayName;
|
||||||
this.isJson = isJson;
|
this.isJson = isJson;
|
||||||
chatTypeId = chatType;
|
chatTypeId = chatType;
|
||||||
this.senderUUID = senderUUID;
|
this.senderUUID = senderUUID;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -28,6 +29,30 @@ namespace MinecraftClient.Protocol
|
||||||
|
|
||||||
public static Dictionary<int, MessageType>? ChatId2Type;
|
public static Dictionary<int, MessageType>? ChatId2Type;
|
||||||
|
|
||||||
|
public static void ReadChatType(Dictionary<string, object> registryCodec)
|
||||||
|
{
|
||||||
|
Dictionary<int, MessageType> chatTypeDictionary = ChatId2Type ?? new();
|
||||||
|
var chatTypeListNbt = (object[])(((Dictionary<string, object>)registryCodec["minecraft:chat_type"])["value"]);
|
||||||
|
foreach (var (chatName, chatId) in from Dictionary<string, object> chatTypeNbt in chatTypeListNbt
|
||||||
|
let chatName = (string)chatTypeNbt["name"]
|
||||||
|
let chatId = (int)chatTypeNbt["id"]
|
||||||
|
select (chatName, chatId))
|
||||||
|
{
|
||||||
|
chatTypeDictionary[chatId] = chatName switch
|
||||||
|
{
|
||||||
|
"minecraft:chat" => MessageType.CHAT,
|
||||||
|
"minecraft:emote_command" => MessageType.EMOTE_COMMAND,
|
||||||
|
"minecraft:msg_command_incoming" => MessageType.MSG_COMMAND_INCOMING,
|
||||||
|
"minecraft:msg_command_outgoing" => MessageType.MSG_COMMAND_OUTGOING,
|
||||||
|
"minecraft:say_command" => MessageType.SAY_COMMAND,
|
||||||
|
"minecraft:team_msg_command_incoming" => MessageType.TEAM_MSG_COMMAND_INCOMING,
|
||||||
|
"minecraft:team_msg_command_outgoing" => MessageType.TEAM_MSG_COMMAND_OUTGOING,
|
||||||
|
_ => MessageType.CHAT,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
ChatId2Type = chatTypeDictionary;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The main function to convert text from MC 1.6+ JSON to MC 1.5.2 formatted text
|
/// The main function to convert text from MC 1.6+ JSON to MC 1.5.2 formatted text
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -47,7 +72,7 @@ namespace MinecraftClient.Protocol
|
||||||
/// <returns>Returns the translated text</returns>
|
/// <returns>Returns the translated text</returns>
|
||||||
public static string ParseSignedChat(ChatMessage message, List<string>? links = null)
|
public static string ParseSignedChat(ChatMessage message, List<string>? links = null)
|
||||||
{
|
{
|
||||||
string sender = message.displayName!;
|
string sender = message.isSenderJson ? ParseText(message.displayName!) : message.displayName!;
|
||||||
string content;
|
string content;
|
||||||
if (Config.Signature.ShowModifiedChat && message.unsignedContent != null)
|
if (Config.Signature.ShowModifiedChat && message.unsignedContent != null)
|
||||||
{
|
{
|
||||||
|
|
@ -66,7 +91,7 @@ namespace MinecraftClient.Protocol
|
||||||
List<string> usingData = new();
|
List<string> usingData = new();
|
||||||
|
|
||||||
MessageType chatType;
|
MessageType chatType;
|
||||||
if (message.isSystemChat)
|
if (message.chatTypeId == -1)
|
||||||
chatType = MessageType.RAW_MSG;
|
chatType = MessageType.RAW_MSG;
|
||||||
else if (!ChatId2Type!.TryGetValue(message.chatTypeId, out chatType))
|
else if (!ChatId2Type!.TryGetValue(message.chatTypeId, out chatType))
|
||||||
chatType = MessageType.CHAT;
|
chatType = MessageType.CHAT;
|
||||||
|
|
@ -119,7 +144,7 @@ namespace MinecraftClient.Protocol
|
||||||
if (message.isSystemChat)
|
if (message.isSystemChat)
|
||||||
{
|
{
|
||||||
if (Config.Signature.MarkSystemMessage)
|
if (Config.Signature.MarkSystemMessage)
|
||||||
color = "§z §r "; // Custom color code §z : Background Gray
|
color = "§z▍§r"; // Custom color code §z : Background Gray
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -128,18 +153,18 @@ namespace MinecraftClient.Protocol
|
||||||
if (Config.Signature.ShowModifiedChat && message.unsignedContent != null)
|
if (Config.Signature.ShowModifiedChat && message.unsignedContent != null)
|
||||||
{
|
{
|
||||||
if (Config.Signature.MarkModifiedMsg)
|
if (Config.Signature.MarkModifiedMsg)
|
||||||
color = "§x §r "; // Custom color code §x : Background Yellow
|
color = "§x▍§r"; // Custom color code §x : Background Yellow
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Config.Signature.MarkLegallySignedMsg)
|
if (Config.Signature.MarkLegallySignedMsg)
|
||||||
color = "§y §r "; // Custom color code §y : Background Green
|
color = "§y▍§r"; // Custom color code §y : Background Green
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Config.Signature.MarkIllegallySignedMsg)
|
if (Config.Signature.MarkIllegallySignedMsg)
|
||||||
color = "§w §r "; // Custom color code §w : Background Red
|
color = "§w▍§r"; // Custom color code §w : Background Red
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return color + text;
|
return color + text;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Security.Permissions;
|
using System.Security.Permissions;
|
||||||
using static MinecraftClient.Protocol.Message.LastSeenMessageList;
|
using static MinecraftClient.Protocol.Message.LastSeenMessageList;
|
||||||
|
|
||||||
|
|
@ -120,7 +121,7 @@ namespace MinecraftClient.Protocol.Message
|
||||||
{
|
{
|
||||||
// net.minecraft.network.message.LastSeenMessagesCollector#add(net.minecraft.network.message.MessageSignatureData, boolean)
|
// net.minecraft.network.message.LastSeenMessagesCollector#add(net.minecraft.network.message.MessageSignatureData, boolean)
|
||||||
// net.minecraft.network.message.LastSeenMessagesCollector#add(net.minecraft.network.message.AcknowledgedMessage)
|
// net.minecraft.network.message.LastSeenMessagesCollector#add(net.minecraft.network.message.AcknowledgedMessage)
|
||||||
if (entry == lastEntry)
|
if (lastEntry != null && entry.signature.SequenceEqual(lastEntry.signature))
|
||||||
return false;
|
return false;
|
||||||
lastEntry = entry;
|
lastEntry = entry;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue