summary refs log tree commit diff
diff options
context:
space:
mode:
authorTheArcaneBrony <myrainbowdash949@gmail.com>2022-08-13 12:22:26 +0200
committerTheArcaneBrony <myrainbowdash949@gmail.com>2022-09-04 10:48:54 +0200
commit6d17f44f9b16fb78abf8a5689b63c88550b9b1a8 (patch)
tree898248e60883dceac343c93e6b4348ce5d5394bd
parentGit workflow - partial list of Ubuntu dependencies (diff)
downloadserver-6d17f44f9b16fb78abf8a5689b63c88550b9b1a8.tar.xz
Plugins finally load!
-rw-r--r--src/plugins/PluginIndex.ts6
-rw-r--r--src/plugins/example-plugin/ExamplePlugin.ts7
-rw-r--r--src/plugins/example-plugin/TestPlugin.ts12
-rw-r--r--src/plugins/example-plugin/plugin.json2
-rw-r--r--src/util/entities/PluginConfig.ts11
-rw-r--r--src/util/plugin/Plugin.ts35
-rw-r--r--src/util/plugin/PluginConfig.ts92
-rw-r--r--src/util/plugin/PluginLoader.ts22
-rw-r--r--src/util/plugin/PluginManifest.ts2
-rw-r--r--src/util/plugin/index.ts1
-rw-r--r--src/util/plugin/plugin_data_objects/ChannelCreateEventArgs.ts7
-rw-r--r--src/util/plugin/plugin_data_objects/GuildCreateEventArgs.ts7
-rw-r--r--src/util/plugin/plugin_data_objects/LoginEventArgs.ts7
-rw-r--r--src/util/plugin/plugin_data_objects/MessageEventArgs.ts7
-rw-r--r--src/util/plugin/plugin_data_objects/PluginLoadedEventArgs.ts3
-rw-r--r--src/util/plugin/plugin_data_objects/RegisterEventArgs.ts7
-rw-r--r--src/util/plugin/plugin_data_objects/TypingEventArgs.ts7
-rwxr-xr-xsrc/util/plugin/plugin_data_objects/_gen.sh21
-rw-r--r--src/util/plugin/plugin_data_objects/_pdo7
-rw-r--r--src/util/plugin/plugin_data_objects/_todo.txt1
-rw-r--r--src/util/plugin/plugin_data_objects/index.ts7
-rw-r--r--src/util/util/Environment.ts3
-rw-r--r--src/util/util/index.ts3
23 files changed, 249 insertions, 28 deletions
diff --git a/src/plugins/PluginIndex.ts b/src/plugins/PluginIndex.ts
new file mode 100644
index 00000000..502161a1
--- /dev/null
+++ b/src/plugins/PluginIndex.ts
@@ -0,0 +1,6 @@
+import { Plugin } from "util/plugin";
+import * as example_plugin from "./example-plugin/TestPlugin";
+
+export const PluginIndex: any = {
+    "example-plugin": new example_plugin.default(),
+};
\ No newline at end of file
diff --git a/src/plugins/example-plugin/ExamplePlugin.ts b/src/plugins/example-plugin/ExamplePlugin.ts
deleted file mode 100644
index e6f70657..00000000
--- a/src/plugins/example-plugin/ExamplePlugin.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Plugin } from "@fosscord/util";
-
-export default class TestPlugin extends Plugin {
-    onPluginLoaded(): void {
-        console.log("Hello from test plugin! IT WORKS!!!!!!!");
-    }
-}
\ No newline at end of file
diff --git a/src/plugins/example-plugin/TestPlugin.ts b/src/plugins/example-plugin/TestPlugin.ts
new file mode 100644
index 00000000..7a86aab2
--- /dev/null
+++ b/src/plugins/example-plugin/TestPlugin.ts
@@ -0,0 +1,12 @@
+import { Plugin } from "@fosscord/util";
+
+export default class TestPlugin implements Plugin {
+    pluginPath: string;
+    async initConfig(): Promise<void> {
+        
+    }
+    onPluginLoaded() {
+        console.log("Test plugin active!");
+    }
+    
+}
\ No newline at end of file
diff --git a/src/plugins/example-plugin/plugin.json b/src/plugins/example-plugin/plugin.json
index 2fcb7a00..f6c1b7ff 100644
--- a/src/plugins/example-plugin/plugin.json
+++ b/src/plugins/example-plugin/plugin.json
@@ -6,5 +6,5 @@
     ],
     "repository": "https://github.com/fosscord/fosscord-server",
     "license": "",
