mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-12 07:04:52 +09:00
Remove old plugin system
Remove the old client/instance fused plugin system along with instanceManagement in client.js and getPlugins in master.js.
This commit is contained in:
1 parent
22c325394f
commit
21d9fdff7b
6 files changed
+3
-302
No files matched your search
@@ -98,6 +98,8 @@ Version 2.0.0
|
|||||||
- Removed the hello event from the socket connection handshake. Breaks
|
- Removed the hello event from the socket connection handshake. Breaks
|
||||||
playerManager, trainTeleports, serverSelect, and discordChat
|
playerManager, trainTeleports, serverSelect, and discordChat
|
||||||
- Changed the format of database/slaves.json.
|
- Changed the format of database/slaves.json.
|
||||||
|
- Removed the output file subscription system. Breaks inventoryImports,
|
||||||
|
playerManager, trainTeleports, serverSelect and researchSync.
|
||||||
|
|
||||||
|
|
||||||
Version 1.2.4
|
Version 1.2.4
|
||||||
|
|||||||
@@ -1,27 +1,15 @@
|
|||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const Tail = require('tail').Tail;
|
|
||||||
const needle = require("needle");
|
|
||||||
const child_process = require('child_process');
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const request = require("request");
|
|
||||||
const deepmerge = require("deepmerge");
|
|
||||||
const ioClient = require("socket.io-client");
|
|
||||||
const util = require("util");
|
|
||||||
const yargs = require("yargs");
|
const yargs = require("yargs");
|
||||||
const version = require("./package").version;
|
const version = require("./package").version;
|
||||||
|
|
||||||
// internal libraries
|
// internal libraries
|
||||||
const objectOps = require("lib/objectOps");
|
|
||||||
const fileOps = require("lib/fileOps");
|
const fileOps = require("lib/fileOps");
|
||||||
const pluginManager = require("lib/manager/pluginManager");
|
|
||||||
const hashFile = require('lib/hash').hashFile;
|
const hashFile = require('lib/hash').hashFile;
|
||||||
const factorio = require("lib/factorio");
|
const factorio = require("lib/factorio");
|
||||||
const schema = require("lib/schema");
|
|
||||||
const link = require("lib/link");
|
const link = require("lib/link");
|
||||||
const errors = require("lib/errors");
|
const errors = require("lib/errors");
|
||||||
|
|
||||||
// Uhm...
|
|
||||||
var global = {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keeps track of the runtime parameters of an instance
|
* Keeps track of the runtime parameters of an instance
|
||||||
@@ -186,7 +174,6 @@ class Instance extends link.Link{
|
|||||||
clientPort: this.server.rconPort,
|
clientPort: this.server.rconPort,
|
||||||
clientPassword: this.server.rconPassword,
|
clientPassword: this.server.rconPassword,
|
||||||
}
|
}
|
||||||
//instanceManagement(slaveConfig, this, compatConfig, this.server, socket); // XXX async function
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.server.start(saveName);
|
await this.server.start(saveName);
|
||||||
@@ -739,130 +726,6 @@ async function startClient() {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure instancemanagement only ever runs once
|
|
||||||
var _instanceInitialized;
|
|
||||||
async function instanceManagement(slaveConfig, instance, instanceconfig, server, socket) {
|
|
||||||
if (_instanceInitialized) return;
|
|
||||||
_instanceInitialized = true;
|
|
||||||
|
|
||||||
let compatUrl = slaveConfig.masterUrl;
|
|
||||||
if (compatUrl.endsWith("/")) {
|
|
||||||
compatUrl = compatUrl.slice(0, -1);
|
|
||||||
}
|
|
||||||
let compatConfig = {
|
|
||||||
name: slaveConfig.name,
|
|
||||||
masterURL: compatUrl,
|
|
||||||
masterAuthToken: slaveConfig.masterToken,
|
|
||||||
publicIP: slaveConfig.publicAddress,
|
|
||||||
instanceDirectory: slaveConfig.instancesDir,
|
|
||||||
factorioDirectory: slaveConfig.factorioDir,
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Started instanceManagement();");
|
|
||||||
|
|
||||||
// load plugins and execute onLoad event
|
|
||||||
let pluginsToLoad = await pluginManager.getPlugins();
|
|
||||||
let plugins = [];
|
|
||||||
|
|
||||||
for(let i = 0; i < pluginsToLoad.length; i++){
|
|
||||||
let pluginLoadStarted = Date.now();
|
|
||||||
let combinedConfig = deepmerge(instanceconfig,compatConfig,{clone:true});
|
|
||||||
combinedConfig.instanceName = instance.name;
|
|
||||||
let pluginConfig = pluginsToLoad[i];
|
|
||||||
|
|
||||||
if(!global.subscribedFiles) {
|
|
||||||
global.subscribedFiles = {};
|
|
||||||
}
|
|
||||||
if (pluginConfig.enabled) {
|
|
||||||
// require plugin class and execute it
|
|
||||||
let pluginClass = require(path.resolve(pluginConfig.pluginPath, "index"));
|
|
||||||
plugins[i] = new pluginClass(combinedConfig, async function(data, callback){
|
|
||||||
if(data && data.toString('utf8')[0] != "/") {
|
|
||||||
console.log("Clusterio | "+ pluginsToLoad[i].name + " | " + data.toString('utf8'));
|
|
||||||
return true;
|
|
||||||
} else if (data && data.toString('utf8')[0] == "/"){
|
|
||||||
let result = await server.sendRcon(data.toString('utf8'));
|
|
||||||
if (typeof callback === "function") {
|
|
||||||
callback(result);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}, { // extra functions to pass in object. Should have done it like this from the start, but won't break backwards compat.
|
|
||||||
socket, // socket.io connection to master (and ES6 destructuring, yay)
|
|
||||||
});
|
|
||||||
if(plugins[i].factorioOutput && typeof plugins[i].factorioOutput === "function"){
|
|
||||||
// when factorio logs a line, send it to the plugin. This includes things like autosaves, chat, errors etc
|
|
||||||
server.on('stdout', data => plugins[i].factorioOutput(data.toString()));
|
|
||||||
}
|
|
||||||
if(pluginConfig.scriptOutputFileSubscription && typeof pluginConfig.scriptOutputFileSubscription == "string"){
|
|
||||||
if(global.subscribedFiles[pluginConfig.scriptOutputFileSubscription]) {
|
|
||||||
// please choose a unique file to subscribe to. If you need plugins to share this interface, set up a direct communication
|
|
||||||
// between those plugins instead.
|
|
||||||
throw "FATAL ERROR IN " + pluginConfig.name + " FILE ALREADY SUBSCRIBED " + pluginConfig.scriptOutputFileSubscription;
|
|
||||||
}
|
|
||||||
|
|
||||||
let outputPath = instance.path(
|
|
||||||
"script-output",
|
|
||||||
pluginConfig.scriptOutputFileSubscription
|
|
||||||
);
|
|
||||||
if (!fs.existsSync(outputPath)) {
|
|
||||||
// Do something
|
|
||||||
fs.writeFileSync(outputPath, "");
|
|
||||||
}
|
|
||||||
global.subscribedFiles[pluginConfig.scriptOutputFileSubscription] = true;
|
|
||||||
console.log("Clusterio | Registered file subscription on "+outputPath);
|
|
||||||
|
|
||||||
|
|
||||||
if(!pluginConfig.fileReadDelay || pluginConfig.fileReadDelay == 0) {
|
|
||||||
// only wipe the file on restart for now, should most likely be rotated during runtime too
|
|
||||||
fs.writeFileSync(outputPath, "");
|
|
||||||
let tail = new Tail(outputPath);
|
|
||||||
tail.on("line", function (data) {
|
|
||||||
plugins[i].scriptOutput(data);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
fs.watch(outputPath, fileChangeHandler);
|
|
||||||
// run once in case a plugin wrote out information before the plugin loaded fully
|
|
||||||
// delay, so the socket got enough time to connect
|
|
||||||
setTimeout(() => {
|
|
||||||
fileChangeHandler(false, pluginConfig.scriptOutputFileSubscription);
|
|
||||||
}, 500);
|
|
||||||
|
|
||||||
// send file contents to plugin for processing
|
|
||||||
function fileChangeHandler(eventType, filename) {
|
|
||||||
if (filename != null) {
|
|
||||||
setTimeout(
|
|
||||||
() => {
|
|
||||||
// get array of lines in file
|
|
||||||
let stuff = fs.readFileSync(instance.path("script-output", filename), "utf8").split("\n");
|
|
||||||
|
|
||||||
// if you found anything, reset the file
|
|
||||||
if (stuff[0]) {
|
|
||||||
fs.writeFileSync(instance.path("script-output", filename), "");
|
|
||||||
}
|
|
||||||
for (let o = 0; o < stuff.length; o++) {
|
|
||||||
if (stuff[o] && !stuff[o].includes('\u0000\u0000')) {
|
|
||||||
try {
|
|
||||||
plugins[i].scriptOutput(stuff[o]);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
pluginConfig.fileReadDelay || 0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(`Clusterio | Loaded plugin ${pluginsToLoad[i].name} in ${Date.now() - pluginLoadStarted}ms`);
|
|
||||||
} else {
|
|
||||||
// this plugin doesn't have a client portion. Maybe it runs on the master only?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // END OF INSTANCE START ---------------------------------------------------------------------
|
|
||||||
|
|
||||||
// string, function
|
// string, function
|
||||||
// returns [{modName:string,hash:string}, ... ]
|
// returns [{modName:string,hash:string}, ... ]
|
||||||
function hashMods(instance, callback) {
|
function hashMods(instance, callback) {
|
||||||
|
|||||||
@@ -1,125 +0,0 @@
|
|||||||
const fs = require("fs-extra");
|
|
||||||
const path = require("path");
|
|
||||||
const git = require("simple-git")("./sharedPlugins");
|
|
||||||
|
|
||||||
|
|
||||||
async function listPlugins() {
|
|
||||||
let plugins = await this.getPlugins();
|
|
||||||
plugins.forEach(plug => {
|
|
||||||
console.log(`${plug.name}`.padEnd(22).substr(0,22)+` - ${plug.description}`.substr(0,80-22));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getPlugins() {
|
|
||||||
let directories = await fs.readdir("./sharedPlugins");
|
|
||||||
let returnArray = [];
|
|
||||||
for(let i in directories){
|
|
||||||
let dir = directories[i];
|
|
||||||
let pluginContents = await fs.readdir(path.join("./sharedPlugins", dir));
|
|
||||||
// console.log(pluginContents)
|
|
||||||
if(pluginContents.includes("config.js") || pluginContents.includes("config.json")){
|
|
||||||
try{
|
|
||||||
var pluginConfig = require(path.join("./../../sharedPlugins", dir, "config"));
|
|
||||||
pluginConfig.pluginPath = path.join("./sharedPlugins", dir);
|
|
||||||
}catch(e){
|
|
||||||
console.log(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if plugin is enabled
|
|
||||||
try{
|
|
||||||
await fs.stat(path.join(pluginConfig.pluginPath, "DISABLED"))
|
|
||||||
pluginConfig.enabled = false;
|
|
||||||
}catch(e){
|
|
||||||
pluginConfig.enabled = true;
|
|
||||||
}
|
|
||||||
returnArray.push(pluginConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return returnArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addPlugin(path) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if(path.includes("git")){ // we are decently sure this is a git repo
|
|
||||||
git.clone(path, data => resolve(data))
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function removePlugin(name) {
|
|
||||||
let plugins = await this.getPlugins();
|
|
||||||
for(let i in plugins){
|
|
||||||
let plug = plugins[i];
|
|
||||||
if(plug.name.includes(name)){
|
|
||||||
// console.log(`Removing plugin ${plug.name}`);
|
|
||||||
await fs.remove(plug.pluginPath);
|
|
||||||
return {
|
|
||||||
ok:true,
|
|
||||||
msg:`Deleted plugin ${plug.name}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
ok:false,
|
|
||||||
msg:`Plugin matching "${name}" not found`,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function enablePlugin(name, instance) {
|
|
||||||
let plugins = await this.getPlugins();
|
|
||||||
let plugin = plugins[findInArray("name", name, plugins)[0]];
|
|
||||||
if(plugin){
|
|
||||||
let files = await fs.readdir(plugin.pluginPath);
|
|
||||||
if(files.includes("DISABLED")){
|
|
||||||
await fs.unlink(path.join(plugin.pluginPath, "DISABLED"));
|
|
||||||
return {
|
|
||||||
ok:true,
|
|
||||||
msg:`Globally enabled plugin ${name}`,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
ok:true,
|
|
||||||
msg:`Plugin ${name} already enabled`,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
ok:false,
|
|
||||||
msg:`Found no excact match for plugin ${name}`,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function disablePlugin(name, instance) {
|
|
||||||
let plugins = await this.getPlugins();
|
|
||||||
let plugin = plugins[findInArray("name", name, plugins)[0]];
|
|
||||||
if(plugin){
|
|
||||||
await fs.writeFile(path.join(plugin.pluginPath, "DISABLED"), "");
|
|
||||||
return {
|
|
||||||
ok:true,
|
|
||||||
msg:`Plugin ${name} is now disabled on this host`,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
ok:false,
|
|
||||||
msg:`Found no excact match for plugin ${name}`,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function findInArray(key, value, array) {
|
|
||||||
let indexes = [];
|
|
||||||
for(let i in array){
|
|
||||||
if(array[i][key] && array[i][key] === value) indexes.push(i);
|
|
||||||
}
|
|
||||||
return indexes;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
listPlugins,
|
|
||||||
getPlugins,
|
|
||||||
addPlugin,
|
|
||||||
removePlugin,
|
|
||||||
enablePlugin,
|
|
||||||
disablePlugin,
|
|
||||||
};
|
|
||||||
@@ -32,7 +32,6 @@ let config = {};
|
|||||||
|
|
||||||
// homebrew modules
|
// homebrew modules
|
||||||
const generateSSLcert = require("lib/generateSSLcert");
|
const generateSSLcert = require("lib/generateSSLcert");
|
||||||
const pluginManager = require("lib/manager/pluginManager");
|
|
||||||
const database = require("lib/database");
|
const database = require("lib/database");
|
||||||
const factorio = require("lib/factorio");
|
const factorio = require("lib/factorio");
|
||||||
const schema = require("lib/schema");
|
const schema = require("lib/schema");
|
||||||
@@ -502,46 +501,10 @@ io.on('connection', function (socket) {
|
|||||||
var masterPlugins = [];
|
var masterPlugins = [];
|
||||||
async function pluginManagement(){
|
async function pluginManagement(){
|
||||||
let startPluginLoad = Date.now();
|
let startPluginLoad = Date.now();
|
||||||
masterPlugins = await getPlugins();
|
// masterPlugins = await getPlugins();
|
||||||
console.log("All plugins loaded in "+(Date.now() - startPluginLoad)+"ms");
|
console.log("All plugins loaded in "+(Date.now() - startPluginLoad)+"ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getPlugins(){
|
|
||||||
let plugins = [];
|
|
||||||
let pluginsToLoad = await pluginManager.getPlugins();
|
|
||||||
for(let i = 0; i < pluginsToLoad.length; i++){
|
|
||||||
let pluginStartedLoading = Date.now(); // just for logging
|
|
||||||
let stats = await fs.stat(pluginsToLoad[i].pluginPath);
|
|
||||||
if(stats.isDirectory()){
|
|
||||||
let pluginConfig = pluginsToLoad[i];
|
|
||||||
if(pluginConfig.masterPlugin && pluginConfig.enabled){
|
|
||||||
let masterPlugin = require(path.resolve(pluginConfig.pluginPath, pluginConfig.masterPlugin));
|
|
||||||
plugins.push({
|
|
||||||
main:new masterPlugin({
|
|
||||||
config,
|
|
||||||
pluginConfig,
|
|
||||||
path: pluginConfig.pluginPath,
|
|
||||||
socketio: io,
|
|
||||||
express: app,
|
|
||||||
db,
|
|
||||||
Prometheus,
|
|
||||||
prometheusPrefix,
|
|
||||||
endpointHitCounter,
|
|
||||||
}),
|
|
||||||
pluginConfig,
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("Loaded plugin "+pluginConfig.name+" in "+(Date.now() - pluginStartedLoading)+"ms");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(let i in plugins){
|
|
||||||
let plugin = plugins[i];
|
|
||||||
if(plugin.main.onLoadFinish && typeof plugin.main.onLoadFinish == "function") await plugin.main.onLoadFinish({plugins});
|
|
||||||
}
|
|
||||||
return plugins;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls listen on server capturing any errors that occurs
|
* Calls listen on server capturing any errors that occurs
|
||||||
* binding to the port.
|
* binding to the port.
|
||||||
|
|||||||
@@ -65,7 +65,6 @@
|
|||||||
"socket.io-client": "^2.2.0",
|
"socket.io-client": "^2.2.0",
|
||||||
"socket.io-prometheus": "^0.2.1",
|
"socket.io-prometheus": "^0.2.1",
|
||||||
"sync-request": "^4.0.1",
|
"sync-request": "^4.0.1",
|
||||||
"tail": "^2.0.2",
|
|
||||||
"typescript-collections": "^1.3.2",
|
"typescript-collections": "^1.3.2",
|
||||||
"yargs": "^14.2.0"
|
"yargs": "^14.2.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
// required here in order to track coverage for them.
|
// required here in order to track coverage for them.
|
||||||
|
|
||||||
require('lib/manager/modManager');
|
require('lib/manager/modManager');
|
||||||
require('lib/manager/pluginManager');
|
|
||||||
require('lib/npmPostinstall.js');
|
require('lib/npmPostinstall.js');
|
||||||
require('lib/typedef');
|
require('lib/typedef');
|
||||||
require('../clusterctl.js');
|
require('../clusterctl.js');
|
||||||
Reference in new issue
Block a user