mirror of
https://github.com/WorldEditAxe/eaglerproxy.git
synced 2024-11-08 06:56:03 -08:00
Remove precompiled .js files
This commit is contained in:
parent
37638f2f33
commit
9965b1370e
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
node_modules
|
||||
insecureSocks
|
||||
insecureSocks
|
||||
build
|
|
@ -1,2 +0,0 @@
|
|||
export class ProxiedPlayer {
|
||||
}
|
19
config.js
19
config.js
|
@ -1,19 +0,0 @@
|
|||
export const config = {
|
||||
name: "BasedProxy",
|
||||
port: 80,
|
||||
maxPlayers: 20,
|
||||
motd: {
|
||||
iconURL: null,
|
||||
l1: "hi",
|
||||
l2: "lol"
|
||||
},
|
||||
server: {
|
||||
host: "127.0.0.1",
|
||||
port: 25565
|
||||
},
|
||||
security: {
|
||||
enabled: false,
|
||||
key: null,
|
||||
cert: null
|
||||
}
|
||||
};
|
|
@ -1,22 +0,0 @@
|
|||
export var EaglerPacketId;
|
||||
(function (EaglerPacketId) {
|
||||
EaglerPacketId[EaglerPacketId["IDENTIFY_CLIENT"] = 1] = "IDENTIFY_CLIENT";
|
||||
EaglerPacketId[EaglerPacketId["IDENTIFY_SERVER"] = 2] = "IDENTIFY_SERVER";
|
||||
EaglerPacketId[EaglerPacketId["LOGIN"] = 4] = "LOGIN";
|
||||
EaglerPacketId[EaglerPacketId["LOGIN_ACK"] = 5] = "LOGIN_ACK";
|
||||
EaglerPacketId[EaglerPacketId["SKIN"] = 7] = "SKIN";
|
||||
EaglerPacketId[EaglerPacketId["C_READY"] = 8] = "C_READY";
|
||||
EaglerPacketId[EaglerPacketId["COMPLETE_HANDSHAKE"] = 9] = "COMPLETE_HANDSHAKE";
|
||||
EaglerPacketId[EaglerPacketId["DISCONNECT"] = 255] = "DISCONNECT";
|
||||
})(EaglerPacketId || (EaglerPacketId = {}));
|
||||
export var DisconnectReason;
|
||||
(function (DisconnectReason) {
|
||||
DisconnectReason[DisconnectReason["UNEXPECTED_PACKET"] = 1] = "UNEXPECTED_PACKET";
|
||||
DisconnectReason[DisconnectReason["DUPLICATE_USERNAME"] = 2] = "DUPLICATE_USERNAME";
|
||||
DisconnectReason[DisconnectReason["BAD_USERNAME"] = 3] = "BAD_USERNAME";
|
||||
DisconnectReason[DisconnectReason["SERVER_DISCONNECT"] = 4] = "SERVER_DISCONNECT";
|
||||
DisconnectReason[DisconnectReason["CUSTOM"] = 8] = "CUSTOM";
|
||||
})(DisconnectReason || (DisconnectReason = {}));
|
||||
export const MAGIC_BUILTIN_SKIN_BYTES = [0x00, 0x05, 0x01, 0x00, 0x00, 0x00];
|
||||
export const MAGIC_ENDING_IDENTIFYS_BYTES = [0x00, 0x00, 0x00];
|
||||
// Afterwards, forward 0x01 (Join Game, Clientbound) and everything after that
|
67
index.js
67
index.js
|
@ -1,67 +0,0 @@
|
|||
import { readFileSync } from "fs";
|
||||
import * as https from "https";
|
||||
import { WebSocketServer } from "ws";
|
||||
import { ProxiedPlayer } from "./classes.js";
|
||||
import { config } from "./config.js";
|
||||
import { handlePacket } from "./listener.js";
|
||||
import { Logger } from "./logger.js";
|
||||
import { BRANDING, NETWORK_VERSION, VERSION } from "./meta.js";
|
||||
import { State } from "./types.js";
|
||||
import { genUUID } from "./utils.js";
|
||||
const logger = new Logger("EagXProxy");
|
||||
const connectionLogger = new Logger("ConnectionHandler");
|
||||
global.PROXY = {
|
||||
brand: BRANDING,
|
||||
version: VERSION,
|
||||
MOTDVersion: NETWORK_VERSION,
|
||||
serverName: config.name,
|
||||
secure: false,
|
||||
proxyUUID: genUUID(config.name),
|
||||
MOTD: {
|
||||
icon: null,
|
||||
motd: [config.motd.l1, config.motd.l2]
|
||||
},
|
||||
playerStats: {
|
||||
max: config.maxPlayers,
|
||||
onlineCount: 0
|
||||
},
|
||||
wsServer: null,
|
||||
players: new Map(),
|
||||
logger: logger,
|
||||
config: config
|
||||
};
|
||||
PROXY.playerStats.onlineCount = PROXY.players.size;
|
||||
let server;
|
||||
if (PROXY.config.security.enabled) {
|
||||
logger.info(`Starting SECURE WebSocket proxy on port ${config.port}...`);
|
||||
if (process.env.REPL_SLUG) {
|
||||
logger.warn("You appear to be running the proxy on Repl.it with encryption enabled. Please note that Repl.it by default provides encryption, and enabling encryption may or may not prevent you from connecting to the server.");
|
||||
}
|
||||
server = new WebSocketServer({
|
||||
server: https.createServer({
|
||||
key: readFileSync(config.security.key),
|
||||
cert: readFileSync(config.security.cert)
|
||||
}).listen(config.port)
|
||||
});
|
||||
}
|
||||
else {
|
||||
logger.info(`Starting INSECURE WebSocket proxy on port ${config.port}...`);
|
||||
server = new WebSocketServer({
|
||||
port: config.port
|
||||
});
|
||||
}
|
||||
PROXY.wsServer = server;
|
||||
server.addListener('connection', c => {
|
||||
connectionLogger.debug(`[CONNECTION] New inbound WebSocket connection from [/${c._socket.remoteAddress}:${c._socket.remotePort}]. (${c._socket.remotePort} -> ${config.port})`);
|
||||
const plr = new ProxiedPlayer();
|
||||
plr.ws = c;
|
||||
plr.ip = c._socket.remoteAddress;
|
||||
plr.remotePort = c._socket.remotePort;
|
||||
plr.state = State.PRE_HANDSHAKE;
|
||||
c.on('message', msg => {
|
||||
handlePacket(msg, plr);
|
||||
});
|
||||
});
|
||||
server.on('listening', () => {
|
||||
logger.info(`Successfully started${config.security.enabled ? " [secure]" : ""} WebSocket proxy on port ${config.port}!`);
|
||||
});
|
26
listener.js
26
listener.js
|
@ -1,26 +0,0 @@
|
|||
import { Logger } from "./logger.js";
|
||||
import { handleMotd } from "./motd.js";
|
||||
import { State } from "./types.js";
|
||||
import { doHandshake } from "./utils.js";
|
||||
const logger = new Logger("PacketHandler");
|
||||
export function handlePacket(packet, client) {
|
||||
if (client.state == State.PRE_HANDSHAKE) {
|
||||
if (packet.toString() === "Accept: MOTD") {
|
||||
handleMotd(client);
|
||||
}
|
||||
else if (!client._handled) {
|
||||
;
|
||||
client._handled = true;
|
||||
doHandshake(client, packet);
|
||||
}
|
||||
}
|
||||
else if (client.state == State.POST_HANDSHAKE) {
|
||||
if (!client.remoteConnection || client.remoteConnection.socket.closed) {
|
||||
logger.warn(`Player ${client.username} is marked as post handshake, but is disconnected from the game server? Disconnecting due to illegal state.`);
|
||||
client.ws.close();
|
||||
}
|
||||
else {
|
||||
client.remoteConnection.writeRaw(packet);
|
||||
}
|
||||
}
|
||||
}
|
54
logger.js
54
logger.js
|
@ -1,54 +0,0 @@
|
|||
import { Chalk } from "chalk";
|
||||
const color = new Chalk({ level: 2 });
|
||||
let global_verbose = false;
|
||||
export function verboseLogging(newVal) {
|
||||
global_verbose = (newVal !== null && newVal !== void 0 ? newVal : global_verbose) ? false : true;
|
||||
}
|
||||
function jsonLog(type, message) {
|
||||
return JSON.stringify({
|
||||
type: type,
|
||||
message: message
|
||||
}) + "\n";
|
||||
}
|
||||
export class Logger {
|
||||
constructor(name, verbose) {
|
||||
this.jsonLog = process.argv.includes("--json") || process.argv.includes("-j");
|
||||
this.loggerName = name;
|
||||
if (verbose)
|
||||
this.verbose = verbose;
|
||||
else
|
||||
this.verbose = global_verbose;
|
||||
}
|
||||
info(s) {
|
||||
if (!this.jsonLog)
|
||||
process.stdout.write(`${color.green("I")} ${color.gray(new Date().toISOString())} ${color.reset(`${color.yellow(`${this.loggerName}:`)} ${s}`)}\n`);
|
||||
else
|
||||
process.stdout.write(jsonLog("info", s));
|
||||
}
|
||||
warn(s) {
|
||||
if (!this.jsonLog)
|
||||
process.stdout.write(`${color.yellow("W")} ${color.gray(new Date().toISOString())} ${color.yellow(`${color.yellow(`${this.loggerName}:`)} ${s}`)}\n`);
|
||||
else
|
||||
process.stderr.write(jsonLog("warn", s));
|
||||
}
|
||||
error(s) {
|
||||
if (!this.jsonLog)
|
||||
process.stderr.write(`* ${color.red("E")} ${color.gray(new Date().toISOString())} ${color.redBright(`${color.red(`${this.loggerName}:`)} ${s}`)}\n`);
|
||||
else
|
||||
process.stderr.write(jsonLog("error", s));
|
||||
}
|
||||
fatal(s) {
|
||||
if (!this.jsonLog)
|
||||
process.stderr.write(`** ${color.red("F!")} ${color.gray(new Date().toISOString())} ${color.bgRedBright(color.redBright(`${color.red(`${this.loggerName}:`)} ${s}`))}\n`);
|
||||
else
|
||||
process.stderr.write(jsonLog("fatal", s));
|
||||
}
|
||||
debug(s) {
|
||||
if (this.verbose || global_verbose) {
|
||||
if (!this.jsonLog)
|
||||
process.stderr.write(`${color.gray("D")} ${color.gray(new Date().toISOString())} ${color.gray(`${color.gray(`${this.loggerName}:`)} ${s}`)}\n`);
|
||||
else
|
||||
process.stderr.write(jsonLog("debug", s));
|
||||
}
|
||||
}
|
||||
}
|
3
meta.js
3
meta.js
|
@ -1,3 +0,0 @@
|
|||
export const BRANDING = Object.freeze("EaglerXProxy");
|
||||
export const VERSION = "1.0.0";
|
||||
export const NETWORK_VERSION = Object.freeze(BRANDING + "/" + VERSION);
|
34
motd.js
34
motd.js
|
@ -1,34 +0,0 @@
|
|||
export function handleMotd(player) {
|
||||
const names = [];
|
||||
for (const [username, player] of PROXY.players) {
|
||||
if (names.length > 0) {
|
||||
names.push(`(and ${PROXY.players.size - names.length} more)`);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
names.push(username);
|
||||
}
|
||||
}
|
||||
player.ws.send(JSON.stringify({
|
||||
brand: PROXY.brand,
|
||||
cracked: true,
|
||||
data: {
|
||||
cache: true,
|
||||
icon: PROXY.MOTD.icon ? true : false,
|
||||
max: PROXY.playerStats.max,
|
||||
motd: PROXY.MOTD.motd,
|
||||
online: PROXY.playerStats.onlineCount,
|
||||
players: names
|
||||
},
|
||||
name: PROXY.serverName,
|
||||
secure: false,
|
||||
time: Date.now(),
|
||||
type: "motd",
|
||||
uuid: PROXY.proxyUUID,
|
||||
vers: PROXY.MOTDVersion
|
||||
}));
|
||||
if (PROXY.MOTD.icon) {
|
||||
player.ws.send(PROXY.MOTD.icon);
|
||||
}
|
||||
player.ws.close();
|
||||
}
|
6
types.js
6
types.js
|
@ -1,6 +0,0 @@
|
|||
export var State;
|
||||
(function (State) {
|
||||
State[State["PRE_HANDSHAKE"] = 0] = "PRE_HANDSHAKE";
|
||||
State[State["POST_HANDSHAKE"] = 1] = "POST_HANDSHAKE";
|
||||
State[State["DISCONNECTED"] = 2] = "DISCONNECTED";
|
||||
})(State || (State = {}));
|
229
utils.js
229
utils.js
|
@ -1,229 +0,0 @@
|
|||
import { v3 } from "uuid";
|
||||
import { encodeULEB128 as encodeVarInt, decodeULEB128 as decodeVarInt, decodeSLEB128 as decodeSVarInt } from "@thi.ng/leb128";
|
||||
import { DisconnectReason, EaglerPacketId, MAGIC_ENDING_IDENTIFYS_BYTES } from "./eaglerPacketDef.js";
|
||||
import { Logger } from "./logger.js";
|
||||
import { State } from "./types.js";
|
||||
import { toBuffer } from "uuid-buffer";
|
||||
import * as mc from "minecraft-protocol";
|
||||
import { config } from "./config.js";
|
||||
const MAGIC_UUID = "a7e774bc-7ea4-11ed-9a58-1f9e14304a59";
|
||||
const logger = new Logger("LoginHandler");
|
||||
const USERNAME_REGEX = /[^0-9^a-z^A-Z^_]/gi;
|
||||
export function genUUID(user) {
|
||||
return v3(user, MAGIC_UUID);
|
||||
}
|
||||
export function bufferizeUUID(uuid) {
|
||||
return toBuffer(uuid);
|
||||
}
|
||||
export function validateUsername(user) {
|
||||
if (user.length > 20)
|
||||
throw new Error("Username is too long!");
|
||||
if (!!user.match(USERNAME_REGEX))
|
||||
throw new Error("Invalid username. Username can only contain alphanumeric characters, and the underscore (_) character.");
|
||||
}
|
||||
export function disconnect(player, message, code) {
|
||||
if (player.state == State.POST_HANDSHAKE) {
|
||||
const messageLen = encodeVarInt(message.length);
|
||||
const d = Buffer.alloc(1 + messageLen.length + message.length);
|
||||
d.set([0x40, ...messageLen, ...Buffer.from(message)]);
|
||||
player.ws.send(d);
|
||||
player.ws.close();
|
||||
}
|
||||
else {
|
||||
const messageLen = encodeVarInt(message.length), codeEnc = encodeVarInt(code !== null && code !== void 0 ? code : DisconnectReason.CUSTOM);
|
||||
const d = Buffer.alloc(1 + codeEnc.length + messageLen.length + message.length);
|
||||
d.set([0xff, ...codeEnc, ...messageLen, ...Buffer.from(message)]);
|
||||
player.ws.send(d);
|
||||
player.ws.close();
|
||||
}
|
||||
}
|
||||
export function awaitPacket(ws, id) {
|
||||
return new Promise((res, rej) => {
|
||||
let resolved = false;
|
||||
const msgCb = (msg) => {
|
||||
if (id != null && msg[0] == id) {
|
||||
resolved = true;
|
||||
ws.removeEventListener('message', msgCb);
|
||||
ws.removeEventListener('close', discon);
|
||||
ws.setMaxListeners(ws.getMaxListeners() - 2 < 0 ? 5 : ws.getMaxListeners() - 2);
|
||||
res(msg);
|
||||
}
|
||||
else if (id == null) {
|
||||
resolved = true;
|
||||
ws.removeEventListener('message', msgCb);
|
||||
ws.removeEventListener('close', discon);
|
||||
ws.setMaxListeners(ws.getMaxListeners() - 2 < 0 ? 5 : ws.getMaxListeners() - 2);
|
||||
res(msg);
|
||||
}
|
||||
};
|
||||
const discon = () => {
|
||||
resolved = true;
|
||||
ws.removeEventListener('message', msgCb);
|
||||
ws.removeEventListener('close', discon);
|
||||
ws.setMaxListeners(ws.getMaxListeners() - 2 < 0 ? 5 : ws.getMaxListeners() - 2);
|
||||
rej("Connection closed");
|
||||
};
|
||||
ws.setMaxListeners(ws.getMaxListeners() + 2);
|
||||
ws.on('message', msgCb);
|
||||
ws.on('close', discon);
|
||||
setTimeout(() => {
|
||||
ws.removeEventListener('message', msgCb);
|
||||
ws.removeEventListener('close', discon);
|
||||
ws.setMaxListeners(ws.getMaxListeners() - 2 < 0 ? 5 : ws.getMaxListeners() - 2);
|
||||
rej("Timed out");
|
||||
}, 10000);
|
||||
});
|
||||
}
|
||||
export function loginServer(ip, port, client) {
|
||||
return new Promise((res, rej) => {
|
||||
let receivedCompression = false;
|
||||
const mcClient = mc.createClient({
|
||||
host: ip,
|
||||
port: port,
|
||||
auth: 'offline',
|
||||
version: '1.8.8',
|
||||
username: client.username
|
||||
});
|
||||
mcClient.on('error', err => {
|
||||
mcClient.end();
|
||||
rej(err);
|
||||
});
|
||||
mcClient.on('end', () => {
|
||||
client.ws.close();
|
||||
});
|
||||
mcClient.on('connect', () => {
|
||||
client.remoteConnection = mcClient;
|
||||
logger.info(`Player ${client.username} has been connected to the server.`);
|
||||
res();
|
||||
});
|
||||
mcClient.on('raw', p => {
|
||||
if (p[0] == 0x03 && !receivedCompression) {
|
||||
receivedCompression = true;
|
||||
const compT = {
|
||||
id: null,
|
||||
thres: null
|
||||
};
|
||||
const id = decodeVarInt(p);
|
||||
compT.id = Number(id[0]);
|
||||
const thres = decodeSVarInt(p.subarray(id[1]));
|
||||
compT.thres = thres[0];
|
||||
client.compressionThreshold = compT.thres;
|
||||
client.ws.send(p);
|
||||
}
|
||||
else {
|
||||
client.ws.send(p);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
export async function doHandshake(client, initialPacket) {
|
||||
client.ws.on('close', () => {
|
||||
client.state = State.DISCONNECTED;
|
||||
if (client.remoteConnection) {
|
||||
client.remoteConnection.end();
|
||||
}
|
||||
PROXY.players.delete(client.username);
|
||||
PROXY.playerStats.onlineCount -= 1;
|
||||
logger.info(`Client [/${client.ip}:${client.remotePort}]${client.username ? ` (${client.username})` : ""} disconnected from the server.`);
|
||||
});
|
||||
if (PROXY.players.size + 1 > PROXY.playerStats.max) {
|
||||
disconnect(client, "The proxy is full!", DisconnectReason.CUSTOM);
|
||||
return;
|
||||
}
|
||||
const identifyC = {
|
||||
id: null,
|
||||
brandingLen: null,
|
||||
branding: null,
|
||||
verLen: null,
|
||||
ver: null
|
||||
};
|
||||
if (true) {
|
||||
// save namespace by nesting func declarations in a if true statement
|
||||
const Iid = decodeVarInt(initialPacket);
|
||||
identifyC.id = Number(Iid[0]);
|
||||
const brandingLen = decodeVarInt(initialPacket.subarray(Iid[1] + 2));
|
||||
identifyC.brandingLen = Number(brandingLen[0]);
|
||||
identifyC.branding = initialPacket.subarray(brandingLen[1] + Iid[1] + 2, brandingLen[1] + Iid[1] + Number(brandingLen[0]) + 2).toString();
|
||||
const verLen = decodeVarInt(initialPacket.subarray(brandingLen[1] + Iid[1] + Number(brandingLen[0]) + 2));
|
||||
identifyC.verLen = Number(verLen[0]);
|
||||
identifyC.ver = initialPacket.subarray(brandingLen[1] + Number(brandingLen[0]) + Iid[1] + verLen[1] + 2).toString();
|
||||
}
|
||||
if (true) {
|
||||
const brandingLen = encodeVarInt(PROXY.brand.length), brand = PROXY.brand;
|
||||
const verLen = encodeVarInt(PROXY.version.length), version = PROXY.version;
|
||||
const buff = Buffer.alloc(2 + MAGIC_ENDING_IDENTIFYS_BYTES.length + brandingLen.length + brand.length + verLen.length + version.length);
|
||||
buff.set([EaglerPacketId.IDENTIFY_SERVER, 0x01, ...brandingLen, ...Buffer.from(brand), ...verLen, ...Buffer.from(version), ...Buffer.from(MAGIC_ENDING_IDENTIFYS_BYTES)]);
|
||||
client.ws.send(buff);
|
||||
}
|
||||
client.clientBrand = identifyC.branding;
|
||||
const login = await awaitPacket(client.ws);
|
||||
const loginP = {
|
||||
id: null,
|
||||
usernameLen: null,
|
||||
username: null,
|
||||
randomStrLen: null,
|
||||
randomStr: null,
|
||||
nullByte: null
|
||||
};
|
||||
if (login[0] === EaglerPacketId.LOGIN) {
|
||||
const Iid = decodeVarInt(login);
|
||||
loginP.id = Number(Iid[0]);
|
||||
const usernameLen = decodeVarInt(login.subarray(loginP[1]));
|
||||
loginP.usernameLen = Number(usernameLen[0]);
|
||||
loginP.username = login.subarray(Iid[1] + usernameLen[1], Iid[1] + usernameLen[1] + loginP.usernameLen).toString();
|
||||
const randomStrLen = decodeVarInt(login.subarray(Iid[1] + usernameLen[1] + loginP.usernameLen));
|
||||
loginP.randomStrLen = Number(randomStrLen[0]);
|
||||
loginP.randomStr = login.subarray(Iid[1] + usernameLen[1] + loginP.usernameLen + randomStrLen[1], Iid[1] + usernameLen[1] + loginP.usernameLen + randomStrLen[1] + loginP.randomStrLen).toString();
|
||||
client.username = loginP.username;
|
||||
client.uuid = genUUID(client.username);
|
||||
try {
|
||||
validateUsername(client.username);
|
||||
}
|
||||
catch (err) {
|
||||
disconnect(client, err.message, DisconnectReason.BAD_USERNAME);
|
||||
return;
|
||||
}
|
||||
if (PROXY.players.has(client.username)) {
|
||||
disconnect(client, `Duplicate username: ${client.username}. Please connect under a different username.`, DisconnectReason.DUPLICATE_USERNAME);
|
||||
return;
|
||||
}
|
||||
PROXY.players.set(client.username, client);
|
||||
if (true) {
|
||||
const usernameLen = encodeVarInt(client.username.length), username = client.username;
|
||||
const uuidLen = encodeVarInt(client.uuid.length), uuid = client.uuid;
|
||||
const buff = Buffer.alloc(1 + usernameLen.length + username.length + uuidLen.length + uuid.length);
|
||||
buff.set([EaglerPacketId.LOGIN_ACK, ...usernameLen, ...Buffer.from(username), ...uuidLen, ...Buffer.from(uuid)]);
|
||||
client.ws.send(buff);
|
||||
if (true) {
|
||||
const [skin, ready] = await Promise.all([awaitPacket(client.ws, EaglerPacketId.SKIN), awaitPacket(client.ws, EaglerPacketId.C_READY)]);
|
||||
if (ready[0] != 0x08) {
|
||||
logger.error(`Client [/${client.ip}:${client.remotePort}] sent an unexpected packet! Disconnecting.`);
|
||||
disconnect(client, "Received bad packet", DisconnectReason.UNEXPECTED_PACKET);
|
||||
client.ws.close();
|
||||
return;
|
||||
}
|
||||
const buff = Buffer.alloc(1);
|
||||
buff.set([EaglerPacketId.COMPLETE_HANDSHAKE]);
|
||||
client.ws.send(buff);
|
||||
client.state = State.POST_HANDSHAKE;
|
||||
PROXY.playerStats.onlineCount += 1;
|
||||
logger.info(`Client [/${client.ip}:${client.remotePort}] authenticated as player "${client.username}" and passed handshake. Connecting!`);
|
||||
try {
|
||||
await loginServer(config.server.host, config.server.port, client);
|
||||
}
|
||||
catch (err) {
|
||||
logger.error(`Could not connect to remote server at [/${config.server.host}:${config.server.port}]: ${err}`);
|
||||
disconnect(client, "Failed to connect to server. Please try again later.", DisconnectReason.CUSTOM);
|
||||
client.state = State.DISCONNECTED;
|
||||
client.ws.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger.error(`Client [/${client.ip}:${client.remotePort}] sent an unexpected packet! Disconnecting.`);
|
||||
disconnect(client, "Received bad packet", DisconnectReason.UNEXPECTED_PACKET);
|
||||
client.ws.close();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user