-    "index": "ExamplePlugin.js"
+    "mainClass": "TestPlugin"
 }
diff --git a/src/util/entities/PluginConfig.ts b/src/util/entities/PluginConfig.ts
new file mode 100644
index 00000000..a1364912
--- /dev/null
+++ b/src/util/entities/PluginConfig.ts
@@ -0,0 +1,11 @@
+import { Column, Entity } from "typeorm";
+import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass";
+
+@Entity("plugin_config")
+export class PluginConfigEntity extends BaseClassWithoutId {
+	@PrimaryIdColumn()
+	key: string;
+
+	@Column({ type: "simple-json", nullable: true })
+	value: number | boolean | null | string | undefined;
+}
\ No newline at end of file
diff --git a/src/util/plugin/Plugin.ts b/src/util/plugin/Plugin.ts
index 1c86a006..0fb1732f 100644
--- a/src/util/plugin/Plugin.ts
+++ b/src/util/plugin/Plugin.ts
@@ -1,5 +1,5 @@
 import EventEmitter from "events";
-import { TypedEventEmitter } from "@fosscord/util";
+import { PluginLoadedEventArgs, TypedEventEmitter } from "@fosscord/util";
 
 type PluginEvents = {
 	error: (error: Error | unknown) => void;
@@ -7,14 +7,31 @@ type PluginEvents = {
 };
 
 //this doesnt work, check later:
- //(EventEmitter as new () => TypedEventEmitter<PluginEvents>) {
-export class Plugin extends EventEmitter {
-	private _untypedOn = this.on
-	private _untypedEmit = this.emit
-	public on = <K extends keyof PluginEvents>(event: K, listener: PluginEvents[K]): this => this._untypedOn(event, listener)
-	public emit = <K extends keyof PluginEvents>(event: K, ...args: Parameters<PluginEvents[K]>): boolean => this._untypedEmit(event, ...args)
-
-	async init() {
+ //EventEmitter as new () => TypedEventEmitter<PluginEvents>
+export class Plugin {
+	/**
+	 * Path the plugin resides in.
+	 *
+	 * @type {string}
+	 * @memberof Plugin
+	 */
+	pluginPath: string;
+	/**
+	 *
+	 *
+	 * @memberof Plugin
+	 */
+	async initConfig() {
 		// insert default config into database?
+		console.log("did you forget to implement initConfig?");
+	}
+	/**
+	 *	
+	 *
+	 * @param {PluginLoadedEventArgs} args Info about plugin environment
+	 * @memberof Plugin
+	 */
+	onPluginLoaded?(args?: PluginLoadedEventArgs) {
+		
 	}
 }
diff --git a/src/util/plugin/PluginConfig.ts b/src/util/plugin/PluginConfig.ts
new file mode 100644
index 00000000..c7a7db87
--- /dev/null
+++ b/src/util/plugin/PluginConfig.ts
@@ -0,0 +1,92 @@
+import { ConfigEntity } from "../entities/Config";
+import fs from "fs";
+import { OrmUtils, Environment } from "..";
+
+// TODO: yaml instead of json
+const overridePath = process.env.PLUGIN_CONFIG_PATH ?? "";
+
+let config: any;
+let pairs: ConfigEntity[];
+
+// TODO: use events to inform about config updates
+// Config keys are separated with _
+
+export const Config = {
+	init: async function init() {
+		if (config) return config;
+		console.log('[Config] Loading configuration...')
+		pairs = await ConfigEntity.find();
+		config = pairsToConfig(pairs);
+		//config = (config || {}).merge(new ConfigValue());
+		//config = OrmUtils.mergeDeep(new ConfigValue(), config)
+
+		if(process.env.CONFIG_PATH)
+			try {
+				const overrideConfig = JSON.parse(fs.readFileSync(overridePath, { encoding: "utf8" }));
+				config = overrideConfig.merge(config);
+			} catch (error) {
+				fs.writeFileSync(overridePath, JSON.stringify(config, null, 4));
+			}
+		
+		return this.set(config);
+	},
+	get: function get() {
+		if(!config) {
+			if(Environment.isDebug)
+				console.log("Oops.. trying to get config without config existing... Returning defaults... (Is the database still initialising?)");
+			return {};
+		}
+		return config;
+	},
+	set: function set(val: Partial<any>) {
+		if (!config || !val) return;
+		config = val.merge(config);
+
+		return applyConfig(config);
+	},
+};
+
+function applyConfig(val: any) {
+	async function apply(obj: any, key = ""): Promise<any> {
+		if (typeof obj === "object" && obj !== null)
+			return Promise.all(Object.keys(obj).map((k) => apply(obj[k], key ? `${key}_${k}` : k)));
+
+		let pair = pairs.find((x) => x.key === key);
+		if (!pair) pair = new ConfigEntity();
+
+		pair.key = key;
+		pair.value = obj;
+		return pair.save();
+	}
+	if(process.env.CONFIG_PATH) {
+		if(Environment.isDebug)
+			console.log(`Writing config: ${process.env.CONFIG_PATH}`)
+		fs.writeFileSync(overridePath, JSON.stringify(val, null, 4));
+	}
+
+	return apply(val);
+}
+
+function pairsToConfig(pairs: ConfigEntity[]) {
+	let value: any = {};
+
+	pairs.forEach((p) => {
+		const keys = p.key.split("_");
+		let obj = value;
+		let prev = "";
+		let prevObj = obj;
+		let i = 0;
+
+		for (const key of keys) {
+			if (!isNaN(Number(key)) && !prevObj[prev]?.length) prevObj[prev] = obj = [];
+			if (i++ === keys.length - 1) obj[key] = p.value;
+			else if (!obj[key]) obj[key] = {};
+
+			prev = key;
+			prevObj = obj;
+			obj = obj[key];
+		}
+	});
+
+	return value;
+}
diff --git a/src/util/plugin/PluginLoader.ts b/src/util/plugin/PluginLoader.ts
index e69cb499..8c140d29 100644
--- a/src/util/plugin/PluginLoader.ts
+++ b/src/util/plugin/PluginLoader.ts
@@ -1,11 +1,13 @@
 import path from "path";
 import fs from "fs";
-import { Plugin, PluginManifest } from "./";
+import { Plugin, PluginLoadedEventArgs, PluginManifest } from "./";
+import { PluginIndex } from "plugins/PluginIndex";
 
 const root = process.env.PLUGIN_LOCATION || "dist/plugins";
 
 let pluginsLoaded = false;
 export class PluginLoader {
+	public static plugins: Plugin[] = [];
 	public static loadPlugins() {
 		console.log(`Plugin root directory: ${path.resolve(root)}`);
 		const dirs = fs.readdirSync(root).filter((x) => {
@@ -17,6 +19,9 @@ export class PluginLoader {
 			}
 		});
 		console.log(dirs);
+		PluginIndex.forEach((x: any)=>{
+			console.log(x.onPluginLoaded)
+		})
 		dirs.forEach(async (x) => {
 			let modPath = path.resolve(path.join(root, x));
 			console.log(`Trying to load plugin: ${modPath}`);
@@ -24,16 +29,13 @@ export class PluginLoader {
 			console.log(
 				`Plugin info: ${manifest.name} (${manifest.id}), written by ${manifest.authors}, available at ${manifest.repository}`
 			);
-			const module_ = require(path.join(modPath, manifest.index)) as Plugin;
-			try {
-				await module_.init();
-				module_.emit("loaded");
-			} catch (error) {
-				module_.emit("error", error);
-			}
+			const module_ = PluginIndex["example-plugin"];
+			
+			module_.pluginPath = modPath;
+			if(module_.onPluginLoaded) module_.onPluginLoaded({} as PluginLoadedEventArgs); 
+			this.plugins.push(module_);
 		});
 
-		//
-		//module_.pluginPath =
+		console.log(`Done loading ${this.plugins.length} plugins!`)
 	}
 }
diff --git a/src/util/plugin/PluginManifest.ts b/src/util/plugin/PluginManifest.ts
index 01b2b084..79ecc465 100644
--- a/src/util/plugin/PluginManifest.ts
+++ b/src/util/plugin/PluginManifest.ts
@@ -6,5 +6,5 @@ export class PluginManifest {
     license: string;
 	version: string // semver
 	versionCode: number // integer
-    index: string;
+    mainClass: string;
 }
\ No newline at end of file
diff --git a/src/util/plugin/index.ts b/src/util/plugin/index.ts
index c4c0c2ac..5974a065 100644
--- a/src/util/plugin/index.ts
+++ b/src/util/plugin/index.ts
@@ -1,3 +1,4 @@
 export * from "./Plugin";
 export * from "./PluginLoader";
 export * from "./PluginManifest";
+export * from "./plugin_data_objects/index";
diff --git a/src/util/plugin/plugin_data_objects/ChannelCreateEventArgs.ts b/src/util/plugin/plugin_data_objects/ChannelCreateEventArgs.ts
new file mode 100644
index 00000000..ce7dec87
--- /dev/null
+++ b/src/util/plugin/plugin_data_objects/ChannelCreateEventArgs.ts
@@ -0,0 +1,7 @@
+export interface PreChannelCreateEventArgs {
+  
+}
+
+export interface OnChannelCreateEventArgs {
+  
+}
diff --git a/src/util/plugin/plugin_data_objects/GuildCreateEventArgs.ts b/src/util/plugin/plugin_data_objects/GuildCreateEventArgs.ts
new file mode 100644
index 00000000..e10e675a
--- /dev/null
+++ b/src/util/plugin/plugin_data_objects/GuildCreateEventArgs.ts
@@ -0,0 +1,7 @@
+export interface PreGuildCreateEventArgs {
+  
+}
+
+export interface OnGuildCreateEventArgs {
+  
+}
diff --git a/src/util/plugin/plugin_data_objects/LoginEventArgs.ts b/src/util/plugin/plugin_data_objects/LoginEventArgs.ts
new file mode 100644
index 00000000..391b852e
--- /dev/null
+++ b/src/util/plugin/plugin_data_objects/LoginEventArgs.ts
@@ -0,0 +1,7 @@
+export interface PreLoginEventArgs {
+  
+}
+
+export interface OnLoginEventArgs {
+  
+}
diff --git a/src/util/plugin/plugin_data_objects/MessageEventArgs.ts b/src/util/plugin/plugin_data_objects/MessageEventArgs.ts
new file mode 100644
index 00000000..0a3498c2
--- /dev/null
+++ b/src/util/plugin/plugin_data_objects/MessageEventArgs.ts
@@ -0,0 +1,7 @@
+export interface PreMessageEventArgs {
+  
+}
+
+export interface OnMessageEventArgs {
+  
+}
diff --git a/src/util/plugin/plugin_data_objects/PluginLoadedEventArgs.ts b/src/util/plugin/plugin_data_objects/PluginLoadedEventArgs.ts
new file mode 100644
index 00000000..58829f15
--- /dev/null
+++ b/src/util/plugin/plugin_data_objects/PluginLoadedEventArgs.ts
@@ -0,0 +1,3 @@
+export interface PluginLoadedEventArgs {
+    
+}
\ No newline at end of file
diff --git a/src/util/plugin/plugin_data_objects/RegisterEventArgs.ts b/src/util/plugin/plugin_data_objects/RegisterEventArgs.ts
new file mode 100644
index 00000000..7f7c0c76
--- /dev/null
+++ b/src/util/plugin/plugin_data_objects/RegisterEventArgs.ts
@@ -0,0 +1,7 @@
+export interface PreRegisterEventArgs {
+  
+}
+
+export interface OnRegisterEventArgs {
+  
+}
diff --git a/src/util/plugin/plugin_data_objects/TypingEventArgs.ts b/src/util/plugin/plugin_data_objects/TypingEventArgs.ts
new file mode 100644
index 00000000..f6660692
--- /dev/null
+++ b/src/util/plugin/plugin_data_objects/TypingEventArgs.ts
@@ -0,0 +1,7 @@
+export interface PreTypingEventArgs {
+  
+}
+
+export interface OnTypingEventArgs {
+  
+}
diff --git a/src/util/plugin/plugin_data_objects/_gen.sh b/src/util/plugin/plugin_data_objects/_gen.sh
new file mode 100755
index 00000000..9fbd1749
--- /dev/null
+++ b/src/util/plugin/plugin_data_objects/_gen.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+while read event
+do
+    if [ ! -f "${event}EventArgs.ts" ]
+    then
+        echo Making event $event...
+        (
+            echo "export interface Pre${event}EventArgs {"
+            echo '  '
+            echo '}'
+            echo ''
+            echo "export interface On${event}EventArgs {"
+            echo '  '
+            echo '}'
+        ) > ${event}EventArgs.ts
+    fi
+done < _pdo
+
+echo ''
+
+node ../../../../scripts/gen_index.js .. --recursive
\ No newline at end of file
diff --git a/src/util/plugin/plugin_data_objects/_pdo b/src/util/plugin/plugin_data_objects/_pdo
new file mode 100644
index 00000000..fa207f77
--- /dev/null
+++ b/src/util/plugin/plugin_data_objects/_pdo
@@ -0,0 +1,7 @@
+Register
+Message
+Login
+GuildCreate
+ChannelCreate
+Typing
+StatusChange
\ No newline at end of file
diff --git a/src/util/plugin/plugin_data_objects/_todo.txt b/src/util/plugin/plugin_data_objects/_todo.txt
new file mode 100644
index 00000000..a6a78c7e
--- /dev/null
+++ b/src/util/plugin/plugin_data_objects/_todo.txt
@@ -0,0 +1 @@
+Voice events when we do voice.
\ No newline at end of file
diff --git a/src/util/plugin/plugin_data_objects/index.ts b/src/util/plugin/plugin_data_objects/index.ts
new file mode 100644
index 00000000..c75d43f9
--- /dev/null
+++ b/src/util/plugin/plugin_data_objects/index.ts
@@ -0,0 +1,7 @@
+export * from "./ChannelCreateEventArgs";
+export * from "./GuildCreateEventArgs";
+export * from "./LoginEventArgs";
+export * from "./MessageEventArgs";
+export * from "./PluginLoadedEventArgs";
+export * from "./RegisterEventArgs";
+export * from "./TypingEventArgs";
diff --git a/src/util/util/Environment.ts b/src/util/util/Environment.ts
new file mode 100644
index 00000000..a6d68785
--- /dev/null
+++ b/src/util/util/Environment.ts
@@ -0,0 +1,3 @@
+export class Environment {
+    static isDebug: boolean = /--debug|--inspect/.test(process.execArgv.join(' '));
+}
diff --git a/src/util/util/index.ts b/src/util/util/index.ts
index 11f0b72a..8135c107 100644
--- a/src/util/util/index.ts
+++ b/src/util/util/index.ts
@@ -23,3 +23,6 @@ export * from "./Snowflake";
 export * from "./String";
 export * from "./Token";
 export * from "./TraverseDirectory";
+export * from "./InvisibleCharacters";
+export * from "./Environment";
+export * from "./Paths";
\ No newline at end of file