diff --git a/.gitignore b/.gitignore index f210749..b9a2291 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ TEMP/ .vscode/ plugins/* !plugins/example-plugin/ -dist/ \ No newline at end of file +dist/ +database/openticket.sqlite \ No newline at end of file diff --git a/README.md b/README.md index f239086..defb6fd 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ You're also able to customise every little aspect of the bot! From embeds to tra > The translation count may not be accurate! ### 📌 Features +- **💩 no bloat/credits** - Your Open Ticket bot doesn't contain any form of bloat or credits! +- **📈 scalable** - Open Ticket is made to handle huge servers! Even if your server contains more than 100k members! - **📄 html transcripts** - Make use of the most customisable, beautiful and easy-to-use HTML Transcripts! - **✅ ticket actions** - Close, Reopen, Delete, Rename & Move all your tickets! - **🇬🇧 translation** - Open Ticket has been translated in more than **32 languages** by our community! @@ -40,6 +42,7 @@ You're also able to customise every little aspect of the bot! From embeds to tra - **📦 commands** - Open Ticket supports both slash & text commands! - **📥 extra types** - The bot also supports Reaction Roles & Url Buttons, because why not ¯\\_(ツ)_/¯ - **🎛️ dependencies** - We try to use as little external dependencies as needed! +- **📢 commands** - The bot contains more than 25 commands! And it's expandable with plugins! > ### 📦 Resources > Resources might not be accurate yet! *(because v4 is still in beta)*
diff --git a/plugins/example-plugin/README.md b/plugins/example-plugin/README.md new file mode 100644 index 0000000..0f11476 --- /dev/null +++ b/plugins/example-plugin/README.md @@ -0,0 +1,4 @@ +# Example Plugin +A simple example of an Open Ticket v4 plugin! + +> Use this plugin as a starter template for all your custom plugins! \ No newline at end of file diff --git a/plugins/example-plugin/plugin.json b/plugins/example-plugin/plugin.json index 48549f7..76fd490 100644 --- a/plugins/example-plugin/plugin.json +++ b/plugins/example-plugin/plugin.json @@ -1,5 +1,5 @@ { - "name":"OT Example Plugin", + "name":"Example Plugin", "id":"example-plugin", "version":"1.0.0", "startFile":"index.ts", diff --git a/src/commands/ticket.ts b/src/commands/ticket.ts index ffa00ea..5743e74 100644 --- a/src/commands/ticket.ts +++ b/src/commands/ticket.ts @@ -215,7 +215,7 @@ export const registerModalResponders = async () => { openticket.responders.modals.get("openticket:ticket-questions").workers.add([ new api.ODWorker("openticket:ticket-questions",0,async (instance,params,source,cancel) => { const {guild,channel,user} = instance - if (!channel) throw new api.ODSystemError("The 'Ticket Questions' modal Requires a channel for responding!") + if (!channel) throw new api.ODSystemError("The 'Ticket Questions' modal requires a channel for responding!") if (!guild){ //error instance.reply(await openticket.builders.messages.getSafe("openticket:error-not-in-guild").build(source,{channel,user:instance.user})) diff --git a/src/core/api/defaults/database.ts b/src/core/api/defaults/database.ts index 1805d90..a9d2d26 100644 --- a/src/core/api/defaults/database.ts +++ b/src/core/api/defaults/database.ts @@ -1,7 +1,7 @@ /////////////////////////////////////// //DEFAULT DATABASE MODULE /////////////////////////////////////// -import { ODValidId, ODValidJsonType } from "../modules/base" +import { ODOptionalPromise, ODValidId, ODValidJsonType } from "../modules/base" import { ODDatabaseManager, ODDatabase, ODFormattedJsonDatabase } from "../modules/database" import { ODTicketJson } from "../openticket/ticket" import { ODOptionJson } from "../openticket/option" @@ -65,38 +65,38 @@ export interface ODFormattedJsonDatabaseIds_DefaultGlobal { * This default class is made for the `global.json` database! */ export class ODFormattedJsonDatabase_DefaultGlobal extends ODFormattedJsonDatabase { - set(category:CategoryId, key:string, value:ODFormattedJsonDatabaseIds_DefaultGlobal[CategoryId]): boolean - set(category:string, key:string, value:ODValidJsonType): boolean + set(category:CategoryId, key:string, value:ODFormattedJsonDatabaseIds_DefaultGlobal[CategoryId]): ODOptionalPromise + set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise - set(category:string, key:string, value:ODValidJsonType): boolean { + set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise { return super.set(category,key,value) } - get(category:CategoryId, key:string): ODFormattedJsonDatabaseIds_DefaultGlobal[CategoryId]|undefined - get(category:string, key:string): ODValidJsonType|undefined + get(category:CategoryId, key:string): ODOptionalPromise + get(category:string, key:string): ODOptionalPromise - get(category:string, key:string): ODValidJsonType|undefined { + get(category:string, key:string): ODOptionalPromise { return super.get(category,key) } - delete(category:CategoryId, key:string): boolean - delete(category:string, key:string): boolean + delete(category:CategoryId, key:string): ODOptionalPromise + delete(category:string, key:string): ODOptionalPromise - delete(category:string, key:string): boolean { + delete(category:string, key:string): ODOptionalPromise { return super.delete(category,key) } - exists(category:keyof ODFormattedJsonDatabaseIds_DefaultGlobal, key:string): boolean - exists(category:string, key:string): boolean + exists(category:keyof ODFormattedJsonDatabaseIds_DefaultGlobal, key:string): ODOptionalPromise + exists(category:string, key:string): ODOptionalPromise - exists(category:string, key:string): boolean { + exists(category:string, key:string): ODOptionalPromise { return super.exists(category,key) } - getCategory(category:CategoryId): {key:string, value:ODFormattedJsonDatabaseIds_DefaultGlobal[CategoryId]}[]|undefined - getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined + getCategory(category:CategoryId): ODOptionalPromise<{key:string, value:ODFormattedJsonDatabaseIds_DefaultGlobal[CategoryId]}[]|undefined> + getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> - getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined { + getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> { return super.getCategory(category) } } @@ -116,38 +116,38 @@ export interface ODFormattedJsonDatabaseIds_DefaultTickets { * This default class is made for the `tickets.json` database! */ export class ODFormattedJsonDatabase_DefaultTickets extends ODFormattedJsonDatabase { - set(category:CategoryId, key:string, value:ODFormattedJsonDatabaseIds_DefaultTickets[CategoryId]): boolean - set(category:string, key:string, value:ODValidJsonType): boolean + set(category:CategoryId, key:string, value:ODFormattedJsonDatabaseIds_DefaultTickets[CategoryId]): ODOptionalPromise + set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise - set(category:string, key:string, value:ODValidJsonType): boolean { + set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise { return super.set(category,key,value) } - get(category:CategoryId, key:string): ODFormattedJsonDatabaseIds_DefaultTickets[CategoryId]|undefined - get(category:string, key:string): ODValidJsonType|undefined + get(category:CategoryId, key:string): ODOptionalPromise + get(category:string, key:string): ODOptionalPromise - get(category:string, key:string): ODValidJsonType|undefined { + get(category:string, key:string): ODOptionalPromise { return super.get(category,key) } - delete(category:CategoryId, key:string): boolean - delete(category:string, key:string): boolean + delete(category:CategoryId, key:string): ODOptionalPromise + delete(category:string, key:string): ODOptionalPromise - delete(category:string, key:string): boolean { + delete(category:string, key:string): ODOptionalPromise { return super.delete(category,key) } - exists(category:keyof ODFormattedJsonDatabaseIds_DefaultTickets, key:string): boolean - exists(category:string, key:string): boolean + exists(category:keyof ODFormattedJsonDatabaseIds_DefaultTickets, key:string): ODOptionalPromise + exists(category:string, key:string): ODOptionalPromise - exists(category:string, key:string): boolean { + exists(category:string, key:string): ODOptionalPromise { return super.exists(category,key) } - getCategory(category:CategoryId): {key:string, value:ODFormattedJsonDatabaseIds_DefaultTickets[CategoryId]}[]|undefined - getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined + getCategory(category:CategoryId): ODOptionalPromise<{key:string, value:ODFormattedJsonDatabaseIds_DefaultTickets[CategoryId]}[]|undefined> + getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> - getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined { + getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> { return super.getCategory(category) } } @@ -167,38 +167,38 @@ export interface ODFormattedJsonDatabaseIds_DefaultUsers { * This default class is made for the `users.json` database! */ export class ODFormattedJsonDatabase_DefaultUsers extends ODFormattedJsonDatabase { - set(category:CategoryId, key:string, value:ODFormattedJsonDatabaseIds_DefaultUsers[CategoryId]): boolean - set(category:string, key:string, value:ODValidJsonType): boolean + set(category:CategoryId, key:string, value:ODFormattedJsonDatabaseIds_DefaultUsers[CategoryId]): ODOptionalPromise + set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise - set(category:string, key:string, value:ODValidJsonType): boolean { + set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise { return super.set(category,key,value) } - get(category:CategoryId, key:string): ODFormattedJsonDatabaseIds_DefaultUsers[CategoryId]|undefined - get(category:string, key:string): ODValidJsonType|undefined + get(category:CategoryId, key:string): ODOptionalPromise + get(category:string, key:string): ODOptionalPromise - get(category:string, key:string): ODValidJsonType|undefined { + get(category:string, key:string): ODOptionalPromise { return super.get(category,key) } - delete(category:CategoryId, key:string): boolean - delete(category:string, key:string): boolean + delete(category:CategoryId, key:string): ODOptionalPromise + delete(category:string, key:string): ODOptionalPromise - delete(category:string, key:string): boolean { + delete(category:string, key:string): ODOptionalPromise { return super.delete(category,key) } - exists(category:keyof ODFormattedJsonDatabaseIds_DefaultUsers, key:string): boolean - exists(category:string, key:string): boolean + exists(category:keyof ODFormattedJsonDatabaseIds_DefaultUsers, key:string): ODOptionalPromise + exists(category:string, key:string): ODOptionalPromise - exists(category:string, key:string): boolean { + exists(category:string, key:string): ODOptionalPromise { return super.exists(category,key) } - getCategory(category:CategoryId): {key:string, value:ODFormattedJsonDatabaseIds_DefaultUsers[CategoryId]}[]|undefined - getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined + getCategory(category:CategoryId): ODOptionalPromise<{key:string, value:ODFormattedJsonDatabaseIds_DefaultUsers[CategoryId]}[]|undefined> + getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> - getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined { + getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> { return super.getCategory(category) } } @@ -219,38 +219,38 @@ export interface ODFormattedJsonDatabaseIds_DefaultOptions { * This default class is made for the `options.json` database! */ export class ODFormattedJsonDatabase_DefaultOptions extends ODFormattedJsonDatabase { - set(category:CategoryId, key:string, value:ODFormattedJsonDatabaseIds_DefaultOptions[CategoryId]): boolean - set(category:string, key:string, value:ODValidJsonType): boolean + set(category:CategoryId, key:string, value:ODFormattedJsonDatabaseIds_DefaultOptions[CategoryId]): ODOptionalPromise + set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise - set(category:string, key:string, value:ODValidJsonType): boolean { + set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise { return super.set(category,key,value) } - get(category:CategoryId, key:string): ODFormattedJsonDatabaseIds_DefaultOptions[CategoryId]|undefined - get(category:string, key:string): ODValidJsonType|undefined + get(category:CategoryId, key:string): ODOptionalPromise + get(category:string, key:string): ODOptionalPromise - get(category:string, key:string): ODValidJsonType|undefined { + get(category:string, key:string): ODOptionalPromise { return super.get(category,key) } - delete(category:CategoryId, key:string): boolean - delete(category:string, key:string): boolean + delete(category:CategoryId, key:string): ODOptionalPromise + delete(category:string, key:string): ODOptionalPromise - delete(category:string, key:string): boolean { + delete(category:string, key:string): ODOptionalPromise { return super.delete(category,key) } - exists(category:keyof ODFormattedJsonDatabaseIds_DefaultOptions, key:string): boolean - exists(category:string, key:string): boolean + exists(category:keyof ODFormattedJsonDatabaseIds_DefaultOptions, key:string): ODOptionalPromise + exists(category:string, key:string): ODOptionalPromise - exists(category:string, key:string): boolean { + exists(category:string, key:string): ODOptionalPromise { return super.exists(category,key) } - getCategory(category:CategoryId): {key:string, value:ODFormattedJsonDatabaseIds_DefaultOptions[CategoryId]}[]|undefined - getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined + getCategory(category:CategoryId): ODOptionalPromise<{key:string, value:ODFormattedJsonDatabaseIds_DefaultOptions[CategoryId]}[]|undefined> + getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> - getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined { + getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> { return super.getCategory(category) } } \ No newline at end of file diff --git a/src/core/api/modules/base.ts b/src/core/api/modules/base.ts index ed76818..b422fce 100644 --- a/src/core/api/modules/base.ts +++ b/src/core/api/modules/base.ts @@ -9,6 +9,12 @@ import { ODConsoleWarningMessage, ODDebugger } from "./console" */ export type ODPromiseVoid = void|Promise +/**## ODOptionalPromise `type` + * This is a simple type to represent a type as normal value or a promise value. + */ +export type ODOptionalPromise = T|Promise + + /**## ODValidButtonColor `type` * This is a collection of all the possible button colors. */ diff --git a/src/core/api/modules/console.ts b/src/core/api/modules/console.ts index 6c1afc3..b6e0943 100644 --- a/src/core/api/modules/console.ts +++ b/src/core/api/modules/console.ts @@ -391,9 +391,9 @@ export class ODDebugFileManager { writeText(text:string){ this.#writeDebugFile(text) } - /**Write a custom note to the debug file (starting with `[NODE]:`) */ + /**Write a custom note to the debug file (starting with `[NOTE]:`) */ writeNote(text:string){ - this.#writeDebugFile("[NODE]: "+text) + this.#writeDebugFile("[NOTE]: "+text) } } diff --git a/src/core/api/modules/database.ts b/src/core/api/modules/database.ts index e25eb2d..9bb9966 100644 --- a/src/core/api/modules/database.ts +++ b/src/core/api/modules/database.ts @@ -1,7 +1,7 @@ /////////////////////////////////////// //DATABASE MODULE /////////////////////////////////////// -import { ODId, ODManager, ODManagerData, ODSystemError, ODValidId, ODValidJsonType } from "./base" +import { ODId, ODManager, ODManagerData, ODOptionalPromise, ODSystemError, ODValidId, ODValidJsonType } from "./base" import fs from "fs" import nodepath from "path" import { ODDebugger } from "./console" @@ -87,27 +87,27 @@ export class ODDatabase extends ODManagerData { file: string = "" /**Add/Overwrite a specific category & key in the database. Returns `true` when overwritten. */ - set(category:string, key:string, value:ODValidJsonType): boolean { + set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise { return false } /**Get a specific category & key in the database */ - get(category:string, key:string): ODValidJsonType|undefined { + get(category:string, key:string): ODOptionalPromise { return undefined } /**Delete a specific category & key in the database */ - delete(category:string, key:string): boolean { + delete(category:string, key:string): ODOptionalPromise { return false } /**Check if a specific category & key exists in the database */ - exists(category:string, key:string): boolean { + exists(category:string, key:string): ODOptionalPromise { return false } /**Get a specific category in the database */ - getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined { + getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> { return undefined } /**Get all values in the database */ - getAll(): ODJsonDatabaseStructure { + getAll(): ODOptionalPromise { return [] } } @@ -145,7 +145,7 @@ export class ODJsonDatabase extends ODDatabase { * const didOverwrite = database.setData("category","key","value") //value can be any of the valid types * //You need an ODJsonDatabase class named "database" for this example to work! */ - set(category:string, key:string, value:ODValidJsonType): boolean { + set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise { const currentList = this.#system.getData() const currentData = currentList.find((d) => (d.category === category) && (d.key === key)) @@ -164,7 +164,7 @@ export class ODJsonDatabase extends ODDatabase { * const data = database.getData("category","key") //data will be the value * //You need an ODJsonDatabase class named "database" for this example to work! */ - get(category:string, key:string): ODValidJsonType|undefined { + get(category:string, key:string): ODOptionalPromise { const currentList = this.#system.getData() const tempresult = currentList.find((d) => (d.category === category) && (d.key === key)) return tempresult ? tempresult.value : undefined @@ -174,7 +174,7 @@ export class ODJsonDatabase extends ODDatabase { * const didExist = database.deleteData("category","key") //delete this value * //You need an ODJsonDatabase class named "database" for this example to work! */ - delete(category:string, key:string): boolean { + delete(category:string, key:string): ODOptionalPromise { const currentList = this.#system.getData() const currentData = currentList.find((d) => (d.category === category) && (d.key === key)) if (currentData) currentList.splice(currentList.indexOf(currentData),1) @@ -183,19 +183,19 @@ export class ODJsonDatabase extends ODDatabase { return currentData ? true : false } /**Check if a value of `category` & `key` exists. Returns `false` when non-existent! */ - exists(category:string, key:string): boolean { + exists(category:string, key:string): ODOptionalPromise { const currentList = this.#system.getData() const tempresult = currentList.find((d) => (d.category === category) && (d.key === key)) return tempresult ? true : false } /**Get all values in `category`. Returns `undefined` when non-existent! */ - getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined { + getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> { const currentList = this.#system.getData() const tempresult = currentList.filter((d) => (d.category === category)) return tempresult ? tempresult.map((data) => {return {key:data.key,value:data.value}}) : undefined } /**Get all values in `category`. */ - getAll(): ODJsonDatabaseStructure { + getAll(): ODOptionalPromise { return this.#system.getData() } @@ -249,7 +249,7 @@ export class ODFormattedJsonDatabase extends ODDatabase { * const didOverwrite = database.setData("category","key","value") //value can be any of the valid types * //You need an ODFormattedJsonDatabase class named "database" for this example to work! */ - set(category:string, key:string, value:ODValidJsonType): boolean { + set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise { const currentList = this.#system.getData() const currentData = currentList.find((d) => (d.category === category) && (d.key === key)) @@ -268,7 +268,7 @@ export class ODFormattedJsonDatabase extends ODDatabase { * const data = database.getData("category","key") //data will be the value * //You need an ODFormattedJsonDatabase class named "database" for this example to work! */ - get(category:string, key:string): ODValidJsonType|undefined { + get(category:string, key:string): ODOptionalPromise { const currentList = this.#system.getData() const tempresult = currentList.find((d) => (d.category === category) && (d.key === key)) return tempresult ? tempresult.value : undefined @@ -278,7 +278,7 @@ export class ODFormattedJsonDatabase extends ODDatabase { * const didExist = database.deleteData("category","key") //delete this value * //You need an ODFormattedJsonDatabase class named "database" for this example to work! */ - delete(category:string, key:string): boolean { + delete(category:string, key:string): ODOptionalPromise { const currentList = this.#system.getData() const currentData = currentList.find((d) => (d.category === category) && (d.key === key)) if (currentData) currentList.splice(currentList.indexOf(currentData),1) @@ -287,19 +287,19 @@ export class ODFormattedJsonDatabase extends ODDatabase { return currentData ? true : false } /**Check if a value of `category` & `key` exists. Returns `false` when non-existent! */ - exists(category:string, key:string): boolean { + exists(category:string, key:string): ODOptionalPromise { const currentList = this.#system.getData() const tempresult = currentList.find((d) => (d.category === category) && (d.key === key)) return tempresult ? true : false } /**Get all values in `category`. Returns `undefined` when non-existent! */ - getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined { + getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> { const currentList = this.#system.getData() const tempresult = currentList.filter((d) => (d.category === category)) return tempresult ? tempresult.map((data) => {return {key:data.key,value:data.value}}) : undefined } /**Get all values in `category`. */ - getAll(): ODJsonDatabaseStructure { + getAll(): ODOptionalPromise { return this.#system.getData() } diff --git a/src/core/api/modules/language.ts b/src/core/api/modules/language.ts index 2e329f9..6a18c61 100644 --- a/src/core/api/modules/language.ts +++ b/src/core/api/modules/language.ts @@ -19,7 +19,9 @@ export class ODLanguage extends ODManagerData { file: string /**The path to the file relative to the main directory. */ path: string + /**The raw object data of the translation. */ data: any + /**The metadata of the language if available. */ metadata: ODLanguageMetadata|null = null constructor(id:ODValidId, file:string, customPath?:string){ diff --git a/src/core/api/modules/stat.ts b/src/core/api/modules/stat.ts index 3ca36e0..baff800 100644 --- a/src/core/api/modules/stat.ts +++ b/src/core/api/modules/stat.ts @@ -42,13 +42,14 @@ export class ODStatsManager extends ODManager { //filter out the deletable stats const deletableStats: ODJsonDatabaseStructure = [] - this.database.getAll().forEach((data) => { + const data = await this.database.getAll() + data.forEach((data) => { if (!validCategories.includes(data.category)) deletableStats.push(data) }) //do additional deletion for (const cb of this.#initListeners){ - await cb(this.database.getAll(),deletableStats) + await cb(data,deletableStats) } //delete all deletable stats @@ -57,9 +58,10 @@ export class ODStatsManager extends ODManager { this.database.delete(data.category,data.key) }) } - reset(){ + async reset(){ if (!this.database) return - this.database.getAll().forEach((data) => { + const data = await this.database.getAll() + data.forEach((data) => { if (!this.database) return this.database.delete(data.category,data.key) }) diff --git a/src/core/startup/init.ts b/src/core/startup/init.ts index 2a7867d..fb089dd 100644 --- a/src/core/startup/init.ts +++ b/src/core/startup/init.ts @@ -87,7 +87,7 @@ interface ODUtilities { */ emojiTitle(emoji:string, text:string): string /**## runAsync `utility function` - * Use this function to run a piece of code asyncronous without creating a separate function for it! + * Use this function to run a snippet of code asyncronous without creating a separate function for it! */ runAsync(func:() => Promise): void /**## timedAwait `utility function` diff --git a/src/core/startup/manageMigration.ts b/src/core/startup/manageMigration.ts index 32194e3..1b5bc7a 100644 --- a/src/core/startup/manageMigration.ts +++ b/src/core/startup/manageMigration.ts @@ -4,7 +4,7 @@ export const loadVersionMigrationSystem = async () => { //ENTER MIGRATION CONTEXT await preloadMigrationContext() - const lastVersion = isMigrationRequired() + const lastVersion = await isMigrationRequired() openticket.versions.add(lastVersion ? lastVersion : api.ODVersion.fromString("openticket:last-version",openticket.versions.get("openticket:version").toString())) if (lastVersion && !openticket.flags.get("openticket:no-migration").value){ //MIGRATION IS REQUIRED @@ -48,8 +48,8 @@ const unloadMigrationContext = async () => { openticket.debug.debug("-- MIGRATION CONTEXT END --") } -const isMigrationRequired = (): false|api.ODVersion => { - const rawVersion = openticket.databases.get("openticket:global").get("openticket:last-version","openticket:version") +const isMigrationRequired = async (): Promise => { + const rawVersion = await openticket.databases.get("openticket:global").get("openticket:last-version","openticket:version") if (!rawVersion) return false const version = api.ODVersion.fromString("openticket:last-version",rawVersion) if (openticket.versions.get("openticket:version").compare(version) == "higher"){ diff --git a/src/data/framework/codeLoader.ts b/src/data/framework/codeLoader.ts index 0699c17..ab358b2 100644 --- a/src/data/framework/codeLoader.ts +++ b/src/data/framework/codeLoader.ts @@ -73,7 +73,7 @@ export const loadDatabaseCleanersCode = async () => { const validPanels: string[] = [] //check global database for valid panel embeds - for (const panel of (globalDatabase.getCategory("openticket:panel-update") ?? [])){ + for (const panel of (await globalDatabase.getCategory("openticket:panel-update") ?? [])){ if (!validPanels.includes(panel.key)){ try{ const splittedId = panel.key.split("_") @@ -84,7 +84,7 @@ export const loadDatabaseCleanersCode = async () => { } //remove all unused panels - for (const panel of (globalDatabase.getCategory("openticket:panel-update") ?? [])){ + for (const panel of (await globalDatabase.getCategory("openticket:panel-update") ?? [])){ if (!validPanels.includes(panel.key)){ globalDatabase.delete("openticket:panel-update",panel.key) } @@ -104,28 +104,28 @@ export const loadDatabaseCleanersCode = async () => { const validSuffixHistories: string[] = [] //check global database for valid option suffix counters - for (const counter of (globalDatabase.getCategory("openticket:option-suffix-counter") ?? [])){ + for (const counter of (await globalDatabase.getCategory("openticket:option-suffix-counter") ?? [])){ if (!validSuffixCounters.includes(counter.key)){ if (openticket.options.exists(counter.key)) validSuffixCounters.push(counter.key) } } //check global database for valid option suffix histories - for (const history of (globalDatabase.getCategory("openticket:option-suffix-history") ?? [])){ + for (const history of (await globalDatabase.getCategory("openticket:option-suffix-history") ?? [])){ if (!validSuffixHistories.includes(history.key)){ if (openticket.options.exists(history.key)) validSuffixHistories.push(history.key) } } //remove all unused suffix counters - for (const counter of (globalDatabase.getCategory("openticket:option-suffix-counter") ?? [])){ + for (const counter of (await globalDatabase.getCategory("openticket:option-suffix-counter") ?? [])){ if (!validSuffixCounters.includes(counter.key)){ globalDatabase.delete("openticket:option-suffix-counter",counter.key) } } //remove all unused suffix histories - for (const history of (globalDatabase.getCategory("openticket:option-suffix-history") ?? [])){ + for (const history of (await globalDatabase.getCategory("openticket:option-suffix-history") ?? [])){ if (!validSuffixHistories.includes(history.key)){ globalDatabase.delete("openticket:option-suffix-history",history.key) } @@ -148,7 +148,7 @@ export const loadDatabaseCleanersCode = async () => { const validUsers: string[] = [] //check user database for valid users - for (const user of userDatabase.getAll()){ + for (const user of (await userDatabase.getAll())){ if (!validUsers.includes(user.key)){ try{ const member = await mainServer.members.fetch(user.key) @@ -158,7 +158,7 @@ export const loadDatabaseCleanersCode = async () => { } //check stats database for valid users - for (const stat of statsDatabase.getAll()){ + for (const stat of (await statsDatabase.getAll())){ if (stat.category.startsWith("openticket:user_")){ if (!validUsers.includes(stat.key)){ try{ @@ -170,14 +170,14 @@ export const loadDatabaseCleanersCode = async () => { } //remove all unused users - for (const user of userDatabase.getAll()){ + for (const user of (await userDatabase.getAll())){ if (!validUsers.includes(user.key)){ userDatabase.delete(user.category,user.key) } } //remove all unused stats - for (const stat of statsDatabase.getAll()){ + for (const stat of (await statsDatabase.getAll())){ if (stat.category.startsWith("openticket:user_")){ if (!validUsers.includes(stat.key)){ statsDatabase.delete(stat.category,stat.key) @@ -187,18 +187,18 @@ export const loadDatabaseCleanersCode = async () => { }) //delete user from database on leave - openticket.client.client.on("guildMemberRemove",(member) => { + openticket.client.client.on("guildMemberRemove",async (member) => { if (member.guild.id != mainServer.id) return //remove unused user - for (const user of userDatabase.getAll()){ + for (const user of (await userDatabase.getAll())){ if (user.key == member.id){ userDatabase.delete(user.category,user.key) } } //remove unused stats - for (const stat of statsDatabase.getAll()){ + for (const stat of (await statsDatabase.getAll())){ if (stat.category.startsWith("openticket:user_")){ if (stat.key == member.id){ statsDatabase.delete(stat.category,stat.key) @@ -213,7 +213,7 @@ export const loadDatabaseCleanersCode = async () => { const validTickets: string[] = [] //check ticket database for valid tickets - for (const ticket of ticketDatabase.getAll()){ + for (const ticket of (await ticketDatabase.getAll())){ if (!validTickets.includes(ticket.key)){ try{ const channel = await openticket.client.fetchGuildTextChannel(mainServer,ticket.key) @@ -223,7 +223,7 @@ export const loadDatabaseCleanersCode = async () => { } //check stats database for valid tickets - for (const stat of statsDatabase.getAll()){ + for (const stat of (await statsDatabase.getAll())){ if (stat.category.startsWith("openticket:ticket_")){ if (!validTickets.includes(stat.key)){ try{ @@ -235,7 +235,7 @@ export const loadDatabaseCleanersCode = async () => { } //remove all unused tickets - for (const ticket of ticketDatabase.getAll()){ + for (const ticket of (await ticketDatabase.getAll())){ if (!validTickets.includes(ticket.key)){ ticketDatabase.delete(ticket.category,ticket.key) openticket.tickets.remove(ticket.key) @@ -243,7 +243,7 @@ export const loadDatabaseCleanersCode = async () => { } //remove all unused stats - for (const stat of statsDatabase.getAll()){ + for (const stat of (await statsDatabase.getAll())){ if (stat.category.startsWith("openticket:ticket_")){ if (!validTickets.includes(stat.key)){ statsDatabase.delete(stat.category,stat.key) @@ -252,11 +252,11 @@ export const loadDatabaseCleanersCode = async () => { } //delete ticket from database on delete - openticket.client.client.on("channelDelete",(channel) => { + openticket.client.client.on("channelDelete",async (channel) => { if (channel.isDMBased() || channel.guild.id != mainServer.id) return //remove unused ticket - for (const ticket of ticketDatabase.getAll()){ + for (const ticket of (await ticketDatabase.getAll())){ if (ticket.key == channel.id){ ticketDatabase.delete(ticket.category,ticket.key) openticket.tickets.remove(ticket.key) @@ -264,7 +264,7 @@ export const loadDatabaseCleanersCode = async () => { } //remove unused stats - for (const stat of statsDatabase.getAll()){ + for (const stat of (await statsDatabase.getAll())){ if (stat.category.startsWith("openticket:ticket_")){ if (stat.key == channel.id){ statsDatabase.delete(stat.category,stat.key) @@ -279,7 +279,7 @@ export const loadPanelAutoUpdateCode = async () => { //PANEL AUTO UPDATE openticket.code.add(new api.ODCode("openticket:panel-auto-update",7,async () => { const globalDatabase = openticket.databases.get("openticket:global") - const panelIds = globalDatabase.getCategory("openticket:panel-update") ?? [] + const panelIds = await globalDatabase.getCategory("openticket:panel-update") ?? [] if (!mainServer) return for (const panelId of panelIds){ diff --git a/src/data/framework/permissionLoader.ts b/src/data/framework/permissionLoader.ts index 9966f69..44eb881 100644 --- a/src/data/framework/permissionLoader.ts +++ b/src/data/framework/permissionLoader.ts @@ -38,14 +38,15 @@ export const loadAllPermissions = async () => { const admins = ticket.option.exists("openticket:admins") ? ticket.option.get("openticket:admins").value : [] const readAdmins = ticket.option.exists("openticket:admins-readonly") ? ticket.option.get("openticket:admins-readonly").value : [] - admins.concat(readAdmins).forEach(async (admin) => { + for (const admin of admins.concat(readAdmins)){ + if (openticket.permissions.exists("openticket:ticket-admin_"+ticket.id.value+"_"+admin)) return const role = await mainServer.roles.fetch(admin) if (!role) return openticket.log("Unable to register permission for ticket admin!","error",[ {key:"roleid",value:admin} ]) openticket.permissions.add(new api.ODPermission("openticket:ticket-admin_"+ticket.id.value+"_"+admin,"channel-role","support",role,channel)) - }) + } }catch(err){ process.emit("uncaughtException",err) openticket.log("Ticket Admin Loading Permissions Error (see above)","error") diff --git a/src/data/openticket/blacklistLoader.ts b/src/data/openticket/blacklistLoader.ts index 49c4a68..6676b98 100644 --- a/src/data/openticket/blacklistLoader.ts +++ b/src/data/openticket/blacklistLoader.ts @@ -4,7 +4,7 @@ export const loadAllBlacklistedUsers = async () => { const userDatabase = openticket.databases.get("openticket:users") if (!userDatabase) return - const users = userDatabase.getCategory("openticket:blacklist") ?? [] + const users = await userDatabase.getCategory("openticket:blacklist") ?? [] users.forEach((user) => { if (typeof user.value == "string" || user.value === null) openticket.blacklist.add(new api.ODBlacklist(user.key,user.value)) }) diff --git a/src/data/openticket/ticketLoader.ts b/src/data/openticket/ticketLoader.ts index ea89958..93d7811 100644 --- a/src/data/openticket/ticketLoader.ts +++ b/src/data/openticket/ticketLoader.ts @@ -6,7 +6,7 @@ export const loadAllTickets = async () => { const ticketDatabase = openticket.databases.get("openticket:tickets") if (!ticketDatabase) return - const tickets = ticketDatabase.getCategory("openticket:ticket") + const tickets = await ticketDatabase.getCategory("openticket:ticket") if (!tickets) return tickets.forEach((ticket) => { try { diff --git a/src/data/openticket/transcriptLoader.ts b/src/data/openticket/transcriptLoader.ts index 36c3419..3f46803 100644 --- a/src/data/openticket/transcriptLoader.ts +++ b/src/data/openticket/transcriptLoader.ts @@ -178,12 +178,16 @@ export const loadAllTranscriptCompilers = async () => { const req = new api.ODHTTPGetRequest("https://apis.dj-dj.be/transcripts/status.json",false) const res = await req.run() if (!res || res.status != 200 || !res.body){ + openticket.debugfile.writeNote("HTML Transcripts Error => status: "+res.status+", body:\n"+res.body) + process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts INIT_COMMUNICATON error! (check otdebug.txt for details)")) return {success:false,errorReason:"HTML Transcripts are currently unavailable!",pendingMessage:null} } try{ const data = JSON.parse(res.body) if (!data || data["v2"] != "online") return {success:false,errorReason:"HTML Transcripts are currently unavailable due to maintenance!",pendingMessage:null} }catch{ + openticket.debugfile.writeNote("HTML Transcripts Error => unable to parse status! body:\n"+res.body) + process.emit("uncaughtException",new api.ODSystemError("HTML Transcripts INIT_STATUS_PARSE error! (check otdebug.txt for details)")) return {success:false,errorReason:"HTML Transcripts are currently unavailable due to JSON parse error!",pendingMessage:null} }