UNPKG

maniajs

Version:

ManiaPlanet (Dedicated) Server Controller.

405 lines (320 loc) 12.7 kB
'use strict'; /** * Client Manager - Will connect to the maniaplanet server */ Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _gbxremote = require('gbxremote'); var _gbxremote2 = _interopRequireDefault(_gbxremote); var _events = require('events'); var _fs = require('fs'); var fs = _interopRequireWildcard(_fs); var _callbackManager = require('./callback-manager'); var _callbackManager2 = _interopRequireDefault(_callbackManager); var _commandManager = require('./command-manager'); var _commandManager2 = _interopRequireDefault(_commandManager); var _send = require('./send'); var _send2 = _interopRequireDefault(_send); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** * Server Client. * @class ServerClient * @type {ServerClient} * * @function {Send} send * * @property {object} game * @property {object} game.CurrentGameInfos * @property {number} game.CurrentGameInfos.GameMode * @property {object] game.NextGameInfos * @property {number} game.NextGameInfos.GameMode * * @property {{data:string,maps:string,skins:string}} paths Server Paths. */ var ServerClient = function (_EventEmitter) { _inherits(ServerClient, _EventEmitter); /** * Prepare the client. parse configuration and pass it to the gbx client. * * @param {App} app context */ function ServerClient(app) { _classCallCheck(this, ServerClient); var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ServerClient).call(this)); _this.setMaxListeners(0); _this.app = app; _this.gbx = null; /** @type {CallbackManager} */ _this.callback = null; /** @type {CommandManager} */ _this.command = null; _this.server = app.config.server; // Server properties _this.titleId = null; _this.version = null; _this.build = null; _this.apiVersion = null; _this.login = null; _this.name = null; _this.comment = null; _this.path = null; _this.ip = null; _this.ports = {}; _this.playerId = null; _this.paths = {}; // Current Game Name, 'trackmania' or 'shootmania'. _this.gameName = app.config.server.game || 'trackmania'; _this.options = {}; // Will be the result of GetServerOptions() call to the mp server. _this.game = {}; // Will be the result of GetGameInfo() call. return _this; } /** * Build a sending query. * * @returns {Send} */ _createClass(ServerClient, [{ key: 'send', value: function send() { return new _send2.default(this.app, this); } /** * Connect to the server. * * @returns {Promise} */ }, { key: 'connect', value: function connect() { var _this2 = this; this.app.log.debug("Connecting to ManiaPlanet Server..."); return new Promise(function (resolve, reject) { _this2.gbx = _gbxremote2.default.createClient(_this2.server.port, _this2.server.address); // On Connect _this2.gbx.on('connect', function () { _this2.app.log.debug('Connection to ManiaPlanet server successful!'); if (_this2.app.config.hasOwnProperty('debug') && _this2.app.config.debug) { _this2.gbx.on('callback', function (method, params) { _this2.app.log.debug("GBX: Callback '" + method + "':", params); }); } return resolve(); }); // On Error _this2.gbx.on('error', function (err) { _this2.app.log.fatal(err.stack); if (err.message === 'read ECONNRESET') { _this2.app.log.fatal('Connection with ManiaPlanet server lost!'); process.exit(1); } else { return reject(err); } }); }).then(function () { // Authentication return _this2.gbx.query('Authenticate', [_this2.server.authentication.username, _this2.server.authentication.password]); }).then(function () { // Set API Version _this2.app.log.debug("Connection to ManiaPlanet Server, Successfully authenticated!"); return _this2.gbx.query('SetApiVersion', ['2015-02-10']); }).then(function () { // Set Callbacks On _this2.app.log.debug("Connection to ManiaPlanet Server, Successfully set api version!"); return _this2.gbx.query('EnableCallbacks', [true]); }).then(function () { // Get server information _this2.app.log.debug("Connection to ManiaPlanet Server, Successfully enabled callbacks!"); // Send boot msg _this2.send().chat("$o$f90Mania$z$o$f90JS$z$fff: Booting Controller...").exec(); // Hide all current ManiaLinks _this2.gbx.query('SendHideManialinkPage', []); return _this2.gbx.query('GetVersion', []); }).then(function (res) { // Get System Info _this2.app.log.debug("Connection to ManiaPlanet Server, Getting information...!"); _this2.version = res.Version; _this2.build = res.Build; _this2.apiVersion = res.ApiVersion; return _this2.gbx.query('GetSystemInfo', []); }).then(function (res) { // Get Detailed Server Player Information (about the server player). _this2.ip = res.PublishedIp; _this2.ports = { port: res.Port, P2PPort: res.P2PPort }; _this2.titleId = res.TitleId; _this2.login = res.ServerLogin; _this2.playerId = res.ServerPlayerId; return _this2.gbx.query('GetDetailedPlayerInfo', [_this2.login]); }).then(function (res) { // Get server options _this2.path = res.Path; return _this2.getServerOptions(); }).then(function (options) { _this2.name = options.Name; _this2.comment = options.Comment; _this2.options = options; }).then(function () { // Get game info return _this2.getGameInfos(); }).then(function (info) { _this2.game = info; // Get Directories. return _this2.getServerDirectories(); }).then(function (dirs) { _this2.paths = dirs; // Test writing and reading in the data directory if (!fs.existsSync(_this2.paths.data)) { return Promise.reject(new Error('ManiaJS could not find the ManiaPlanet data dir! Is ManiaJS running on the same machine?')); } try { fs.accessSync(_this2.paths.data); } catch (err) { return Promise.reject(err); } // If scripted? Then enable scripted callbacks if (_this2.isScripted()) { _this2.app.log.debug('Enabling Scripted Callbacks...'); return new Promise(function (resolve, reject) { _this2.gbx.query('GetModeScriptSettings', []).then(function (settings) { if (!settings) { return reject(new Error('No ScriptSettings received!')); } // Add callback listener. if (!settings.hasOwnProperty('S_UseScriptCallbacks')) { return resolve(); // Ignore and continue. } settings['S_UseScriptCallbacks'] = true; // TODO: Floats. console.log(settings); // Set and resolve, BUG: will throw error, type error. _this2.gbx.query('SetModeScriptSettings', [settings]).then(function () { return resolve(); }).catch(function (err) { return reject(err); }); }); }); } return Promise.resolve(); }); } /** * Register the Callbacks. * * @return {Promise} */ }, { key: 'register', value: function register() { var _this3 = this; this.app.log.debug('Registering callbacks...'); return new Promise(function (resolve) { _this3.callback = new _callbackManager2.default(_this3.app, _this3); _this3.command = new _commandManager2.default(_this3.app, _this3); _this3.callback.loadSet('maniaplanet'); if (_this3.app.config.server.game === 'trackmania') { _this3.callback.loadSet('trackmania'); } return resolve(); }); } /** * Update information about the server. * * @return {Promise} */ }, { key: 'updateInfos', value: function updateInfos() { var _this4 = this; // Update return this.getServerOptions().then(function () { return _this4.getGameInfos(); }); } /** * Is Current mode scripted? * * @returns {boolean} */ }, { key: 'isScripted', value: function isScripted() { return this.game.CurrentGameInfos.GameMode === 0 || false; } /** * Get Current Mode Integer, try to convert script name to game mode integer. * @returns {number} */ }, { key: 'currentMode', value: function currentMode() { if (this.isScripted()) { // TODO: Script => legacy integers. } return this.game.CurrentGameInfos.GameMode; } /** * Get Options of server. * * @returns {Promise} */ }, { key: 'getServerOptions', value: function getServerOptions() { var _this5 = this; return new Promise(function (resolve, reject) { _this5.gbx.query('GetServerOptions', []).then(function (res) { // Update properties. _this5.name = res.Name; _this5.comment = res.Comment; _this5.options = res; return resolve(res); }).catch(function (err) { return reject(err); }); }); } /** * Get GetGameInfos call info. Will also update current server.game infos. * * @returns {Promise} */ }, { key: 'getGameInfos', value: function getGameInfos() { var _this6 = this; return new Promise(function (resolve, reject) { _this6.gbx.query('GetGameInfos', []).then(function (res) { _this6.game = res; return resolve(res); }).catch(function (err) { return reject(err); }); }); } /** * Get Server Directories. * @returns Promise promise with object: data, maps, skins. */ }, { key: 'getServerDirectories', value: function getServerDirectories() { var _this7 = this; return new Promise(function (resolve, reject) { _this7.gbx.query('system.multicall', [[{ methodName: 'GameDataDirectory', params: [] }, { methodName: 'GetMapsDirectory', params: [] }, { methodName: 'GetSkinsDirectory', params: [] }]]).then(function (results) { return resolve({ data: results[0][0], maps: results[1][0], skins: results[2][0] }); }).catch(function (err) { return reject(err); }); }); } }]); return ServerClient; }(_events.EventEmitter); exports.default = ServerClient;