node-minecraft-protocol icon indicating copy to clipboard operation
node-minecraft-protocol copied to clipboard

custom_payload packet won't encode properly.

Open VenixPLL opened this issue 1 year ago • 8 comments

[ ] The FAQ doesn't contain a resolution to my issue

Versions

Detailed description of a problem

A clear and concise description of what the problem is.

node-protocol cannot convert json -> byte from generated json custom_payload packet cannot be encoded back from json.

Current code

const { createDeserializer, createSerializer } = require('minecraft-protocol');

const serializerMap = new Map();
const deserializerMap = new Map();

function getOrCreateSerializer(state, version, isServer) {
  const key = `${state}_${version}_${isServer}`;
  if (!serializerMap.has(key)) {
    serializerMap.set(key, createSerializer({ state, version, isServer }));
  }
  return serializerMap.get(key);
}

function getOrCreateDeserializer(state, version, isServer) {
  const key = `${state}_${version}_${isServer}`;
  if (!deserializerMap.has(key)) {
    deserializerMap.set(key, createDeserializer({ state, version, isServer }));
  }
  return deserializerMap.get(key);
}

function convertObjectToBuffer(state, version, json, isServer) {
  const serializer = getOrCreateSerializer(state, version, isServer);

  const data = serializer.createPacketBuffer(JSON.parse(json));
  const arrByte = Uint8Array.from(data);

  return arrByte;
}

function convertBufferToObject(state, version, buffer, isServer) {
  const buf = Buffer.from(buffer);
  const deserializer = getOrCreateDeserializer(state, version, isServer);
  const data = deserializer.parsePacketBuffer(buf).data;
  const out = JSON.stringify(data);

  return out;
}

const chat = [3,8,116,101,115,116,32,97,115,100]
const positionlook = [18,0,0,0,0,0,0,0,0,64,87,64,0,0,0,0,0,0,0,0,0,0,0,0,0,-61,94,13,127,-65,-78,-14,-85,1]
const payload = [10,15,109,105,110,101,99,114,97,102,116,58,98,114,97,110,100,7,118,97,110,105,108,108,97]

console.log("Testing Chat");
testLibrary(chat);
console.log("Testing PositionLook");
testLibrary(positionlook);
console.log("Testing Payload");
testLibrary(payload);

function testLibrary(array) {
    const decodedData = convertBufferToObject('play', '1.18.2', array, true);
    console.log(decodedData);

    const payloadData = convertObjectToBuffer('play', '1.18.2', decodedData, false);
    console.log(payloadData);

    console.log("Done!");
}

Expected behavior

custom_payload should be converted back to Buffer

Behavior i got

Throws error when encoding custom_payload

Testing Payload {"name":"custom_payload","params":{"channel":"minecraft:brand","data":{"type":"Buffer","data":[7,118,97,110,105,108,108,97]}}} node:buffer:404 throw new ERR_INVALID_ARG_VALUE.RangeError('size', size); ^

RangeError [ERR_INVALID_ARG_VALUE]: The argument 'size' is invalid. Received NaN

Additional Context

All other packets including chunk/declare command/positions works, only custom_payload is affected.

VenixPLL avatar Aug 26 '23 14:08 VenixPLL

What is schema for your custom_payload ?

extremeheat avatar Dec 27 '23 02:12 extremeheat

What is schema for your custom_payload ?

Everything you need is in the code above, node-mc-protocol should be able to re-encode packets generated by itself node-mc-protocol is able to decode that packet from bytes but it is unable to parse it back into bytes.

VenixPLL avatar Feb 12 '24 17:02 VenixPLL

@extremeheat https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.17/protocol.json#L4949

          "container",
          [
            {
              "name": "channel",
              "type": "string"
            },
            {
              "name": "data",
              "type": "restBuffer"
            }
          ]
        ],

wojtess avatar Feb 12 '24 17:02 wojtess

const out = JSON.stringify(data); this is the bug

rom1504 avatar Feb 12 '24 20:02 rom1504

const out = JSON.stringify(data); this is the bug So with what you would replace it. If that's the bug, all packets encode properly using it even chunk packets, and custompayload od having a problem.

VenixPLL avatar Feb 22 '24 11:02 VenixPLL

So you cant just send custom_payloads with node-protocol? Creating a handmade test json of a packet that is valid by looking at minecraft-data specifications

Direction: SERVERBOUND (does not matter, both ways) ConnectionState: PLAY Version: 1.18.2, (does not matter)

{"name":"custom_payload","params":{"channel":"minecraft:brand","data":{"type":"Buffer","data":[1,2,3,4,5,6,7,8,9,10]}}}

And it can't even encode that, lemme remind you that chunk packets that are full of buffers are encoding correctly without problems, only that custom_payload is throwing some weird errors. RangeError [ERR_INVALID_ARG_VALUE]: The argument 'size' is invalid. Received NaN

is there something that i am missing? i would like to use this library alone without the need for entire mineflayer, that works perfectly fine in mineflayer but alone it isnt That issue is hanging there for too long.

VenixPLL avatar Feb 26 '24 13:02 VenixPLL

Did you try this example? https://github.com/PrismarineJS/node-minecraft-protocol/blob/master/examples%2Fclient_custom_channel%2Fclient_custom_channel.js

Custom payload is a protodef protocol encoded payload. After registration, node minecraft protocol will try to parse registered custom channel messages. But you can just keep the protocol as a string like in the example. And parse the payload as json. I dont think Node minecraft protocol can parse json by itself.

IceTank avatar Feb 26 '24 14:02 IceTank

so if i wanted to make a proxy where i handle all that connecting stuff and just use protocol to decode/encode packets, is there any way i can register that channel? without using client/server, decoding works so i would be able to register it before i send anything. All that to make it work in the example code in the issue.

VenixPLL avatar Feb 26 '24 14:02 VenixPLL