PrismarineJS / PrismarineJS/node-minecraft-protocol
custom_click_action packet - incorrect nbt buffer size?
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 1.4k
- Forks
- 290
- Avg merge
- 4d 8h
- Merged PRs (30d)
- 7
Description
[+] The FAQ doesn't contain a resolution to my issue
Versions
- minecraft-protocol: 1.64.0
- server: paper 1.21.8
- node: 24.6.0
Detailed description of a problem
The Dialog API was added in 1.21.6. The dialog can be called during the configuration state. When the button is clicked, the custom_click_action packet is sent. I tried sending this packet, but it always returns an error about an invalid value.
What did you try yet?
I wrote code to manually send this packet using AI, and it worked. As far as I understand, the nbt buffer length is being calculated incorrectly. The code, as I've verified, is presented below.
Correct buffer: <Buffer 00 08 10 6e 6c 6f 67 69 6e 3a 6c 6f 67 69 6e 2f 79 65 73 1a 0a 08 00 08 70 61 73 73 77 6f 72 64 00 0b 68 65 6c 6c 6f 20 77 6f 72 6c 64 00>
Incorrect buffer: <Buffer 00 08 10 6e 6c 6f 67 69 6e 3a 6c 6f 67 69 6e 2f 79 65 73 01 0a 08 00 08 70 61 73 73 77 6f 72 64 00 0b 68 65 6c 6c 6f 20 77 6f 72 6c 64 00>
The difference here is in 1 number.
packetParts value is: [
<Buffer 08>,
<Buffer 10 6e 6c 6f 67 69 6e 3a 6c 6f 67 69 6e 2f 79 65 73>,
<Buffer 1a>,
<Buffer 0a 08 00 08 70 61 73 73 77 6f 72 64 00 0b 68 65 6c 6c 6f 20 77 6f 72 6c 64 00>
]
As far as I understand, the server sees that the nbt is short and does not read it completely.
Your current code
bot._client.on('packet', async (data, meta) => {
if (meta.name === 'show_dialog') {
// manual sending (works correctly)
const packetParts = [];
packetParts.push(encodeVarInt(0x08)); // packet id
packetParts.push(encodeString("nlogin:login/yes")); // The identifier for the click action
const keyBytes = Buffer.from('password', 'utf8');
const passBytes = Buffer.from('hello world', 'utf8');
const nbtSize = 1 + 1 + 2 + keyBytes.length + 2 + passBytes.length + 1;
const nbtBuffer = Buffer.alloc(nbtSize);
let offset = 0;
nbtBuffer.writeUInt8(0x0A, offset++);
nbtBuffer.writeUInt8(0x08, offset++);
nbtBuffer.writeUInt16BE(keyBytes.length, offset);
offset += 2;
keyBytes.copy(nbtBuffer, offset);
offset += keyBytes.length;
nbtBuffer.writeUInt16BE(passBytes.length, offset);
offset += 2;
passBytes.copy(nbtBuffer, offset);
offset += passBytes.length;
nbtBuffer.writeUInt8(0x00, offset++);
packetParts.push(encodeVarInt(nbtBuffer.length)); // nbt buffer size
packetParts.push(nbtBuffer); // nbt buffer data
const rawBuffer = Buffer.concat(packetParts);
bot._client.writeRaw(rawBuffer);
// sending using write (not working correctly)
bot._client.write('custom_click_action', { id: 'nlogin:login/yes', nbt: nbt.comp({ password: nbt.string('hello world')}, ) });
}
});
function encodeVarInt(value) {
const bytes = [];
do {
let temp = value & 0x7f;
value >>>= 7;
if (value !== 0) {
temp |= 0x80;
}
bytes.push(temp);
} while (value !== 0);
return Buffer.from(bytes);
}
function encodeString(text) {
const stringBuffer = Buffer.from(text, 'utf8');
const lengthBuffer = encodeVarInt(stringBuffer.length);
return Buffer.concat([lengthBuffer, stringBuffer]);
}
// I also added code to track the buffer of the sent packet.
// this.compressor.on('data', (buffer) => {
// console.log(buffer)
// })
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the custom_click_action packet serialization and compare the write() output with the manually constructed buffer shown in the issue. Check how the nbt field length is encoded, then verify that the emitted packet contains the expected 0x1a length and is accepted by the server.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100