UNPKG

steam-condenser

Version:
406 lines 19.7 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var Server_1 = __importDefault(require("./Server")); var S2CChallengePacket_1 = __importDefault(require("./Packets/S2CChallengePacket")); var S2AInfoBasePacket_1 = __importDefault(require("./Packets/S2AInfoBasePacket")); var S2APlayerPacket_1 = __importDefault(require("./Packets/S2APlayerPacket")); var S2ARulesPacket_1 = __importDefault(require("./Packets/S2ARulesPacket")); var A2SPlayerPacket_1 = __importDefault(require("./Packets/A2SPlayerPacket")); var A2SInfoPacket_1 = __importDefault(require("./Packets/A2SInfoPacket")); var A2SRulesPacket_1 = __importDefault(require("./Packets/A2SRulesPacket")); var SteamPacket_1 = __importDefault(require("./Packets/SteamPacket")); var GameServer = /** @class */ (function (_super) { __extends(GameServer, _super); function GameServer(address, port) { var _this = _super.call(this, address, port) || this; _this.infoHash = {}; _this.challengeNumber = -1; _this.rconAuthenticated = false; return _this; } GameServer.prototype.getPing = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { return [2 /*return*/, new Promise(function (resolve) { if (typeof _this.ping === 'undefined') { resolve(_this.updatePing()); } else { resolve(_this.ping); } })]; }); }); }; GameServer.prototype.getPlayers = function (rconPassword) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(typeof this.playerHash === 'undefined')) return [3 /*break*/, 2]; return [4 /*yield*/, this.updatePlayers(rconPassword)]; case 1: _a.sent(); _a.label = 2; case 2: return [2 /*return*/, this.playerHash || {}]; } }); }); }; GameServer.prototype.getRules = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { return [2 /*return*/, new Promise(function (resolve, reject) { if (typeof _this.rulesHash === 'undefined') { _this.updateRules() .then(function () { resolve(_this.rulesHash); }) .catch(reject); } else { resolve(_this.rulesHash); } })]; }); }); }; GameServer.prototype.getServerInfo = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(typeof this.infoHash === 'undefined')) return [3 /*break*/, 2]; return [4 /*yield*/, this.updateServerInfo()]; case 1: _a.sent(); _a.label = 2; case 2: return [2 /*return*/, this.infoHash]; } }); }); }; GameServer.prototype.initialize = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.initSocket()]; case 1: _a.sent(); return [4 /*yield*/, this.updatePing()]; case 2: _a.sent(); return [4 /*yield*/, this.updateServerInfo()]; case 3: _a.sent(); return [4 /*yield*/, this.updateChallengeNumber()]; case 4: _a.sent(); return [2 /*return*/]; } }); }); }; GameServer.prototype.handleResponseForRequest = function (requestType, repeatOnFailure) { if (repeatOnFailure === void 0) { repeatOnFailure = true; } return __awaiter(this, void 0, void 0, function () { var expectedResponse, requestPacket, responsePacket; return __generator(this, function (_a) { switch (_a.label) { case 0: switch (requestType) { case GameServer.REQUEST_CHALLENGE: expectedResponse = S2CChallengePacket_1.default; requestPacket = new A2SPlayerPacket_1.default(); break; case GameServer.REQUEST_INFO: expectedResponse = S2AInfoBasePacket_1.default; requestPacket = new A2SInfoPacket_1.default(); break; case GameServer.REQUEST_PLAYER: expectedResponse = S2APlayerPacket_1.default; requestPacket = new A2SPlayerPacket_1.default(this.challengeNumber); break; case GameServer.REQUEST_RULES: expectedResponse = S2ARulesPacket_1.default; requestPacket = new A2SRulesPacket_1.default(this.challengeNumber); break; default: throw new Error('Called with wrong request type.'); } if (typeof this.socket === 'undefined') { throw new Error('socket not set up'); } return [4 /*yield*/, this.socket.send(requestPacket)]; case 1: _a.sent(); if (typeof this.socket === 'undefined') { throw new Error('socket not set up'); } return [4 /*yield*/, this.socket.getReply()]; case 2: responsePacket = _a.sent(); if (!(responsePacket instanceof SteamPacket_1.default)) { throw new Error("Invalid response packet " + responsePacket); } if (responsePacket instanceof S2AInfoBasePacket_1.default) { this.infoHash = responsePacket.getInfo(); } else if (responsePacket instanceof S2APlayerPacket_1.default) { this.playerHash = responsePacket.getPlayerHash(); } else if (responsePacket instanceof S2ARulesPacket_1.default) { this.rulesHash = responsePacket.getRulesArray(); } else if (responsePacket instanceof S2CChallengePacket_1.default) { this.challengeNumber = responsePacket.getChallengeNumber(); } else { throw new Error("Response of type " + responsePacket + "cannot be handled by this method."); } if (!(responsePacket instanceof expectedResponse)) { // TODO: Logger /* eslint-disable no-console */ console.error('was', responsePacket); console.error('expected', expectedResponse); console.error('sent', requestPacket); /* eslint-enable no-console */ if (repeatOnFailure) { return [2 /*return*/, this.handleResponseForRequest(requestType, false)]; } // throw new Error(`Response was not expected${responsePacket}`); } return [2 /*return*/]; } }); }); }; GameServer.prototype.isRconAuthenticated = function () { return this.rconAuthenticated; }; GameServer.prototype.updateChallengeNumber = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.handleResponseForRequest(GameServer.REQUEST_CHALLENGE)]; }); }); }; GameServer.prototype.updatePing = function () { return __awaiter(this, void 0, void 0, function () { var startTime, endTime; return __generator(this, function (_a) { switch (_a.label) { case 0: if (typeof this.socket === 'undefined') { throw new Error('socket not set up'); } return [4 /*yield*/, this.socket.send(new A2SInfoPacket_1.default())]; case 1: _a.sent(); startTime = new Date().getTime(); if (typeof this.socket === 'undefined') { throw new Error('socket not set up'); } return [4 /*yield*/, this.socket.getReply()]; case 2: _a.sent(); endTime = new Date().getTime(); this.ping = endTime - startTime; return [2 /*return*/, this.ping]; } }); }); }; GameServer.prototype.updatePlayers = function (rconPassword) { return __awaiter(this, void 0, void 0, function () { var status, players, lines, i, line, attributes, i, player, playerData; return __generator(this, function (_a) { switch (_a.label) { case 0: if (typeof this.playerHash === 'undefined') { this.playerHash = {}; } return [4 /*yield*/, this.handleResponseForRequest(GameServer.REQUEST_PLAYER)]; case 1: _a.sent(); if (!this.rconAuthenticated && typeof rconPassword === 'undefined') { return [2 /*return*/, false]; } if (!(!this.rconAuthenticated && typeof rconPassword !== 'undefined')) return [3 /*break*/, 3]; return [4 /*yield*/, this.rconAuth(rconPassword)]; case 2: _a.sent(); _a.label = 3; case 3: return [4 /*yield*/, this.rconExec('status')]; case 4: status = _a.sent(); players = []; lines = status.split('\n'); for (i = 0; i < lines.length; i += 1) { line = lines[i]; if (line.startsWith('#') && line !== '#end') { players.push(line.substr(1).trim()); } } attributes = GameServer.GetPlayerStatusAttributes(players[0]); players = players.slice(1); for (i = 0; i < players.length; i += 1) { player = players[i]; playerData = GameServer.SplitPlayerStatus(attributes, player); if (typeof this.playerHash[playerData.name] !== 'undefined') { this.playerHash[playerData.name].addInformation(playerData); } } return [2 /*return*/, this.playerHash]; } }); }); }; GameServer.prototype.updateRules = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.handleResponseForRequest(GameServer.REQUEST_RULES)]; }); }); }; GameServer.prototype.updateServerInfo = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.handleResponseForRequest(GameServer.REQUEST_INFO)]; }); }); }; GameServer.prototype.setTimeout = function (time) { var _a; _super.prototype.setTimeout.call(this, time); (_a = this.socket) === null || _a === void 0 ? void 0 : _a.setTimeout(time); }; GameServer.prototype.toString = function () { var _this = this; var returnString = ''; returnString += "Ping: " + this.ping + "\n"; returnString += "Challenge number: " + this.challengeNumber + "\n"; // Use infoHash as genereic json object var hash = this.infoHash; if (typeof this.infoHash !== 'undefined') { returnString += 'Info:\n'; Object.keys(this.infoHash).forEach(function (key) { returnString += " " + key + ": " + hash + "\n"; }); } if (typeof this.playerHash !== 'undefined') { returnString += 'Players:\n'; returnString = Object.keys(this.playerHash).join('\n'); } if (typeof this.rulesHash !== 'undefined') { returnString += 'Rules:\n'; Object.keys(this.rulesHash).forEach(function (key) { // Typescript think rulehash might get undefined, even with above check if (typeof _this.rulesHash !== 'undefined') { returnString += " " + key + ": " + _this.rulesHash[key] + "\n"; } }); } return returnString; }; GameServer.GetPlayerStatusAttributes = function (statusHeader) { var statusAttributes = []; var split = statusHeader.split(/\s+/); for (var i = 0; i < split.length; i += 1) { var attr = split[i]; if (attr === 'connected') { statusAttributes.push('time'); } else if (attr === 'frag') { statusAttributes.push('score'); } else { statusAttributes.push(attr); } } return statusAttributes; }; GameServer.SplitPlayerStatus = function (attributes, playerStatus) { var statusStr = playerStatus; if (attributes[0] !== 'userid') { statusStr = statusStr.replace(/^\d+ +/, ''); } var firstquote = statusStr.indexOf('"'); var lastquote = statusStr.lastIndexOf('"'); var data = statusStr.substr(0, firstquote).split(/\s+/) .concat([statusStr.substr(firstquote + 1, lastquote - 1 - firstquote)]) .concat(statusStr.substr(lastquote + 1).split(/\s+/)) .filter(function (l) { return l !== ''; }); // TODO: Why? if (attributes.length > data.length && attributes.includes('state')) { data.splice(3, 0); } else if (attributes.length < data.length) { data.splice(1, 1); } var playerData = {}; for (var part = 0; part < data.length; part += 1) { playerData[attributes[part]] = data[part]; } return playerData; }; GameServer.REQUEST_CHALLENGE = 0; GameServer.REQUEST_INFO = 1; GameServer.REQUEST_PLAYER = 2; GameServer.REQUEST_RULES = 3; return GameServer; }(Server_1.default)); exports.default = GameServer; //# sourceMappingURL=GameServer.js.map