From 95b8baf560638afc23425f1261a48aa7f3354cf0 Mon Sep 17 00:00:00 2001 From: Thomas Smyth Date: Sat, 30 Jan 2021 14:39:56 +0000 Subject: [PATCH] Dynamically load plugins --- squad-server/factory.js | 20 ++++-- squad-server/plugins/index.js | 78 ++++++++++------------- squad-server/scripts/build-config-file.js | 7 +- squad-server/scripts/build-readme.js | 7 +- 4 files changed, 58 insertions(+), 54 deletions(-) diff --git a/squad-server/factory.js b/squad-server/factory.js index f611b599..074bf088 100644 --- a/squad-server/factory.js +++ b/squad-server/factory.js @@ -8,7 +8,7 @@ import sequelize from 'sequelize'; import Logger from 'core/logger'; import SquadServer from './index.js'; -import plugins from './plugins/index.js'; +import Plugins from './plugins/index.js'; const { Sequelize } = sequelize; @@ -16,6 +16,8 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); export default class SquadServerFactory { static async buildFromConfig(config) { + const plugins = await Plugins.getPlugins(); + for (const plugin of Object.keys(plugins)) { Logger.setColor(plugin, 'magentaBright'); } @@ -160,7 +162,9 @@ export default class SquadServerFactory { return SquadServerFactory.buildFromConfigString(SquadServerFactory.readConfigFile(configPath)); } - static buildConfig() { + static async buildConfig() { + const plugins = await Plugins.getPlugins(); + const templatePath = path.resolve(__dirname, './templates/config-template.json'); const templateString = fs.readFileSync(templatePath, 'utf8'); const template = SquadServerFactory.parseConfig(templateString); @@ -183,13 +187,17 @@ export default class SquadServerFactory { return template; } - static buildConfigFile() { + static async buildConfigFile() { const configPath = path.resolve(__dirname, '../config.json'); - const config = JSON.stringify(SquadServerFactory.buildConfig(), null, 2); - fs.writeFileSync(configPath, config); + const config = await SquadServerFactory.buildConfig(); + + const configString = JSON.stringify(config, null, 2); + fs.writeFileSync(configPath, configString); } - static buildReadmeFile() { + static async buildReadmeFile() { + const plugins = await Plugins.getPlugins(); + const pluginKeys = Object.keys(plugins).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0 ); diff --git a/squad-server/plugins/index.js b/squad-server/plugins/index.js index df2e0987..e52a6768 100644 --- a/squad-server/plugins/index.js +++ b/squad-server/plugins/index.js @@ -1,46 +1,36 @@ -import AutoKickUnassigned from './auto-kick-unassigned.js'; -import AutoTKWarn from './auto-tk-warn.js'; -import ChatCommands from './chat-commands.js'; -import DBLog from './db-log.js'; -import DiscordAdminBroadcast from './discord-admin-broadcast.js'; -import DiscordAdminCamLogs from './discord-admin-cam-logs.js'; -import DiscordAdminRequest from './discord-admin-request.js'; -import DiscordChat from './discord-chat.js'; -import DiscordDebug from './discord-debug.js'; -import DiscordRcon from './discord-rcon.js'; -import DiscordRoundWinner from './discord-round-winner.js'; -import DiscordServerStatus from './discord-server-status.js'; -import DiscordSubsystemRestarter from './discord-subsystem-restarter.js'; -import DiscordTeamkill from './discord-teamkill.js'; -import IntervalledBroadcasts from './intervalled-broadcasts.js'; -import SCBLInfo from './scbl-info.js'; -import SeedingMode from './seeding-mode.js'; -import TeamRandomizer from './team-randomizer.js'; - -const plugins = [ - AutoKickUnassigned, - AutoTKWarn, - ChatCommands, - DBLog, - DiscordAdminBroadcast, - DiscordAdminCamLogs, - DiscordAdminRequest, - DiscordChat, - DiscordDebug, - DiscordRcon, - DiscordRoundWinner, - DiscordServerStatus, - DiscordSubsystemRestarter, - DiscordTeamkill, - IntervalledBroadcasts, - SCBLInfo, - SeedingMode, - TeamRandomizer -]; - -const pluginsByName = {}; -for (const plugin of plugins) { - pluginsByName[plugin.name] = plugin; +import fs from 'fs'; + +import Logger from 'core/logger'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +class Plugins { + constructor() { + this.plugins = null; + } + + async getPlugins(force = false) { + if (this.plugins && !force) return this.plugins; + + this.plugins = {}; + + const dir = await fs.promises.opendir(path.join(__dirname, './')); + for await (const dirent of dir) { + if (!dirent.isFile()) continue; + if ( + ['index.js', 'base-plugin.js', 'discord-base-plugin.js', 'readme.md'].includes(dirent.name) + ) + continue; + Logger.verbose('Plugins', 1, `Loading plugin file ${dirent.name}...`); + const { default: Plugin } = await import(`./${dirent.name}`); + + this.plugins[Plugin.name] = Plugin; + } + + return this.plugins; + } } -export default pluginsByName; +export default new Plugins(); diff --git a/squad-server/scripts/build-config-file.js b/squad-server/scripts/build-config-file.js index 6f9501a7..e6cfc7b0 100644 --- a/squad-server/scripts/build-config-file.js +++ b/squad-server/scripts/build-config-file.js @@ -1,5 +1,8 @@ import SquadServerFactory from '../factory.js'; console.log('Building config...'); -SquadServerFactory.buildConfigFile(); -console.log('Done.'); +SquadServerFactory.buildConfigFile() + .then(() => { + console.log('Done.'); + }) + .catch(console.log); diff --git a/squad-server/scripts/build-readme.js b/squad-server/scripts/build-readme.js index 66e025dc..f471c91b 100644 --- a/squad-server/scripts/build-readme.js +++ b/squad-server/scripts/build-readme.js @@ -1,5 +1,8 @@ import SquadServerFactory from '../factory.js'; console.log('Building readme...'); -SquadServerFactory.buildReadmeFile(); -console.log('Done.'); +SquadServerFactory.buildReadmeFile() + .then(() => { + console.log('Done.'); + }) + .catch(console.log);