minecraft-core-master
Version:
Núcleo avanzado para launchers de Minecraft. Descarga, instala y ejecuta versiones de Minecraft, assets, librerías, Java y loaders de forma automática y eficiente.
134 lines (133 loc) • 4.31 kB
JavaScript
import net from "net";
export class CustomBuffer {
buffer;
offsetValue = 0;
constructor(existingBuffer = Buffer.alloc(48)) {
this.buffer = existingBuffer;
}
writeVarInt(val) {
while (true) {
if ((val & 0xFFFFFF80) === 0)
return this.writeUByte(val);
this.writeUByte((val & 0x7F) | 0x80);
val >>>= 7;
}
}
readVarInt() {
let val = 0;
let count = 0;
let byte;
do {
if (count > 5)
throw new Error("VarInt is too big");
byte = this.buffer.readUInt8(this.offsetValue++);
val |= (byte & 0x7F) << (7 * count++);
} while ((byte & 0x80) !== 0);
return val;
}
writeString(str) {
const bytes = Buffer.from(str, "utf-8");
this.writeVarInt(bytes.length);
this.ensureCapacity(bytes.length);
bytes.copy(this.buffer, this.offsetValue);
this.offsetValue += bytes.length;
}
readString() {
const length = this.readVarInt();
if (this.offsetValue + length > this.buffer.length)
throw new Error("Buffer overflow");
const str = this.buffer.toString("utf-8", this.offsetValue, this.offsetValue + length);
this.offsetValue += length;
return str;
}
writeUShort(val) {
this.writeUByte((val >> 8) & 0xFF);
this.writeUByte(val & 0xFF);
}
writeUByte(val) {
this.ensureCapacity(1);
this.buffer.writeUInt8(val, this.offsetValue++);
}
bufferSlice() {
return this.buffer.slice(0, this.offsetValue);
}
offset() {
return this.offsetValue;
}
ensureCapacity(additional) {
if (this.offsetValue + additional > this.buffer.length) {
this.buffer = Buffer.concat([this.buffer, Buffer.alloc(Math.max(additional, 50))]);
}
}
}
export function writePCBuffer(client, buffer) {
const lengthBuffer = new CustomBuffer();
lengthBuffer.writeVarInt(buffer.bufferSlice().length);
client.write(Buffer.concat([lengthBuffer.bufferSlice(), buffer.bufferSlice()]));
}
export async function ping(server, port, timeout = 3000, protocol = '754') {
return new Promise((resolve, reject) => {
const start = Date.now();
const socket = net.connect({ host: server, port }, () => {
const handshake = new CustomBuffer();
handshake.writeVarInt(0);
handshake.writeVarInt(Number(protocol));
handshake.writeString(server);
handshake.writeUShort(port);
handshake.writeVarInt(1);
writePCBuffer(socket, handshake);
const request = new CustomBuffer();
request.writeVarInt(0);
writePCBuffer(socket, request);
});
socket.setTimeout(timeout, () => {
reject(new Error(`Socket timed out connecting to ${server}:${port}`));
socket.destroy();
});
let readingBuffer = Buffer.alloc(0);
socket.on("data", (data) => {
readingBuffer = Buffer.concat([readingBuffer, data]);
const buffer = new CustomBuffer(readingBuffer);
let length;
try {
length = buffer.readVarInt();
}
catch {
return;
}
if (readingBuffer.length < length - buffer.offset())
return;
buffer.readVarInt();
try {
const json = JSON.parse(buffer.readString());
resolve({
ms: Date.now() - start,
version: json.version.name,
playersConnect: json.players.online,
playersMax: json.players.max
});
}
catch (err) {
reject(err);
}
finally {
socket.destroy();
}
});
socket.once("error", (err) => {
reject(err);
socket.destroy();
});
});
}
export class Status {
ip;
port;
constructor(ip = "0.0.0.0", port = 25565) {
this.ip = ip;
this.port = port;
}
async getStatus() {
return ping(this.ip, this.port, 3000);
}
}