steam-condenser
Version:
TypeScript port of steam-condenser.
406 lines • 19.7 kB
JavaScript
"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