diff --git a/languages/spanish.json b/languages/spanish.json index d5398e3..da41fd5 100644 --- a/languages/spanish.json +++ b/languages/spanish.json @@ -2,7 +2,7 @@ "_TRANSLATION":{ "otversion":"v4.0.0", "translator":"Redactado & Josuens", - "lastedited":"22/8/2024", + "lastedited":"22/08/2024", "language":"Spanish" }, "checker":{ diff --git a/package.json b/package.json index 681b0d8..a497fb4 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "scripts": { "build": "node index.js -%-compile", "start": "node index.js", - "test": "node index.js --dev-config --dev-database" + "test": "node index.js --dev-config --dev-database", + "testnc": "node index.js --no-compile --dev-config --dev-database" }, "type": "commonjs", "license": "GPL-3.0-only", diff --git a/src/core/api/api.ts b/src/core/api/api.ts index 387de94..7f393a0 100644 --- a/src/core/api/api.ts +++ b/src/core/api/api.ts @@ -32,6 +32,7 @@ export * from "./defaults/base" export * from "./defaults/event" export * from "./defaults/config" export * from "./defaults/database" +export * from "./defaults/plugin" export * from "./defaults/checker" export * from "./defaults/client" export * from "./defaults/language" diff --git a/src/core/api/defaults/checker.ts b/src/core/api/defaults/checker.ts index e12773d..24ada35 100644 --- a/src/core/api/defaults/checker.ts +++ b/src/core/api/defaults/checker.ts @@ -65,6 +65,7 @@ export class ODCheckerRenderer_Default extends ODCheckerRenderer { horizontalFiller: string = "=" verticalFiller: string = "|" descriptionSeparator: string = " => " + headerSeparator: string = " => " footerTipPrefix: string = "=> " disableHeader: boolean = false @@ -93,7 +94,7 @@ export class ODCheckerRenderer_Default extends ODCheckerRenderer { if (!renderEmpty && !hasErrors && !hasWarnings && (!hasInfo || compact)) return [] - const headerText = ansis.bold.hex("#f8ba00")(t.headerOpenticket)+" "+t.headerConfigchecker+" => "+ansis.hex("#f8ba00")(t.headerDescription) + const headerText = ansis.bold.hex("#f8ba00")(t.headerOpenticket)+" "+t.headerConfigchecker+this.headerSeparator+ansis.hex("#f8ba00")(t.headerDescription) const footerErrorText = (hasErrors) ? this.footerTipPrefix+ansis.gray(tm.insertTranslationParams(t.footerError,[ansis.bold.red(t.error)])) : "" const footerWarningText = (hasWarnings) ? this.footerTipPrefix+ansis.gray(tm.insertTranslationParams(t.footerWarning,[ansis.bold.yellow(t.warning)])) : "" const footerSupportText = tm.insertTranslationParams(t.footerSupport,[ansis.green("https://discord.dj-dj.be"),ansis.green("https://otdocs.dj-dj.be")]) diff --git a/src/core/api/defaults/event.ts b/src/core/api/defaults/event.ts index c9b02b1..200af2d 100644 --- a/src/core/api/defaults/event.ts +++ b/src/core/api/defaults/event.ts @@ -3,7 +3,6 @@ /////////////////////////////////////// //BASE MODULES import { ODPromiseVoid, ODValidId } from "../modules/base" -import { ODPluginClassManager, ODPluginEventManager, ODPluginManager } from "../modules/plugin" import { ODConsoleManager, ODError } from "../modules/console" import { ODCheckerResult, ODCheckerStorage } from "../modules/checker" import { ODDefaultsManager } from "../modules/defaults" @@ -13,7 +12,7 @@ import { ODEvent, ODEventManager } from "../modules/event" import * as discord from "discord.js" //DEFAULT MODULES -import { ODVersionManager_Default } from "./base" +import { ODPluginClassManager_Default, ODPluginManager_Default } from "./plugin" import { ODConfigManager_Default} from "./config" import { ODDatabaseManager_Default } from "./database" import { ODFlagManager_Default } from "./flag" @@ -53,12 +52,9 @@ export interface ODEventIds_Default { "afterErrorHandling": ODEvent_Default<(error:Error, origin:NodeJS.UncaughtExceptionOrigin, message:ODError) => ODPromiseVoid> //plugins - "afterPluginsLoaded": ODEvent_Default<(plugins:ODPluginManager) => ODPromiseVoid> - "onPluginClassLoad": ODEvent_Default<(classes:ODPluginClassManager, plugins:ODPluginManager) => ODPromiseVoid> - "afterPluginClassesLoaded": ODEvent_Default<(classes:ODPluginClassManager, plugins:ODPluginManager) => ODPromiseVoid> - "onPluginEventLoad": ODEvent_Default<(classes:ODPluginEventManager, plugins:ODPluginManager) => ODPromiseVoid> - "afterPluginEventsLoaded": ODEvent_Default<(classes:ODPluginEventManager, plugins:ODPluginManager) => ODPromiseVoid> - + "afterPluginsLoaded": ODEvent_Default<(plugins:ODPluginManager_Default) => ODPromiseVoid> + "onPluginClassLoad": ODEvent_Default<(classes:ODPluginClassManager_Default, plugins:ODPluginManager_Default) => ODPromiseVoid> + "afterPluginClassesLoaded": ODEvent_Default<(classes:ODPluginClassManager_Default, plugins:ODPluginManager_Default) => ODPromiseVoid> "onFlagLoad": ODEvent_Default<(flags:ODFlagManager_Default) => ODPromiseVoid> "afterFlagsLoaded": ODEvent_Default<(flags:ODFlagManager_Default) => ODPromiseVoid> @@ -277,6 +273,9 @@ export interface ODEventIds_Default { "afterStartScreensLoaded": ODEvent_Default<(startscreen:ODStartScreenManager_Default) => ODPromiseVoid> "onStartScreenRender": ODEvent_Default<(startscreen:ODStartScreenManager_Default) => ODPromiseVoid> "afterStartScreensRendered": ODEvent_Default<(startscreen:ODStartScreenManager_Default) => ODPromiseVoid> + + //ready + "onReadyForUsage": ODEvent_Default<() => ODPromiseVoid> } /**## ODEventManager_Default `default_class` diff --git a/src/core/api/defaults/plugin.ts b/src/core/api/defaults/plugin.ts new file mode 100644 index 0000000..4bd5f77 --- /dev/null +++ b/src/core/api/defaults/plugin.ts @@ -0,0 +1,77 @@ +/////////////////////////////////////// +//DEFAULT POST MODULE +/////////////////////////////////////// +import { ODValidId, ODManagerData } from "../modules/base" +import { ODPlugin, ODPluginClassManager, ODPluginManager } from "../modules/plugin" + +/**## ODPluginManagerIds_Default `type` + * This type is an array of ids available in the `ODPluginManager_Default` class. + * It's used to generate typescript declarations for this class. + */ +export interface ODPluginManagerIds_Default {} + +/**## ODPluginManager_Default `default_class` + * This is a special class that adds type definitions & typescript to the ODPluginManager class. + * It doesn't add any extra features! + * + * This default class is made for the global variable `openticket.plugins`! + */ +export class ODPluginManager_Default extends ODPluginManager { + declare classes: ODPluginClassManager_Default + + get(id:PluginId): ODPluginManagerIds_Default[PluginId] + get(id:ODValidId): ODPlugin|null + + get(id:ODValidId): ODPlugin|null { + return super.get(id) + } + + remove(id:PluginId): ODPluginManagerIds_Default[PluginId] + remove(id:ODValidId): ODPlugin|null + + remove(id:ODValidId): ODPlugin|null { + return super.remove(id) + } + + exists(id:keyof ODPluginManagerIds_Default): boolean + exists(id:ODValidId): boolean + + exists(id:ODValidId): boolean { + return super.exists(id) + } +} + +/**## ODPluginClassManagerIds_Default `type` + * This type is an array of ids available in the `ODPluginClassManager_Default` class. + * It's used to generate typescript declarations for this class. + */ +export interface ODPluginClassManagerIds_Default {} + +/**## ODPluginClassManager_Default `default_class` + * This is a special class that adds type definitions & typescript to the ODPluginClassManager class. + * It doesn't add any extra features! + * + * This default class is made for the global variable `openticket.plugins.classes`! + */ +export class ODPluginClassManager_Default extends ODPluginClassManager { + get(id:PluginClassId): ODPluginClassManagerIds_Default[PluginClassId] + get(id:ODValidId): ODManagerData|null + + get(id:ODValidId): ODManagerData|null { + return super.get(id) + } + + remove(id:PluginClassId): ODPluginClassManagerIds_Default[PluginClassId] + remove(id:ODValidId): ODManagerData|null + + remove(id:ODValidId): ODManagerData|null { + return super.remove(id) + } + + exists(id:keyof ODPluginClassManagerIds_Default): boolean + exists(id:ODValidId): boolean + + exists(id:ODValidId): boolean { + return super.exists(id) + } +} \ No newline at end of file diff --git a/src/core/api/main.ts b/src/core/api/main.ts index 84a3873..b65ab05 100644 --- a/src/core/api/main.ts +++ b/src/core/api/main.ts @@ -1,12 +1,12 @@ //BASE MODULES import { ODEnvHelper, ODVersion } from "./modules/base" -import { ODPluginManager } from "./modules/plugin" import { ODConsoleManager, ODConsoleMessage, ODConsoleMessageParam, ODConsoleMessageTypes, ODDebugFileManager, ODDebugger, ODError } from "./modules/console" import { ODCheckerStorage } from "./modules/checker" import { ODDefaultsManager } from "./modules/defaults" //DEFAULT MODULES import { ODVersionManager_Default } from "./defaults/base" +import { ODPluginManager_Default } from "./defaults/plugin" import { ODEventManager_Default } from "./defaults/event" import { ODConfigManager_Default} from "./defaults/config" import { ODDatabaseManager_Default } from "./defaults/database" @@ -57,7 +57,7 @@ export class ODMain { events: ODEventManager_Default /**The manager that handles & executes all plugins in the bot. */ - plugins: ODPluginManager + plugins: ODPluginManager_Default /**The manager that manages & checks all the console flags of the bot. (like `--debug`) */ flags: ODFlagManager_Default /**The manager that manages & contains all the config files of the bot. (like `config/general.json`) */ @@ -132,7 +132,7 @@ export class ODMain { this.debug = new ODDebugger(this.console) this.events = new ODEventManager_Default(this.debug) - this.plugins = new ODPluginManager(this.debug) + this.plugins = new ODPluginManager_Default(this.debug) this.flags = new ODFlagManager_Default(this.debug) this.configs = new ODConfigManager_Default(this.debug) this.databases = new ODDatabaseManager_Default(this.debug) diff --git a/src/core/api/modules/checker.ts b/src/core/api/modules/checker.ts index 90d0249..956867d 100644 --- a/src/core/api/modules/checker.ts +++ b/src/core/api/modules/checker.ts @@ -367,7 +367,7 @@ export class ODChecker extends ODManagerData { type,message, path:this.locationTraceToString(locationTrace), - filepath:this.config.file, + filepath:this.config.path, translationParams, messageDocs:docs, diff --git a/src/core/api/modules/config.ts b/src/core/api/modules/config.ts index a875946..a53ad50 100644 --- a/src/core/api/modules/config.ts +++ b/src/core/api/modules/config.ts @@ -67,8 +67,10 @@ export class ODConfigManager extends ODManager { * You will only use this class if you want to create your own config implementation (e.g. `yml`, `xml`,...)! */ export class ODConfig extends ODManagerData { - /**The full path to this config with extension */ + /**The name of the file with extension. */ file: string = "" + /**The path to the file relative to the main directory. */ + path: string = "" /**An object/array of the entire config file! Variables inside it can be edited while the bot is running! */ data: any = undefined } @@ -87,9 +89,9 @@ export class ODJsonConfig extends ODConfig { constructor(id:ODValidId, file:string, customPath?:string){ super(id) try { - const filename = (file.endsWith(".json")) ? file : file+".json" - this.file = customPath ? nodepath.join("./",customPath,filename) : nodepath.join("./config/",filename) - this.data = JSON.parse(fs.readFileSync(this.file).toString()) + this.file = (file.endsWith(".json")) ? file : file+".json" + this.path = customPath ? nodepath.join("./",customPath,this.file) : nodepath.join("./config/",this.file) + this.data = JSON.parse(fs.readFileSync(this.path).toString()) }catch(err){ process.emit("uncaughtException",err) throw new ODSystemError("Config \""+nodepath.join("./",customPath ?? "./config/",file)+"\" doesn't exist!") diff --git a/src/core/api/modules/defaults.ts b/src/core/api/modules/defaults.ts index b4b2030..352c4ac 100644 --- a/src/core/api/modules/defaults.ts +++ b/src/core/api/modules/defaults.ts @@ -20,8 +20,6 @@ export interface ODDefaults { /**Load the default open ticket plugin classes. */ pluginClassLoading:boolean, - /**Load the default open ticket plugin events. */ - pluginEventLoading:boolean, /**Load the default open ticket flags. */ flagLoading:boolean, @@ -225,7 +223,6 @@ export class ODDefaultsManager { softPluginLoading:false, pluginClassLoading:true, - pluginEventLoading:true, flagLoading:true, flagInitiating:true, diff --git a/src/core/api/modules/language.ts b/src/core/api/modules/language.ts index 0a4c8c5..253342b 100644 --- a/src/core/api/modules/language.ts +++ b/src/core/api/modules/language.ts @@ -7,7 +7,10 @@ import { ODDebugger } from "./console" import fs from "fs" export class ODLanguage extends ODManagerData { + /**The name of the file with `.json` extension. */ file: string + /**The path to the file relative to the main directory. */ + path: string data: any metadata: { otversion:string, @@ -19,9 +22,9 @@ export class ODLanguage extends ODManagerData { constructor(id:ODValidId, file:string, customPath?:string){ super(id) try{ - const filename = (file.endsWith(".json")) ? file : file+".json" - this.file = customPath ? nodepath.join("./",customPath,filename) : nodepath.join("./languages/",filename) - this.data = JSON.parse(fs.readFileSync(this.file).toString()) + this.file = (file.endsWith(".json")) ? file : file+".json" + this.path = customPath ? nodepath.join("./",customPath,this.file) : nodepath.join("./languages/",this.file) + this.data = JSON.parse(fs.readFileSync(this.path).toString()) }catch(err){ process.emit("uncaughtException",err) throw new ODSystemError("Language \""+nodepath.join("./",customPath ?? "./languages/",file)+"\" doesn't exist!") diff --git a/src/core/api/modules/plugin.ts b/src/core/api/modules/plugin.ts index ac01ef4..99b568d 100644 --- a/src/core/api/modules/plugin.ts +++ b/src/core/api/modules/plugin.ts @@ -11,13 +11,11 @@ export interface ODUnknownCrashedPlugin { } export class ODPluginManager extends ODManager { - events: ODPluginEventManager classes: ODPluginClassManager unknownCrashedPlugins: ODUnknownCrashedPlugin[] = [] constructor(debug:ODDebugger){ super(debug,"plugin") - this.events = new ODPluginEventManager(debug) this.classes = new ODPluginClassManager(debug) } @@ -147,91 +145,6 @@ export class ODPlugin extends ODManagerData { } } -export class ODPluginEvent extends ODManagerData { - listeners: Function[] = [] - oncelisteners: Function[] = [] - - getCurrentListeners(){ - const final: Function[] = [] - this.oncelisteners.forEach((l) => final.push(l)) - this.listeners.forEach((l) => final.push(l)) - - this.oncelisteners = [] - return final - } -} - -export class ODPluginEventManager extends ODManager { - #debug: ODDebugger - listenerLimit: number = 25 - - constructor(debug:ODDebugger){ - super(debug,"plugin event") - this.#debug = debug - } - - setListenerLimit(limit:number){ - this.listenerLimit = limit - } - - on(event:string, callback:Function){ - const eventdata = this.get(event) - if (eventdata){ - eventdata.listeners.push(callback) - - if (eventdata.listeners.length > this.listenerLimit){ - this.#debug.console.log(new ODConsoleWarningMessage("Possible plugin event memory leak detected!",[ - {key:"event",value:event}, - {key:"listeners",value:eventdata.listeners.length.toString()} - ])) - } - }else{ - throw new ODSystemError("unknown plugin event \""+event+"\"") - } - } - - once(event:string, callback:Function){ - const eventdata = this.get(event) - if (eventdata){ - eventdata.oncelisteners.push(callback) - - }else{ - throw new ODSystemError("unknown plugin event \""+event+"\"") - } - } - - wait(event:string): Promise { - return new Promise((resolve,reject) => { - const eventdata = this.get(event) - if (eventdata){ - eventdata.oncelisteners.push((...args:any) => {resolve(args)}) - }else{ - reject("unknown plugin event \""+event+"\"") - } - }) - } - - emit(event:string, params:any[]): Promise { - return new Promise(async (resolve,reject) => { - const eventdata = this.get(event) - if (eventdata){ - const listeners = eventdata.getCurrentListeners() - - for (const listener of listeners){ - try { - await listener(...params) - }catch(err){ - process.emit("uncaughtException",err) - } - } - resolve() - }else{ - reject("unknown plugin event \""+event+"\"") - } - }) - } -} - export class ODPluginClassManager extends ODManager { constructor(debug:ODDebugger){ super(debug,"plugin class") diff --git a/src/data/framework/checkerLoader.ts b/src/data/framework/checkerLoader.ts index 76d5963..88993f2 100644 --- a/src/data/framework/checkerLoader.ts +++ b/src/data/framework/checkerLoader.ts @@ -18,17 +18,14 @@ export const loadAllConfigCheckerFunctions = async () => { export const loadAllConfigCheckerTranslations = async () => { if ((generalConfig && generalConfig.data.system && generalConfig.data.system.useTranslatedConfigChecker) ? generalConfig.data.system.useTranslatedConfigChecker : false){ - registerDefaultCheckerSystemTranslations() //translate checker system text - registerDefaultCheckerMessageTranslations() //translate checker messages - registerDefaultCheckerCustomTranslations() //translate custom checker messages + registerDefaultCheckerSystemTranslations(openticket.checkers.translation,openticket.languages) //translate checker system text + registerDefaultCheckerMessageTranslations(openticket.checkers.translation,openticket.languages) //translate checker messages + registerDefaultCheckerCustomTranslations(openticket.checkers.translation,openticket.languages) //translate custom checker messages } } //GLOBAL FUNCTIONS -export const registerDefaultCheckerSystemTranslations = () => { - const tm = openticket.checkers.translation - const lm = openticket.languages - +export const registerDefaultCheckerSystemTranslations = (tm:api.ODCheckerTranslationRegister_Default,lm:api.ODLanguageManager_Default) => { //SYSTEM //tm.quickTranslate(lm,"checker.system.headerOpenTicket","other","openticket:header-openticket") //OPEN TICKET (ignore) tm.quickTranslate(lm,"checker.system.typeError","other","openticket:type-error") // [ERROR] (ignore) @@ -45,10 +42,7 @@ export const registerDefaultCheckerSystemTranslations = () => { tm.quickTranslate(lm,"checker.system.dataMessages","other","openticket:data-message") // message } -export const registerDefaultCheckerMessageTranslations = () => { - const tm = openticket.checkers.translation - const lm = openticket.languages - +export const registerDefaultCheckerMessageTranslations = (tm:api.ODCheckerTranslationRegister_Default,lm:api.ODLanguageManager_Default) => { //STRUCTURES tm.quickTranslate(lm,"checker.messages.invalidType","message","openticket:invalid-type") // This property needs to be the type: {0}! tm.quickTranslate(lm,"checker.messages.propertyMissing","message","openticket:property-missing") // The property {0} is missing from this object! @@ -113,10 +107,7 @@ export const registerDefaultCheckerMessageTranslations = () => { tm.quickTranslate(lm,"checker.messages.idNonExistent","message","openticket:id-non-existent") // The id {0} doesn't exist! } -export const registerDefaultCheckerCustomTranslations = () => { - const tm = openticket.checkers.translation - const lm = openticket.languages - +export const registerDefaultCheckerCustomTranslations = (tm:api.ODCheckerTranslationRegister_Default,lm:api.ODLanguageManager_Default) => { //CUSTOM tm.quickTranslate(lm,"checker.messages.invalidLanguage","message","openticket:invalid-language") // This is an invalid language! tm.quickTranslate(lm,"checker.messages.invalidButton","message","openticket:invalid-button") // This button needs to have at least an {0} or {1}! diff --git a/src/data/framework/eventLoader.ts b/src/data/framework/eventLoader.ts index 0aa865b..0371e4a 100644 --- a/src/data/framework/eventLoader.ts +++ b/src/data/framework/eventLoader.ts @@ -10,8 +10,6 @@ export const loadAllEvents = () => { "afterPluginsLoaded", "onPluginClassLoad", "afterPluginClassesLoaded", - "onPluginEventLoad", - "afterPluginEventsLoaded", //flags "onFlagLoad", @@ -230,7 +228,10 @@ export const loadAllEvents = () => { "onStartScreenLoad", "afterStartScreensLoaded", "onStartScreenRender", - "afterStartScreensRendered" + "afterStartScreensRendered", + + //ready + "onReadyForUsage" ] eventList.forEach((event) => openticket.events.add(new api.ODEvent(event))) } \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 268447f..3226910 100644 --- a/src/index.ts +++ b/src/index.ts @@ -92,14 +92,6 @@ const main = async () => { await openticket.events.get("onPluginClassLoad").emit([openticket.plugins.classes,openticket.plugins]) await openticket.events.get("afterPluginClassesLoaded").emit([openticket.plugins.classes,openticket.plugins]) - //load plugin events - openticket.log("Loading plugin events...","system") - if (openticket.defaults.getDefault("pluginEventLoading")){ - - } - await openticket.events.get("onPluginEventLoad").emit([openticket.plugins.events,openticket.plugins]) - await openticket.events.get("afterPluginEventsLoaded").emit([openticket.plugins.events,openticket.plugins]) - //load flags openticket.log("Loading flags...","system") if (openticket.defaults.getDefault("flagLoading")){ @@ -743,5 +735,6 @@ const main = async () => { //YIPPPIE!! //The startup of Open Ticket is completed :) + await openticket.events.get("onReadyForUsage").emit([]) } main() \ No newline at end of file