UNPKG

maniajs

Version:

ManiaPlanet (Dedicated) Server Controller.

289 lines (227 loc) 8.63 kB
'use strict'; 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 _fs = require('fs'); var fs = _interopRequireWildcard(_fs); var _path = require('path'); var path = _interopRequireWildcard(_path); var _glob = require('glob'); var glob = _interopRequireWildcard(_glob); var _async = require('async'); var async = _interopRequireWildcard(_async); var _dependencyGraph = require('dependency-graph'); 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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * Plugin class. * @class PluginManager * @type {PluginManager} */ var PluginManager = function () { /** * Construct plugin manager. * * @param {App} app */ function PluginManager(app) { _classCallCheck(this, PluginManager); this.app = app; this.graph = new _dependencyGraph.DepGraph(); // ObjectArray this.plugins = {}; // Array of plugin ids in order for starting. this.order = []; } /** * Load all plugins in order of requirements/dependencies. * * @returns {Promise} */ _createClass(PluginManager, [{ key: 'loadPlugins', value: function loadPlugins() { var _this = this; this.app.log.debug("Loading plugins from configuration..."); return new Promise(function (resolve, reject) { // Get all plugin info's first var plugins = _this.app.config.plugins && _this.app.config.plugins !== null ? _this.app.config.plugins : []; var pluginIds = Object.keys(plugins); // Init plugins. pluginIds.forEach(function (pluginId) { _this.app.log.debug("Loading plugin '" + pluginId + "'..."); // Import plugin. try { // Plugin config. var config = _this.app.config.plugins[pluginId]; // Load plugin (require). var PluginClass = require(pluginId).default; // Save plugin details to plugin array. _this.plugins[pluginId] = new PluginClass(); // Is Plugin suited for the Game (trackmania/shootmania) if (_this.plugins[pluginId].hasOwnProperty('game') && _this.plugins[pluginId].game.hasOwnProperty('games')) { if (_this.plugins[pluginId].game.games.indexOf(_this.app.serverFacade.client.gameName) > -1 || _this.plugins[pluginId].game.games.length === 0) { // All Right! Let's continue. } else { // Don't load! Unload from local properties, throw warning. delete _this.plugins[pluginId]; _this.app.log.warn('Plugin \'' + pluginId + '\' is not suited for the current game! Plugin unloaded!'); return; // Stop current loop. } } // Inject App, options and child logger. _this.plugins[pluginId].inject(_this.app, config, _this.app.log.child({ plugin: pluginId })); // Register node _this.graph.addNode(pluginId); } catch (err) { return reject(err); } }); // Set plugins to app plugins. _this.app.plugins = _this.plugins; return resolve(); }); } /** * Call on MapBegin, will check against current game mode. * Will also disable plugins when not compatible with game mode. */ }, { key: 'begin', value: function begin() { var _this2 = this; return new Promise(function (resolve, reject) { Object.keys(_this2.plugins).forEach(function (pluginId) { var plugin = _this2.plugins[pluginId]; if (plugin.hasOwnProperty('game') && plugin.game.hasOwnProperty('modes') && plugin.game.modes.length > 0) { if (plugin.game.modes.indexOf(_this2.app.serverFacade.client.currentMode()) > -1) { // All OK! } else { // Stop! // TODO: Stop plugin. } } }); return resolve(); }); } /** * Start all plugins, this will first determinate the start order, then ask the plugins to init, async and in order. * * @return {Promise} */ }, { key: 'startPlugins', value: function startPlugins() { var self = this; this.app.log.debug("Starting all plugins... Determinate order..."); // Determinate order. try { this.determinateOrder(); } catch (err) { return Promise.reject(err); } this.app.log.debug("Starting all plugins... Calling init..."); return new Promise(function (resolve, reject) { async.eachSeries(self.order, function (id, callback) { self.plugins[id].init().then(function () { callback(); }).catch(function (err) { callback(err); }); }, function (err) { if (err) { return reject(err); } return resolve(); }); }); } /** * Determinate start order. */ }, { key: 'determinateOrder', value: function determinateOrder() { var ids = Object.keys(this.plugins); // Loop and register dependencies to nodes. for (var i = 0; i < ids.length; i++) { var id = ids[i]; var plugin = this.plugins[id]; if (plugin.hasOwnProperty('dependencies')) { var dependencies = plugin.dependencies; if (dependencies.length > 0) { // Parse, add node and go on. this.graph.addDependency(plugin); } } } this.order = this.graph.overallOrder(); } /** * Load all models from plugins. * * @param sequelize * * @returns {Promise} */ }, { key: 'loadModels', value: function loadModels(sequelize) { var _this3 = this; if (this.order.length === 0) { this.determinateOrder(); } this.order.forEach(function (id) { if (_this3.plugins[id].directory) { var modelDirectory = path.normalize(_this3.plugins[id].directory + '/models/'); try { if (modelDirectory && fs.existsSync(modelDirectory)) { var list = glob.sync(modelDirectory + '*.js'); if (list.length > 0) { list.forEach(function (file) { // Import sequelize model. var model = sequelize.import(file); // Set in the plugin. if (!_this3.plugins[id].models) { _this3.plugins[id].models = {}; } _this3.plugins[id].models[model.name] = model; // Set in the global models. if (!_this3.app.models.hasOwnProperty(id)) { _this3.app.models[id] = {}; } _this3.app.models[id][model.name] = model; }); } } } catch (err) { _this3.app.log.warn('Warning, can\'t load models for plugin ' + id, err.stack); } } }); } /** * Emit event on all plugins! * Will be in the order calculated on dependencies. * * @param {string} event * @param {object} params * @param {object} options */ }, { key: 'emitAll', value: function emitAll(event, params, options) { var _this4 = this; params = params || {}; options = options || {}; // Always do it on the specific order we always use! this.order.forEach(function (id) { _this4.plugins[id].emit(event, params); }); } }]); return PluginManager; }(); exports.default = PluginManager;