docs: update references to wiki.vg

wiki.vg has been shut down and is in the process of being merged into minecraft.wiki
This commit is contained in:
Timofey Gelazoniya 2024-12-28 22:47:11 +03:00
parent 838ffc497a
commit 9469564736
Signed by: zeldon
GPG Key ID: 047886915281DD2A
4 changed files with 333 additions and 306 deletions

View File

@ -1,12 +1,12 @@
/**
* Implementation of the RakNet ping/pong protocol.
* @see https://wiki.vg/Raknet_Protocol
* @see https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Raknet_Protocol
*/
'use strict';
"use strict";
import dgram from 'node:dgram';
import crypto from 'node:crypto'
import dgram from "node:dgram";
import crypto from "node:crypto";
const MAGIC = "00ffff00fefefefefdfdfdfd12345678";
const START_TIME = new Date().getTime();
@ -15,7 +15,7 @@ const START_TIME = new Date().getTime();
* Creates an Unconnected Ping packet.
* @param {number} pingId
* @returns {Buffer}
* @see {@link https://wiki.vg/Raknet_Protocol#Unconnected_Ping}
* @see {@link https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Raknet_Protocol#Unconnected_Ping}
*/
const createUnconnectedPingFrame = (timestamp) => {
const buffer = Buffer.alloc(33);
@ -30,15 +30,19 @@ const createUnconnectedPingFrame = (timestamp) => {
* Extract Modt from Unconnected Pong Packet and convert to an object
* @param {Buffer} unconnectedPongPacket
* @returns {Object}
* @see {@link https://wiki.vg/Raknet_Protocol#Unconnected_Pong}
* @see {@link https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Raknet_Protocol#Unconnected_Pong}
*/
const extractModt = (unconnectedPongPacket) => {
// Skip everything to Modt
const offset = 33;
const length = unconnectedPongPacket.readUInt16BE(offset);
let modt = unconnectedPongPacket.toString("utf-8", offset + 2, offset + 2 + length);
let modt = unconnectedPongPacket.toString(
"utf-8",
offset + 2,
offset + 2 + length
);
const components = modt.split(';');
const components = modt.split(";");
const parsedComponents = {
edition: components[0],
name: components[1],
@ -48,11 +52,11 @@ const extractModt = (unconnectedPongPacket) => {
},
players: {
online: Number(components[4]),
max: Number(components[5])
max: Number(components[5]),
},
serverId: components[6],
mapName: components[7],
gameMode: components[8]
gameMode: components[8],
};
return parsedComponents;
@ -66,12 +70,12 @@ const extractModt = (unconnectedPongPacket) => {
* @param {number} [timeout=5000] - The timeout duration in milliseconds.
*/
const ping = (host, port = 19132, cb, timeout = 5000) => {
const socket = dgram.createSocket('udp4');
const socket = dgram.createSocket("udp4");
// Set manual timeout interval.
// This ensures the connection will NEVER hang regardless of internal state
const timeoutTask = setTimeout(() => {
socket.emit('error', new Error('Socket timeout'));
socket.emit("error", new Error("Socket timeout"));
}, timeout);
const closeSocket = () => {
@ -104,7 +108,7 @@ const ping = (host, port = 19132, cb, timeout = 5000) => {
handleError(err);
}
socket.on('message', (pongPacket) => {
socket.on("message", (pongPacket) => {
const id = pongPacket[0];
switch (id) {
@ -116,13 +120,13 @@ const ping = (host, port = 19132, cb, timeout = 5000) => {
}
default: {
handleError(new Error('Received unexpected packet'));
handleError(new Error("Received unexpected packet"));
break;
}
}
});
socket.on('error', handleError);
socket.on("error", handleError);
};
/**
@ -133,13 +137,18 @@ const ping = (host, port = 19132, cb, timeout = 5000) => {
* @returns {Promise<import('../types/index.js').BedrockPingResponse>}
*/
export const pingBedrock = (host, options = {}) => {
if (!host) throw new Error('Host argument is not provided');
if (!host) throw new Error("Host argument is not provided");
const { port = 19132, timeout = 5000 } = options;
return new Promise((resolve, reject) => {
ping(host, port, (res, err) => {
ping(
host,
port,
(res, err) => {
err ? reject(err) : resolve(res);
}, timeout);
},
timeout
);
});
};

View File

@ -1,12 +1,12 @@
/**
* Implementation of the Java Minecraft ping protocol.
* @see https://wiki.vg/Server_List_Ping
* @see https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Server_List_Ping
*/
'use strict';
"use strict";
import net from 'node:net';
import varint from './varint.js';
import net from "node:net";
import varint from "./varint.js";
/**
* Ping a Minecraft Java server.
@ -17,12 +17,12 @@ import varint from './varint.js';
* @param {number} [protocolVersion=-1] The protocol version of the Java client.
*/
function ping(host, port = 25565, cb, timeout = 5000, protocolVersion = -1) {
const socket = net.createConnection(({ host, port }));
const socket = net.createConnection({ host, port });
// Set manual timeout interval.
// This ensures the connection will NEVER hang regardless of internal state
const timeoutTask = setTimeout(() => {
socket.emit('error', new Error('Socket timeout'));
socket.emit("error", new Error("Socket timeout"));
}, timeout);
const closeSocket = () => {
@ -52,34 +52,32 @@ function ping(host, port = 25565, cb, timeout = 5000, protocolVersion = -1) {
// This prevents the runtime from delaying the write at all
socket.setNoDelay(true);
socket.on('connect', () => {
socket.on("connect", () => {
const handshake = varint.concat([
varint.encodeInt(0),
varint.encodeInt(protocolVersion),
varint.encodeInt(host.length),
varint.encodeString(host),
varint.encodeUShort(port),
varint.encodeInt(1)
varint.encodeInt(1),
]);
socket.write(handshake);
const request = varint.concat([
varint.encodeInt(0)
]);
const request = varint.concat([varint.encodeInt(0)]);
socket.write(request);
});
let incomingBuffer = Buffer.alloc(0);
socket.on('data', (data) => {
socket.on("data", (data) => {
incomingBuffer = Buffer.concat([incomingBuffer, data]);
// Wait until incomingBuffer is at least 5 bytes long to ensure it has captured the first VarInt value
// This value is used to determine the full read length of the response
// "VarInts are never longer than 5 bytes"
// https://wiki.vg/Data_types#VarInt_and_VarLong
// https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Data_types#VarInt_and_VarLong
if (incomingBuffer.length < 5) {
return;
}
@ -92,12 +90,20 @@ function ping(host, port = 25565, cb, timeout = 5000, protocolVersion = -1) {
return;
}
const packetId = varint.decodeInt(incomingBuffer, varint.decodeLength(packetLength));
const packetId = varint.decodeInt(
incomingBuffer,
varint.decodeLength(packetLength)
);
if (packetId === 0) {
const data = incomingBuffer.subarray(varint.decodeLength(packetLength) + varint.decodeLength(packetId));
const data = incomingBuffer.subarray(
varint.decodeLength(packetLength) + varint.decodeLength(packetId)
);
const responseLength = varint.decodeInt(data, 0);
const response = data.subarray(varint.decodeLength(responseLength), varint.decodeLength(responseLength) + responseLength);
const response = data.subarray(
varint.decodeLength(responseLength),
varint.decodeLength(responseLength) + responseLength
);
try {
const message = JSON.parse(response);
@ -108,11 +114,11 @@ function ping(host, port = 25565, cb, timeout = 5000, protocolVersion = -1) {
handleError(err);
}
} else {
handleError(new Error('Received unexpected packet'));
handleError(new Error("Received unexpected packet"));
}
});
socket.on('error', handleError);
socket.on("error", handleError);
}
/**
@ -123,13 +129,19 @@ function ping(host, port = 25565, cb, timeout = 5000, protocolVersion = -1) {
* @returns {Promise<import('../types/index.js').JavaPingResponse>}
*/
export function pingJava(host, options = {}) {
if (!host) throw new Error('Host argument is not provided');
if (!host) throw new Error("Host argument is not provided");
const { port = 25565, timeout = 5000, protocolVersion = -1 } = options;
return new Promise((resolve, reject) => {
ping(host, port, (res, err) => {
ping(
host,
port,
(res, err) => {
err ? reject(err) : resolve(res);
}, timeout, protocolVersion);
},
timeout,
protocolVersion
);
});
}

View File

@ -1,4 +1,4 @@
// https://wiki.vg/Data_types
// https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol#Data_types
/**
* A utility object for encoding and decoding varints.
@ -10,13 +10,13 @@ const varint = {
* @returns {Buffer}
*/
encodeInt: (val) => {
// "constInts are never longer than 5 bytes"
// https://wiki.vg/Data_types#constInt_and_constLong
// "VarInts are never longer than 5 bytes"
// https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Data_types#VarInt_and_VarLong
const buf = Buffer.alloc(5);
let written = 0;
while (true) {
const byte = val & 0x7F;
const byte = val & 0x7f;
val >>>= 7;
if (val === 0) {
@ -36,7 +36,7 @@ const varint = {
* @returns {Buffer}
*/
encodeString: (val) => {
return Buffer.from(val, 'utf-8');
return Buffer.from(val, "utf-8");
},
/**
@ -45,7 +45,7 @@ const varint = {
* @returns {Buffer}
*/
encodeUShort: (val) => {
return Buffer.from([val >> 8, val & 0xFF]);
return Buffer.from([val >> 8, val & 0xff]);
},
/**
@ -60,10 +60,7 @@ const varint = {
length += chunk.length;
}
const buffer = [
varint.encodeInt(length),
...chunks
];
const buffer = [varint.encodeInt(length), ...chunks];
return Buffer.concat(buffer);
},
@ -81,7 +78,7 @@ const varint = {
while (true) {
const byte = buffer.readUInt8(offset++);
val |= (byte & 0x7F) << count++ * 7;
val |= (byte & 0x7f) << (count++ * 7);
if ((byte & 0x80) !== 0x80) {
break;
@ -109,19 +106,26 @@ const varint = {
const N9 = Math.pow(2, 63);
// Return the number of bytes required based on the value
return (
val < N1 ? 1
: val < N2 ? 2
: val < N3 ? 3
: val < N4 ? 4
: val < N5 ? 5
: val < N6 ? 6
: val < N7 ? 7
: val < N8 ? 8
: val < N9 ? 9
: 10
);
}
return val < N1
? 1
: val < N2
? 2
: val < N3
? 3
: val < N4
? 4
: val < N5
? 5
: val < N6
? 6
: val < N7
? 7
: val < N8
? 8
: val < N9
? 9
: 10;
},
};
export default varint;

16
types/lib/java.d.ts vendored
View File

@ -4,14 +4,14 @@
* @param protocolVersion The protocol version.
*/
export type JavaPingOptions = {
port?: number | undefined,
timeout?: number | undefined,
port?: number | undefined;
timeout?: number | undefined;
protocolVersion?: number | undefined;
};
/**
* JSON format chat component used for description field.
* @see https://wiki.vg/Chat
* @see https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Chat
*/
export type ChatComponent = {
text: string;
@ -25,13 +25,13 @@ export type ChatComponent = {
};
export type SampleProp = {
name: string,
name: string;
id: string;
};
/**
* `JSON Response` field of Response packet.
* @see https://wiki.vg/Server_List_Ping#Response
* @see https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Server_List_Ping#Status_Response
*/
export type JavaPingResponse = {
version: {
@ -76,5 +76,7 @@ export type JavaPingResponse = {
* ```
* @see [source](https://github.com/minescope/mineping/blob/915edbec9c9ad811459458600af3531ec0836911/lib/java.js#L117)
*/
export function pingJava(host: string, options?: JavaPingOptions): Promise<JavaPingResponse>;
export function pingJava(
host: string,
options?: JavaPingOptions
): Promise<JavaPingResponse>;