Conversation
_signedChat chose chat_command_signed whenever the client had profile keys and a chat session, regardless of the command. The vanilla client picks the packet per command: ClientPacketListener.sendCommand sends the unsigned ServerboundChatCommandPacket when SignableCommand.of(...) .arguments() is empty, and only sends the signed packet when there is an argument to sign. Every argumentless command (/login, /list, and any command the server's command tree does not mark as a message argument) went out on the signed packet with an empty signature list. The packet now follows the signatures actually produced.
93043f8 to
1aca229
Compare
rom1504
left a comment
There was a problem hiding this comment.
Astra agent review — AI-generated, not manually written by the maintainer.
The Astra agent reviewed this change at the maintainer's request. I inspected the current diff and packet schema and ran a local reproduction using the current chat plugin with installed dependencies; an unsigned command consumes acknowledgement state without sending it. I did not run a live vanilla server or the full test suite.
| } | ||
| client.write((mcData.supportFeature('seperateSignedChatCommandPacket') && canSign) ? 'chat_command_signed' : 'chat_command', chatPacket) | ||
| // A command with nothing to sign goes as the unsigned chat_command whether or not the client can sign. | ||
| client.write((mcData.supportFeature('seperateSignedChatCommandPacket') && argumentSignatures.length > 0) ? 'chat_command_signed' : 'chat_command', chatPacket) |
There was a problem hiding this comment.
Astra agent review — AI-generated, not manually written by the maintainer.
On versions with seperateSignedChatCommandPacket (for example 1.21.8), the newly selected chat_command contains only command, so the acknowledgement fields in chatPacket never reach the server. However, this branch still calls getAcknowledgements() (which marks entries as acknowledged) and then resets _lastSeenMessages.pending. I reproduced receiving one signed message, sending /list with signing enabled, and then sending chat: the command clears pending from 1 to 0 and the following chat_message sends offset 0, although no packet reported that acknowledgement offset. This desynchronizes the last-seen window used for chat validation. Could the unsigned-command branch leave both the pending count and entry flags untouched, with a regression covering an unsigned command followed by signed chat? Older versions whose chat_command carries acknowledgements should retain their current accounting.
Constraints on the serverbound command packet:
chat_command_signedis written only when the command produced at least one argument signature./login,/list, anything the server's command tree does not mark as a message argument) is written aschat_command, whether or not the client can sign.Vanilla reference:
ClientPacketListener.sendCommandsends the unsignedServerboundChatCommandPacketwhenSignableCommand.of(...).arguments()is empty.Tests:
/login hunter2and an argumentless/msgwritechat_commandwith an empty signature list. Both fail on master and pass with the change. They do not run in CI yet; #1526 makes this file run and #1527 fixes the pre-existing test in it.