Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

custom_payload packet won't encode properly. #1256

Open
VenixPLL opened this issue Aug 26, 2023 · 8 comments
Open

custom_payload packet won't encode properly. #1256

VenixPLL opened this issue Aug 26, 2023 · 8 comments

Comments

@VenixPLL
Copy link

VenixPLL commented Aug 26, 2023

[ ] 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.

@extremeheat
Copy link
Member

What is schema for your custom_payload ?

@VenixPLL
Copy link
Author

VenixPLL commented Feb 12, 2024

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.

@wojtess
Copy link

wojtess commented Feb 12, 2024

@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"
            }
          ]
        ],

@rom1504
Copy link
Member

rom1504 commented Feb 12, 2024

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

@VenixPLL
Copy link
Author

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
Copy link
Author

VenixPLL commented Feb 26, 2024

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.

@IceTank
Copy link
Contributor

IceTank commented Feb 26, 2024

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.

@VenixPLL
Copy link
Author

VenixPLL commented Feb 26, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants