UNPKG

@krp-races/krp-node-wrapper

Version:

A node.js wrapper for a dedicated or challenge server in kart racing pro.

163 lines (160 loc) 7.13 kB
var tslib_es6 = require('../tslib.es6-DGH0njpN.js'); var events = require('events'); var enums_ClientStatus = require('../enums/ClientStatus.js'); var modules_SocketWrapper = require('./SocketWrapper.js'); var utils_writeStringLines = require('../utils/writeStringLines.js'); var utils_readStringLines = require('../utils/readStringLines.js'); var utils_timeout = require('../utils/timeout.js'); require('dgram'); class RemoteAdminClient extends events.EventEmitter { constructor(options) { super(); this.enabled = false; this.status = enums_ClientStatus.ClientStatus.NOT_CONNECTED; this.messageId = 0; this.options = options; this.socket = new modules_SocketWrapper.SocketWrapper(options); this.socket.on("error", this.handleError.bind(this)); this.on("connected", this.handleKeepAlive.bind(this)); } setEnabled(enabled) { const prevEnabled = this.enabled; this.enabled = enabled; if (!prevEnabled && enabled) this.handleReconnect(); if (prevEnabled && !enabled) this.disconnect(); } getEnabled() { return this.enabled; } setStatus(status) { this.status = status; this.messageId = 0; } getStatus() { return this.status; } connect() { return tslib_es6.__awaiter(this, void 0, void 0, function* () { if (this.status === enums_ClientStatus.ClientStatus.CONNECTED) return; this.setStatus(enums_ClientStatus.ClientStatus.CONNECTING); const data = utils_writeStringLines.writeStringLines(["CONNECT", this.options.password]); this.socket.send(data); const promise = new Promise((resolve, reject) => { const listener = (msg) => { const lines = utils_readStringLines.readStringLines(msg); switch (lines[0]) { case "OK": if (lines[1] !== "krp") { reject(new Error("Wrong game")); this.setStatus(enums_ClientStatus.ClientStatus.NOT_CONNECTED); this.socket.removeListener("message", listener); break; } resolve(undefined); this.setStatus(enums_ClientStatus.ClientStatus.CONNECTED); this.socket.removeListener("message", listener); break; case "FULL": reject(new Error("Server is full")); this.setStatus(enums_ClientStatus.ClientStatus.NOT_CONNECTED); this.socket.removeListener("message", listener); break; case "WRONGPASSWORD": reject(new Error("Wrong password")); this.setStatus(enums_ClientStatus.ClientStatus.NOT_CONNECTED); this.socket.removeListener("message", listener); break; } }; this.socket.on("message", listener); }); return Promise.race([promise, utils_timeout.timeout(5000)]).catch((err) => this.handleError(err)); }); } disconnect() { if (this.status !== enums_ClientStatus.ClientStatus.CONNECTED) return; const data = utils_writeStringLines.writeStringLines(["DISCONNECT"]); this.socket.send(data); this.setStatus(enums_ClientStatus.ClientStatus.NOT_CONNECTED); this.emit("disconnected"); } sendCommand(command, message) { return tslib_es6.__awaiter(this, void 0, void 0, function* () { if (this.status !== enums_ClientStatus.ClientStatus.CONNECTED) return; const messageId = this.messageId; const base = ["CMD", messageId.toFixed(0), command]; if (command === "MSG") { if (!message || message === "") throw new Error("Message is required for MSG command"); base.push(message); } const data = utils_writeStringLines.writeStringLines(base); this.socket.send(data); // Increase message id for next command this.messageId++; const promise = new Promise((resolve) => { const listener = (msg) => { const lines = utils_readStringLines.readStringLines(msg); if (lines[0] === "ACK" && parseInt(lines[1]) === messageId) { resolve(undefined); this.socket.removeListener("message", listener); } }; this.socket.on("message", listener); }); return Promise.race([promise, utils_timeout.timeout(5000)]).catch((err) => this.handleError(err)); }); } keepAlive() { return tslib_es6.__awaiter(this, void 0, void 0, function* () { if (this.status !== enums_ClientStatus.ClientStatus.CONNECTED) return; const data = utils_writeStringLines.writeStringLines(["KEEPALIVE"]); this.socket.send(data); const promise = new Promise((resolve) => { const listener = (msg) => { const lines = utils_readStringLines.readStringLines(msg); if (lines[0] === "ALIVE") { resolve(undefined); this.socket.removeListener("message", listener); } }; this.socket.on("message", listener); }); return Promise.race([promise, utils_timeout.timeout(5000)]).catch((err) => this.handleError(err)); }); } handleReconnect() { return tslib_es6.__awaiter(this, void 0, void 0, function* () { // If not enabled, do not attempt to reconnect if (!this.enabled) return; yield this.connect().catch((err) => this.handleError(err)); // When connected to a server, do not attempt to reconnect if (this.status === enums_ClientStatus.ClientStatus.CONNECTED) { this.emit("connected"); return; } // Attempt to reconnect in x milliseconds setTimeout(this.handleReconnect.bind(this), 5000); }); } handleKeepAlive() { return tslib_es6.__awaiter(this, void 0, void 0, function* () { if (this.status !== enums_ClientStatus.ClientStatus.CONNECTED) return; yield this.keepAlive().catch((err) => this.handleError(err)); setTimeout(this.handleKeepAlive.bind(this), 15000); }); } handleError(err) { this.emit("error", err); this.disconnect(); } } exports.RemoteAdminClient = RemoteAdminClient;