@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
JavaScript
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;