PrismarineJS / PrismarineJS/node-minecraft-protocol

"Chunk size is 42 but only 2 was read" error

Open
#1,279 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

possible bug
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.45.0
  • server: vanilla/all version
  • node: 20.5.1

Detailed description of a problem

Missing characters in string, found size is 3 expected size was 50
The error got in Minecraft: Internal Exception: io.netty.handler.codec.DecoderException: net.minecraft.class_8911: Loading NBT data.
The error is random and I am failing to debug or reproduce.
Full error:

PartialReadError: Read error for undefined : Missing characters in string, found size is 3 expected size was 50
    at new ExtendableError (/root/QbastyBots/OpenAnarchy/node_modules/.pnpm/protodef@1.15.0/node_modules/protodef/src/utils.js:63:13)
    at new PartialReadError (/root/QbastyBots/OpenAnarchy/node_modules/.pnpm/protodef@1.15.0/node_modules/protodef/src/utils.js:70:5)
    at Object.string (eval at compile (/root/QbastyBots/OpenAnarchy/node_modules/.pnpm/protodef@1.15.0/node_modules/protodef/src/compiler.js:258:12), <anonymous>:91:15)
    at Object.packet_set_protocol (eval at compile (/root/QbastyBots/OpenAnarchy/node_modules/.pnpm/protodef@1.15.0/node_modules/protodef/src/compiler.js:258:12), <anonymous>:712:69)
    at eval (eval at compile (/root/QbastyBots/OpenAnarchy/node_modules/.pnpm/protodef@1.15.0/node_modules/protodef/src/compiler.js:258:12), <anonymous>:728:64)
    at packet (eval at compile (/root/QbastyBots/OpenAnarchy/node_modules/.pnpm/protodef@1.15.0/node_modules/protodef/src/compiler.js:258:12), <anonymous>:732:9)
    at CompiledProtodef.read (/root/QbastyBots/OpenAnarchy/node_modules/.pnpm/protodef@1.15.0/node_modules/protodef/src/compiler.js:70:12)
    at e.message (/root/QbastyBots/OpenAnarchy/node_modules/.pnpm/protodef@1.15.0/node_modules/protodef/src/compiler.js:111:49)
    at tryCatch (/root/QbastyBots/OpenAnarchy/node_modules/.pnpm/protodef@1.15.0/node_modules/protodef/src/utils.js:50:16)
    at CompiledProtodef.parsePacketBuffer (/root/QbastyBots/OpenAnarchy/node_modules/.pnpm/protodef@1.15.0/node_modules/protodef/src/compiler.js:111:29)
Chunk size is 42 but only 2 was read ; partial packet : {"name":96}; buffer :e00000000000436f6f6b69653a206d737473686173683d41646d696e697374720d0a0100080003000000
error: 02:01:2024|20:18:42:69108310 [object Object]

Current code

import sendLog from "./sendLog.js";
import requestMojang from "./requestMojang.js";
import { createServer } from "minecraft-protocol";
import { readFileSync } from "node:fs";
export default async function verifyServer(client) {
  const serverLogo = readFileSync("./images/server-icon.png", { encoding: "base64" });
  const { ip, port } = client.config.server;
  const server = createServer({
    host: ip,
    "online-mode": false,
    maxPlayers: new Date().getFullYear(),
    motd: client.config.server.motd,
    version: false,
    port: port,
    errorHandler: error => sendLog(error, client, 0),
    beforePing: response => {
      response.version.name = "";
      response.favicon = `data:image/png;base64,${serverLogo}`;
    },
  });
  sendLog(`[SERVER] Server started on ${ip}:${port}`, client, 1);
  server.on("login", async serverClient => {
    const code = await getCode(client, serverClient);
    serverClient.end(await codeCreatedMessage(client, code.code));
  });
}
async function getCode(client, serverClient) {
  const generateCode = () => Math.floor(1000 + Math.random() * 9000);
  const codeArray = (await client.db.get("codeArray")) || [];
  const currentDate = new Date();
  const validCodes = codeArray.filter(e => new Date(e.expiry) > currentDate);
  const { username } = serverClient;
  const existingCode = validCodes.find(e => e.username === username);
  let expiry;
  if (existingCode) {
    expiry = existingCode.expiry;
  } else {
    expiry = new Date(currentDate.getTime() + 5 * 60000);
    let code = generateCode();
    while (validCodes.some(e => e.code === code)) {
      code = generateCode();
    }
    const premium = (await requestMojang(username)) !== false;
    const time = formatUTCDate(expiry);
    const channel = client.channels.cache.get(client.config.discord.channel.logs);
    sendLog(
      `[SERVER] ${serverClient.username} has been given the code ${code} which expires at ${time}.`,
      client,
      1
    );
    await channel.send(
      `**${serverClient.username}** has been given the code **${code}** which expires at **${time}**.`
    );
    const newCode = { username, code, expiry, premium };
    await client.db.set("codeArray", [...validCodes, newCode]);
    return newCode;
  }
  await client.db.set("codeArray", validCodes);
  return existingCode;
}
function formatUTCDate(date) {
  const hours = date.getUTCHours();
  const minutes = date.getUTCMinutes();
  const ampm = hours >= 12 ? "PM" : "AM";
  const displayHours = hours % 12 || 12;
  return `${displayHours}:${String(minutes).padStart(2, "0")} ${ampm} (UTC)`;
}
const formatTime = milliseconds => {
  const seconds = Math.floor(milliseconds / 1000);
  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  const remainingSeconds = seconds % 60;
  const timeParts = [];
  if (hours > 0) timeParts.push(`${hours} ${hours === 1 ? "hour" : "hours"}`);
  if (minutes > 0) timeParts.push(`${minutes} ${minutes === 1 ? "minute" : "minutes"}`);
  if (remainingSeconds > 0 || (hours === 0 && minutes === 0)) {
    timeParts.push(`${remainingSeconds} ${remainingSeconds === 1 ? "second" : "seconds"}`);
  }
  return timeParts.join(", ");
};
const codeCreatedMessage = async (client, code) => {
  const codeArray = (await client.db.get("codeArray")) || [];
  const entry = codeArray.find(e => e.code === code);
  if (entry) {
    const expiry = new Date(entry.expiry);
    if (expiry instanceof Date) {
      const remainingTime = Math.max(0, expiry.getTime() - Date.now());
      const { title, lineone, linetwo, linethree, lineaftertime } = client.config.server;
      return `${title}\n\n${lineone}${code}\n\n${linetwo}#${
        client.channels.cache.get(client.config.discord.channel.verification)?.name
      }\n${linethree}${formatTime(remainingTime)}${lineaftertime}`;
    } else {
      const { title, linerror } = client.config.server;
      return `${title}\n\n${linerror}`;
    }
  } else {
    const { title, linerror } = client.config.server;
    return `${title}\n\n${linerror}`;
  }
};

Expected behavior

It should work normally without errors.

Additional context

Add any other context about the problem here.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No repository file or test is identified; start with the supplied createServer configuration, packet buffer, and stack trace through node_modules/protodef/src/compiler.js. Try to reproduce the intermittent packet 96 parsing failure with the stated Minecraft, Node, and minecraft-protocol versions, then define done as the same connection completing without PartialReadError.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
backend, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
18/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.