Bug fixes for new database system

This commit is contained in:
DJj123dj
2024-11-25 19:24:48 +01:00
parent b22f7b2de7
commit 3e928ed06e
11 changed files with 161 additions and 180 deletions
+1 -1
View File
@@ -67,7 +67,7 @@ export const registerCommandResponders = async () => {
//add panel to database on auto-update //add panel to database on auto-update
if (instance.options.getBoolean("auto-update",false)){ if (instance.options.getBoolean("auto-update",false)){
const globalDatabase = openticket.databases.get("openticket:global") const globalDatabase = openticket.databases.get("openticket:global")
globalDatabase.set("openticket:panel-update",panelMessage.channel.id+"_"+panelMessage.id,panel.id.value) await globalDatabase.set("openticket:panel-update",panelMessage.channel.id+"_"+panelMessage.id,panel.id.value)
} }
}), }),
new api.ODWorker("openticket:logs",-1,(instance,params,source,cancel) => { new api.ODWorker("openticket:logs",-1,(instance,params,source,cancel) => {
+4
View File
@@ -64,10 +64,14 @@ export interface ODEventIds_Default {
//configs //configs
"onConfigLoad": ODEvent_Default<(configs:ODConfigManager_Default) => ODPromiseVoid> "onConfigLoad": ODEvent_Default<(configs:ODConfigManager_Default) => ODPromiseVoid>
"afterConfigsLoaded": ODEvent_Default<(configs:ODConfigManager_Default) => ODPromiseVoid> "afterConfigsLoaded": ODEvent_Default<(configs:ODConfigManager_Default) => ODPromiseVoid>
"onConfigInit": ODEvent_Default<(configs:ODConfigManager_Default) => ODPromiseVoid>
"afterConfigsInitiated": ODEvent_Default<(configs:ODConfigManager_Default) => ODPromiseVoid>
//databases //databases
"onDatabaseLoad": ODEvent_Default<(databases:ODDatabaseManager_Default) => ODPromiseVoid> "onDatabaseLoad": ODEvent_Default<(databases:ODDatabaseManager_Default) => ODPromiseVoid>
"afterDatabasesLoaded": ODEvent_Default<(databases:ODDatabaseManager_Default) => ODPromiseVoid> "afterDatabasesLoaded": ODEvent_Default<(databases:ODDatabaseManager_Default) => ODPromiseVoid>
"onDatabaseInit": ODEvent_Default<(databases:ODDatabaseManager_Default) => ODPromiseVoid>
"afterDatabasesInitiated": ODEvent_Default<(databases:ODDatabaseManager_Default) => ODPromiseVoid>
//languages //languages
"onLanguageLoad": ODEvent_Default<(languages:ODLanguageManager_Default) => ODPromiseVoid> "onLanguageLoad": ODEvent_Default<(languages:ODLanguageManager_Default) => ODPromiseVoid>
+23 -42
View File
@@ -1,7 +1,7 @@
/////////////////////////////////////// ///////////////////////////////////////
//CONFIG MODULE //CONFIG MODULE
/////////////////////////////////////// ///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODSystemError, ODValidId } from "./base" import { ODId, ODManager, ODManagerData, ODPromiseVoid, ODSystemError, ODValidId } from "./base"
import nodepath from "path" import nodepath from "path"
import { ODDebugger } from "./console" import { ODDebugger } from "./console"
import fs from "fs" import fs from "fs"
@@ -12,51 +12,20 @@ import fs from "fs"
* It manages all config files in the bot and allows plugins to access config files from open ticket & other plugins! * It manages all config files in the bot and allows plugins to access config files from open ticket & other plugins!
* *
* You will use this class to get/add a config file (`ODConfig`) in your plugin! * You will use this class to get/add a config file (`ODConfig`) in your plugin!
* @example
* //get ./config/general.json => ODConfig class
* const generalConfig = openticket.configs.get("openticket:general")
*
* //add a new config with id "test" => ./config/test.json
* const testConfig = new api.ODConfig("test","test.json")
* openticket.configs.add(testConfig)
*/ */
export class ODConfigManager extends ODManager<ODConfig> { export class ODConfigManager extends ODManager<ODConfig> {
constructor(debug:ODDebugger){ constructor(debug:ODDebugger){
super(debug,"config") super(debug,"config")
} }
/**Init all config files. */
/**Add data to the manager. The id will be fetched from the data class! You can optionally select to overwrite existing data! async init(){
* @example for (const config of this.getAll()){
* //add a new config with id "test" => ./config/test.json try{
* const testConfig = new api.ODConfig("test","test.json") await config.init()
* openticket.configs.add(testConfig) }catch(err){
*/ process.emit("uncaughtException",new ODSystemError(err))
add(data:ODConfig, overwrite?:boolean): boolean {
return super.add(data,overwrite)
} }
/**Get data that matches the `ODId`. Returns the found data.
* @example
* //get "./config/general.json" (ot-general) => ODConfig class
* const generalConfig = openticket.configs.get("openticket:general")
*/
get(id:ODValidId): ODConfig|null {
return super.get(id)
} }
/**Remove data that matches the `ODId`. Returns the removed data.
* @example
* //remove the "test" config
* openticket.configs.remove("test") //returns null if non-existing
*/
remove(id:ODValidId): ODConfig|null {
return super.remove(id)
}
/**Check if data that matches the `ODId` exists. Returns a boolean.
* @example
* //check if "./config/general.json" (ot-general) exists => boolean
* const exists = openticket.configs.exists("openticket:general")
*/
exists(id:ODValidId): boolean {
return super.exists(id)
} }
} }
@@ -72,7 +41,17 @@ export class ODConfig extends ODManagerData {
/**The path to the file relative to the main directory. */ /**The path to the file relative to the main directory. */
path: string = "" path: string = ""
/**An object/array of the entire config file! Variables inside it can be edited while the bot is running! */ /**An object/array of the entire config file! Variables inside it can be edited while the bot is running! */
data: any = undefined data: any
constructor(id:ODValidId, data:any){
super(id)
this.data = data
}
/**Init the config. */
init(): ODPromiseVoid {
//nothing
}
} }
/**## ODJsonConfig `class` /**## ODJsonConfig `class`
@@ -90,10 +69,13 @@ export class ODJsonConfig extends ODConfig {
#reloadListeners: Function[] = [] #reloadListeners: Function[] = []
constructor(id:ODValidId, file:string, customPath?:string){ constructor(id:ODValidId, file:string, customPath?:string){
super(id) super(id,{})
this.file = (file.endsWith(".json")) ? file : file+".json" this.file = (file.endsWith(".json")) ? file : file+".json"
this.path = customPath ? nodepath.join("./",customPath,this.file) : nodepath.join("./config/",this.file) this.path = customPath ? nodepath.join("./",customPath,this.file) : nodepath.join("./config/",this.file)
}
/**Init the config. */
init(): ODPromiseVoid {
if (!fs.existsSync(this.path)) throw new ODSystemError("Unable to parse config \""+nodepath.join("./",this.path)+"\", the file doesn't exist!") if (!fs.existsSync(this.path)) throw new ODSystemError("Unable to parse config \""+nodepath.join("./",this.path)+"\", the file doesn't exist!")
try{ try{
this.data = JSON.parse(fs.readFileSync(this.path).toString()) this.data = JSON.parse(fs.readFileSync(this.path).toString())
@@ -102,7 +84,6 @@ export class ODJsonConfig extends ODConfig {
throw new ODSystemError("Unable to parse config \""+nodepath.join("./",this.path)+"\"!") throw new ODSystemError("Unable to parse config \""+nodepath.join("./",this.path)+"\"!")
} }
} }
/**Reload the JSON file. Be aware that this doesn't update classes that used individual parts of the config data! */ /**Reload the JSON file. Be aware that this doesn't update classes that used individual parts of the config data! */
reload(){ reload(){
if (!fs.existsSync(this.path)) throw new ODSystemError("Unable to reload config \""+nodepath.join("./",this.path)+"\", the file doesn't exist!") if (!fs.existsSync(this.path)) throw new ODSystemError("Unable to reload config \""+nodepath.join("./",this.path)+"\", the file doesn't exist!")
+37 -80
View File
@@ -1,7 +1,7 @@
/////////////////////////////////////// ///////////////////////////////////////
//DATABASE MODULE //DATABASE MODULE
/////////////////////////////////////// ///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODOptionalPromise, ODSystemError, ODValidId, ODValidJsonType } from "./base" import { ODId, ODManager, ODManagerData, ODOptionalPromise, ODPromiseVoid, ODSystemError, ODValidId, ODValidJsonType } from "./base"
import fs from "fs" import fs from "fs"
import nodepath from "path" import nodepath from "path"
import { ODDebugger } from "./console" import { ODDebugger } from "./console"
@@ -13,51 +13,21 @@ import * as fjs from "formatted-json-stringify"
* It manages all databases in the bot and allows to permanently store data from the bot! * It manages all databases in the bot and allows to permanently store data from the bot!
* *
* You will use this class to get/add a database (`ODDatabase`) in your plugin! * You will use this class to get/add a database (`ODDatabase`) in your plugin!
* @example
* //get ./database/ot-global.json => ODDatabase class
* const globalDB = openticket.databases.get("openticket:global")
*
* //add a new database with id "test" => ./database/idk-test.json
* const testDatabase = new api.ODDatabase("test","idk-test.json")
* openticket.databases.add(testDatabase)
*/ */
export class ODDatabaseManager extends ODManager<ODDatabase> { export class ODDatabaseManager extends ODManager<ODDatabase> {
constructor(debug:ODDebugger){ constructor(debug:ODDebugger){
super(debug,"database") super(debug,"database")
} }
/**Add data to the manager. The id will be fetched from the data class! You can optionally select to overwrite existing data! /**Init all database files. */
* @example async init(){
* //add a new database with id "test" => ./database/idk-test.json for (const database of this.getAll()){
* const testDatabase = new api.ODDatabase("test","idk-test.json") try{
* openticket.databases.add(testDatabase) await database.init()
*/ }catch(err){
add(data:ODDatabase, overwrite?:boolean): boolean { process.emit("uncaughtException",new ODSystemError(err))
return super.add(data,overwrite)
} }
/**Get data that matches the `ODId`. Returns the found data.
* @example
* //get ./database/ot-global.json => ODDatabase class
* const globalDB = openticket.databases.get("openticket:global")
*/
get(id:ODValidId): ODDatabase|null {
return super.get(id)
} }
/**Remove data that matches the `ODId`. Returns the removed data.
* @example
* //remove the "test" database
* openticket.databases.remove("test") //returns null if non-existing
*/
remove(id:ODValidId): ODDatabase|null {
return super.remove(id)
}
/**Check if data that matches the `ODId` exists. Returns a boolean.
* @example
* //check if "./database/idk-test.json" (test) exists => boolean
* const exists = openticket.databases.exists("test")
*/
exists(id:ODValidId): boolean {
return super.exists(id)
} }
} }
@@ -66,26 +36,17 @@ export class ODDatabaseManager extends ODManager<ODDatabase> {
* This class doesn't do anything at all, it just gives a template & basic methods for a database. Use `ODJsonDatabase` instead! * This class doesn't do anything at all, it just gives a template & basic methods for a database. Use `ODJsonDatabase` instead!
* *
* You will only use this class if you want to create your own database implementation (e.g. `mongodb`, `mysql`,...)! * You will only use this class if you want to create your own database implementation (e.g. `mongodb`, `mysql`,...)!
* @example
* class SomeDatabase extends ODDatabase {
* //override this method
* setData(category:string, key:string, value:ODValidJsonType): boolean {
* return false
* }
* //override this method
* getData(category:string, key:string): ODValidJsonType|undefined {
* return undefined
* }
* //override this method
* deleteData(category:string, key:string): boolean {
* return false
* }
* }
*/ */
export class ODDatabase extends ODManagerData { export class ODDatabase extends ODManagerData {
/**The full path to this database with extension */ /**The name of the file with extension. */
file: string = "" file: string = ""
/**The path to the file relative to the main directory. */
path: string = ""
/**Init the database. */
init(): ODPromiseVoid {
//nothing
}
/**Add/Overwrite a specific category & key in the database. Returns `true` when overwritten. */ /**Add/Overwrite a specific category & key in the database. Returns `true` when overwritten. */
set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean> { set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean> {
return false return false
@@ -122,24 +83,19 @@ export type ODJsonDatabaseStructure = {category:string, key:string, value:ODVali
* It stores data in a `json` file as a large `Array` using the `category`, `key`, `value` strategy. * It stores data in a `json` file as a large `Array` using the `category`, `key`, `value` strategy.
* You can store the following types: `string`, `number`, `boolean`, `array`, `object` & `null`! * You can store the following types: `string`, `number`, `boolean`, `array`, `object` & `null`!
* *
* You will only use this class if you want to create your own database or use an existing one! * You will use this class if you want to create your own database or use an existing one!
* @example
* //get,set & delete data
* const data = database.getData("category","key") //data will be the value
* const didOverwrite = database.setData("category","key","value") //value can be any of the valid types
* const didExist = database.deleteData("category","key") //delete this value
* //You need an ODJsonDatabase class named "database" for this example to work!
*/ */
export class ODJsonDatabase extends ODDatabase { export class ODJsonDatabase extends ODDatabase {
constructor(id:ODValidId, file:string, customPath?:string){ constructor(id:ODValidId, file:string, customPath?:string){
super(id) super(id)
const filename = (file.endsWith(".json")) ? file : file+".json" this.file = (file.endsWith(".json")) ? file : file+".json"
this.file = customPath ? nodepath.join("./",customPath,filename) : nodepath.join("./database/",filename) this.path = customPath ? nodepath.join("./",customPath,this.file) : nodepath.join("./database/",this.file)
//init file if it doesn't exist yet
this.#system.getData()
} }
/**Init the database. */
init(): ODPromiseVoid {
this.#system.getData()
}
/**Set/overwrite the value of `category` & `key`. Returns `true` when overwritten! /**Set/overwrite the value of `category` & `key`. Returns `true` when overwritten!
* @example * @example
* const didOverwrite = database.setData("category","key","value") //value can be any of the valid types * const didOverwrite = database.setData("category","key","value") //value can be any of the valid types
@@ -202,21 +158,21 @@ export class ODJsonDatabase extends ODDatabase {
#system = { #system = {
/**Read parsed data from the json file */ /**Read parsed data from the json file */
getData: (): ODJsonDatabaseStructure => { getData: (): ODJsonDatabaseStructure => {
if (fs.existsSync(this.file)){ if (fs.existsSync(this.path)){
try{ try{
return JSON.parse(fs.readFileSync(this.file).toString()) return JSON.parse(fs.readFileSync(this.path).toString())
}catch(err){ }catch(err){
process.emit("uncaughtException",err) process.emit("uncaughtException",err)
throw new ODSystemError("Unable to read database "+this.file+"! getData() read error. (see error above)") throw new ODSystemError("Unable to read database "+this.path+"! getData() read error. (see error above)")
} }
}else{ }else{
fs.writeFileSync(this.file,"[]") fs.writeFileSync(this.path,"[]")
return [] return []
} }
}, },
/**Write parsed data to the json file */ /**Write parsed data to the json file */
setData: (data:ODJsonDatabaseStructure) => { setData: (data:ODJsonDatabaseStructure) => {
fs.writeFileSync(this.file,JSON.stringify(data,null,"\t")) fs.writeFileSync(this.path,JSON.stringify(data,null,"\t"))
} }
} }
} }
@@ -236,14 +192,15 @@ export class ODFormattedJsonDatabase extends ODDatabase {
constructor(id:ODValidId, file:string, formatter:fjs.ArrayFormatter, customPath?:string){ constructor(id:ODValidId, file:string, formatter:fjs.ArrayFormatter, customPath?:string){
super(id) super(id)
const filename = (file.endsWith(".json")) ? file : file+".json" this.file = (file.endsWith(".json")) ? file : file+".json"
this.file = customPath ? nodepath.join("./",customPath,filename) : nodepath.join("./database/",filename) this.path = customPath ? nodepath.join("./",customPath,this.file) : nodepath.join("./database/",this.file)
this.formatter = formatter this.formatter = formatter
//init file if it doesn't exist yet
this.#system.getData()
} }
/**Init the database. */
init(): ODPromiseVoid {
this.#system.getData()
}
/**Set/overwrite the value of `category` & `key`. Returns `true` when overwritten! /**Set/overwrite the value of `category` & `key`. Returns `true` when overwritten!
* @example * @example
* const didOverwrite = database.setData("category","key","value") //value can be any of the valid types * const didOverwrite = database.setData("category","key","value") //value can be any of the valid types
@@ -306,16 +263,16 @@ export class ODFormattedJsonDatabase extends ODDatabase {
#system = { #system = {
/**Read parsed data from the json file */ /**Read parsed data from the json file */
getData: (): ODJsonDatabaseStructure => { getData: (): ODJsonDatabaseStructure => {
if (fs.existsSync(this.file)){ if (fs.existsSync(this.path)){
return JSON.parse(fs.readFileSync(this.file).toString()) return JSON.parse(fs.readFileSync(this.path).toString())
}else{ }else{
fs.writeFileSync(this.file,"[]") fs.writeFileSync(this.path,"[]")
return [] return []
} }
}, },
/**Write parsed data to the json file */ /**Write parsed data to the json file */
setData: (data:ODJsonDatabaseStructure) => { setData: (data:ODJsonDatabaseStructure) => {
fs.writeFileSync(this.file,this.formatter.stringify(data)) fs.writeFileSync(this.path,this.formatter.stringify(data))
} }
} }
} }
+6
View File
@@ -29,8 +29,12 @@ export interface ODDefaults {
flagInitiating:boolean, flagInitiating:boolean,
/**Load the default open ticket configs. */ /**Load the default open ticket configs. */
configLoading:boolean, configLoading:boolean,
/**Enable the default initializer for open ticket config. */
configInitiating:boolean,
/**Load the default open ticket databases. */ /**Load the default open ticket databases. */
databaseLoading:boolean, databaseLoading:boolean,
/**Enable the default initializer for open ticket database. */
databaseInitiating:boolean,
/**Load the default open ticket sessions. */ /**Load the default open ticket sessions. */
sessionLoading:boolean, sessionLoading:boolean,
@@ -230,7 +234,9 @@ export class ODDefaultsManager {
flagLoading:true, flagLoading:true,
flagInitiating:true, flagInitiating:true,
configLoading:true, configLoading:true,
configInitiating:true,
databaseLoading:true, databaseLoading:true,
databaseInitiating:true,
sessionLoading:true, sessionLoading:true,
languageLoading:true, languageLoading:true,
+17 -4
View File
@@ -328,9 +328,12 @@ export class ODOptionCounterDynamicSuffix extends ODOptionSuffix {
constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){ constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){
super(id,option) super(id,option)
this.database = database this.database = database
if (!this.database.exists("openticket:option-suffix-counter",option.id.value)) this.database.set("openticket:option-suffix-counter",this.option.id.value,0) this.#init()
} }
async #init(){
if (!await this.database.exists("openticket:option-suffix-counter",this.option.id.value)) await this.database.set("openticket:option-suffix-counter",this.option.id.value,0)
}
getSuffix(user:discord.User): string { getSuffix(user:discord.User): string {
const rawCurrentValue = this.database.get("openticket:option-suffix-counter",this.option.id.value) const rawCurrentValue = this.database.get("openticket:option-suffix-counter",this.option.id.value)
const currentValue = (typeof rawCurrentValue != "number") ? 0 : rawCurrentValue const currentValue = (typeof rawCurrentValue != "number") ? 0 : rawCurrentValue
@@ -347,9 +350,12 @@ export class ODOptionCounterFixedSuffix extends ODOptionSuffix {
constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){ constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){
super(id,option) super(id,option)
this.database = database this.database = database
if (!this.database.exists("openticket:option-suffix-counter",option.id.value)) this.database.set("openticket:option-suffix-counter",this.option.id.value,0) this.#init()
} }
async #init(){
if (!await this.database.exists("openticket:option-suffix-counter",this.option.id.value)) await this.database.set("openticket:option-suffix-counter",this.option.id.value,0)
}
getSuffix(user:discord.User): string { getSuffix(user:discord.User): string {
const rawCurrentValue = this.database.get("openticket:option-suffix-counter",this.option.id.value) const rawCurrentValue = this.database.get("openticket:option-suffix-counter",this.option.id.value)
const currentValue = (typeof rawCurrentValue != "number") ? 0 : rawCurrentValue const currentValue = (typeof rawCurrentValue != "number") ? 0 : rawCurrentValue
@@ -370,9 +376,12 @@ export class ODOptionRandomNumberSuffix extends ODOptionSuffix {
constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){ constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){
super(id,option) super(id,option)
this.database = database this.database = database
if (!this.database.exists("openticket:option-suffix-history",option.id.value)) this.database.set("openticket:option-suffix-history",this.option.id.value,[]) this.#init()
} }
async #init(){
if (!await this.database.exists("openticket:option-suffix-history",this.option.id.value)) await this.database.set("openticket:option-suffix-history",this.option.id.value,[])
}
#generateUniqueValue(history:string[]): string { #generateUniqueValue(history:string[]): string {
const rawNumber = Math.round(Math.random()*1000).toString() const rawNumber = Math.round(Math.random()*1000).toString()
let number = rawNumber let number = rawNumber
@@ -401,9 +410,13 @@ export class ODOptionRandomHexSuffix extends ODOptionSuffix {
constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){ constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){
super(id,option) super(id,option)
this.database = database this.database = database
if (!this.database.exists("openticket:option-suffix-history",option.id.value)) this.database.set("openticket:option-suffix-history",this.option.id.value,[]) this.#init()
} }
async #init(){
if (!await this.database.exists("openticket:option-suffix-history",this.option.id.value)) await this.database.set("openticket:option-suffix-history",this.option.id.value,[])
}
#generateUniqueValue(history:string[]): string { #generateUniqueValue(history:string[]): string {
const hex = crypto.randomBytes(2).toString("hex") const hex = crypto.randomBytes(2).toString("hex")
if (history.includes(hex)) return this.#generateUniqueValue(history) if (history.includes(hex)) return this.#generateUniqueValue(history)
+2 -2
View File
@@ -78,7 +78,7 @@ const loadAllVersionMigrations = async (lastVersion:api.ODVersion) => {
const saveAllVersionsToDatabase = async () => { const saveAllVersionsToDatabase = async () => {
const globalDatabase = openticket.databases.get("openticket:global") const globalDatabase = openticket.databases.get("openticket:global")
await openticket.versions.loopAll((version,id) => { await openticket.versions.loopAll(async (version,id) => {
globalDatabase.set("openticket:last-version",id.value,version.toString()) await globalDatabase.set("openticket:last-version",id.value,version.toString())
}) })
} }
+39 -39
View File
@@ -86,14 +86,14 @@ export const loadDatabaseCleanersCode = async () => {
//remove all unused panels //remove all unused panels
for (const panel of (await globalDatabase.getCategory("openticket:panel-update") ?? [])){ for (const panel of (await globalDatabase.getCategory("openticket:panel-update") ?? [])){
if (!validPanels.includes(panel.key)){ if (!validPanels.includes(panel.key)){
globalDatabase.delete("openticket:panel-update",panel.key) await globalDatabase.delete("openticket:panel-update",panel.key)
} }
} }
//delete panel from database on delete //delete panel from database on delete
openticket.client.client.on("messageDelete",(msg) => { openticket.client.client.on("messageDelete",async (msg) => {
if (globalDatabase.exists("openticket:panel-update",msg.channel.id+"_"+msg.id)){ if (await globalDatabase.exists("openticket:panel-update",msg.channel.id+"_"+msg.id)){
globalDatabase.delete("openticket:panel-update",msg.channel.id+"_"+msg.id) await globalDatabase.delete("openticket:panel-update",msg.channel.id+"_"+msg.id)
} }
}) })
})) }))
@@ -120,24 +120,24 @@ export const loadDatabaseCleanersCode = async () => {
//remove all unused suffix counters //remove all unused suffix counters
for (const counter of (await globalDatabase.getCategory("openticket:option-suffix-counter") ?? [])){ for (const counter of (await globalDatabase.getCategory("openticket:option-suffix-counter") ?? [])){
if (!validSuffixCounters.includes(counter.key)){ if (!validSuffixCounters.includes(counter.key)){
globalDatabase.delete("openticket:option-suffix-counter",counter.key) await globalDatabase.delete("openticket:option-suffix-counter",counter.key)
} }
} }
//remove all unused suffix histories //remove all unused suffix histories
for (const history of (await globalDatabase.getCategory("openticket:option-suffix-history") ?? [])){ for (const history of (await globalDatabase.getCategory("openticket:option-suffix-history") ?? [])){
if (!validSuffixHistories.includes(history.key)){ if (!validSuffixHistories.includes(history.key)){
globalDatabase.delete("openticket:option-suffix-history",history.key) await globalDatabase.delete("openticket:option-suffix-history",history.key)
} }
} }
})) }))
//OPTION DATABASE CLEANER //OPTION DATABASE CLEANER
openticket.code.add(new api.ODCode("openticket:option-database-cleaner",10,() => { openticket.code.add(new api.ODCode("openticket:option-database-cleaner",10,() => {
//delete all unused options //delete all unused options (async)
openticket.options.getAll().forEach((option) => { openticket.options.getAll().forEach(async (option) => {
if (optionDatabase.exists("openticket:used-option",option.id.value) && !openticket.tickets.getAll().some((ticket) => ticket.option.id.value == option.id.value)){ if (await optionDatabase.exists("openticket:used-option",option.id.value) && !openticket.tickets.getAll().some((ticket) => ticket.option.id.value == option.id.value)){
optionDatabase.delete("openticket:used-option",option.id.value) await optionDatabase.delete("openticket:used-option",option.id.value)
} }
}) })
})) }))
@@ -172,7 +172,7 @@ export const loadDatabaseCleanersCode = async () => {
//remove all unused users //remove all unused users
for (const user of (await userDatabase.getAll())){ for (const user of (await userDatabase.getAll())){
if (!validUsers.includes(user.key)){ if (!validUsers.includes(user.key)){
userDatabase.delete(user.category,user.key) await userDatabase.delete(user.category,user.key)
} }
} }
@@ -180,7 +180,7 @@ export const loadDatabaseCleanersCode = async () => {
for (const stat of (await statsDatabase.getAll())){ for (const stat of (await statsDatabase.getAll())){
if (stat.category.startsWith("openticket:user_")){ if (stat.category.startsWith("openticket:user_")){
if (!validUsers.includes(stat.key)){ if (!validUsers.includes(stat.key)){
statsDatabase.delete(stat.category,stat.key) await statsDatabase.delete(stat.category,stat.key)
} }
} }
} }
@@ -193,7 +193,7 @@ export const loadDatabaseCleanersCode = async () => {
//remove unused user //remove unused user
for (const user of (await userDatabase.getAll())){ for (const user of (await userDatabase.getAll())){
if (user.key == member.id){ if (user.key == member.id){
userDatabase.delete(user.category,user.key) await userDatabase.delete(user.category,user.key)
} }
} }
@@ -201,7 +201,7 @@ export const loadDatabaseCleanersCode = async () => {
for (const stat of (await statsDatabase.getAll())){ for (const stat of (await statsDatabase.getAll())){
if (stat.category.startsWith("openticket:user_")){ if (stat.category.startsWith("openticket:user_")){
if (stat.key == member.id){ if (stat.key == member.id){
statsDatabase.delete(stat.category,stat.key) await statsDatabase.delete(stat.category,stat.key)
} }
} }
} }
@@ -237,7 +237,7 @@ export const loadDatabaseCleanersCode = async () => {
//remove all unused tickets //remove all unused tickets
for (const ticket of (await ticketDatabase.getAll())){ for (const ticket of (await ticketDatabase.getAll())){
if (!validTickets.includes(ticket.key)){ if (!validTickets.includes(ticket.key)){
ticketDatabase.delete(ticket.category,ticket.key) await ticketDatabase.delete(ticket.category,ticket.key)
openticket.tickets.remove(ticket.key) openticket.tickets.remove(ticket.key)
} }
} }
@@ -246,7 +246,7 @@ export const loadDatabaseCleanersCode = async () => {
for (const stat of (await statsDatabase.getAll())){ for (const stat of (await statsDatabase.getAll())){
if (stat.category.startsWith("openticket:ticket_")){ if (stat.category.startsWith("openticket:ticket_")){
if (!validTickets.includes(stat.key)){ if (!validTickets.includes(stat.key)){
statsDatabase.delete(stat.category,stat.key) await statsDatabase.delete(stat.category,stat.key)
} }
} }
} }
@@ -258,7 +258,7 @@ export const loadDatabaseCleanersCode = async () => {
//remove unused ticket //remove unused ticket
for (const ticket of (await ticketDatabase.getAll())){ for (const ticket of (await ticketDatabase.getAll())){
if (ticket.key == channel.id){ if (ticket.key == channel.id){
ticketDatabase.delete(ticket.category,ticket.key) await ticketDatabase.delete(ticket.category,ticket.key)
openticket.tickets.remove(ticket.key) openticket.tickets.remove(ticket.key)
} }
} }
@@ -267,7 +267,7 @@ export const loadDatabaseCleanersCode = async () => {
for (const stat of (await statsDatabase.getAll())){ for (const stat of (await statsDatabase.getAll())){
if (stat.category.startsWith("openticket:ticket_")){ if (stat.category.startsWith("openticket:ticket_")){
if (stat.key == channel.id){ if (stat.key == channel.id){
statsDatabase.delete(stat.category,stat.key) await statsDatabase.delete(stat.category,stat.key)
} }
} }
} }
@@ -314,49 +314,49 @@ export const loadDatabaseSaversCode = async () => {
openticket.code.add(new api.ODCode("openticket:ticket-saver",6,() => { openticket.code.add(new api.ODCode("openticket:ticket-saver",6,() => {
const mainVersion = openticket.versions.get("openticket:version") const mainVersion = openticket.versions.get("openticket:version")
openticket.tickets.onAdd((ticket) => { openticket.tickets.onAdd(async (ticket) => {
ticketDatabase.set("openticket:ticket",ticket.id.value,ticket.toJson(mainVersion)) await ticketDatabase.set("openticket:ticket",ticket.id.value,ticket.toJson(mainVersion))
//add option to database if non-existent //add option to database if non-existent
if (!optionDatabase.exists("openticket:used-option",ticket.option.id.value)){ if (!(await optionDatabase.exists("openticket:used-option",ticket.option.id.value))){
optionDatabase.set("openticket:used-option",ticket.option.id.value,ticket.option.toJson(mainVersion)) await optionDatabase.set("openticket:used-option",ticket.option.id.value,ticket.option.toJson(mainVersion))
} }
}) })
openticket.tickets.onChange((ticket) => { openticket.tickets.onChange(async (ticket) => {
ticketDatabase.set("openticket:ticket",ticket.id.value,ticket.toJson(mainVersion)) await ticketDatabase.set("openticket:ticket",ticket.id.value,ticket.toJson(mainVersion))
//add option to database if non-existent //add option to database if non-existent
if (!optionDatabase.exists("openticket:used-option",ticket.option.id.value)){ if (!(await optionDatabase.exists("openticket:used-option",ticket.option.id.value))){
optionDatabase.set("openticket:used-option",ticket.option.id.value,ticket.option.toJson(mainVersion)) await optionDatabase.set("openticket:used-option",ticket.option.id.value,ticket.option.toJson(mainVersion))
} }
//delete all unused options on ticket move //delete all unused options on ticket move
openticket.options.getAll().forEach((option) => { for (const option of openticket.options.getAll()){
if (optionDatabase.exists("openticket:used-option",option.id.value) && !openticket.tickets.getAll().some((ticket) => ticket.option.id.value == option.id.value)){ if (await optionDatabase.exists("openticket:used-option",option.id.value) && !openticket.tickets.getAll().some((ticket) => ticket.option.id.value == option.id.value)){
optionDatabase.delete("openticket:used-option",option.id.value) await optionDatabase.delete("openticket:used-option",option.id.value)
}
} }
}) })
}) openticket.tickets.onRemove(async (ticket) => {
openticket.tickets.onRemove((ticket) => { await ticketDatabase.delete("openticket:ticket",ticket.id.value)
ticketDatabase.delete("openticket:ticket",ticket.id.value)
//remove option from database if unused //remove option from database if unused
if (!openticket.tickets.getAll().some((ticket) => ticket.option.id.value == ticket.option.id.value)){ if (!openticket.tickets.getAll().some((ticket) => ticket.option.id.value == ticket.option.id.value)){
optionDatabase.delete("openticket:used-option",ticket.option.id.value) await optionDatabase.delete("openticket:used-option",ticket.option.id.value)
} }
}) })
})) }))
//BLACKLIST SAVER //BLACKLIST SAVER
openticket.code.add(new api.ODCode("openticket:blacklist-saver",5,() => { openticket.code.add(new api.ODCode("openticket:blacklist-saver",5,() => {
openticket.blacklist.onAdd((blacklist) => { openticket.blacklist.onAdd(async (blacklist) => {
userDatabase.set("openticket:blacklist",blacklist.id.value,blacklist.reason) await userDatabase.set("openticket:blacklist",blacklist.id.value,blacklist.reason)
}) })
openticket.blacklist.onChange((blacklist) => { openticket.blacklist.onChange(async (blacklist) => {
userDatabase.set("openticket:blacklist",blacklist.id.value,blacklist.reason) await userDatabase.set("openticket:blacklist",blacklist.id.value,blacklist.reason)
}) })
openticket.blacklist.onRemove((blacklist) => { openticket.blacklist.onRemove(async (blacklist) => {
userDatabase.delete("openticket:blacklist",blacklist.id.value) await userDatabase.delete("openticket:blacklist",blacklist.id.value)
}) })
})) }))
+4
View File
@@ -20,10 +20,14 @@ export const loadAllEvents = () => {
//configs //configs
"onConfigLoad", "onConfigLoad",
"afterConfigsLoaded", "afterConfigsLoaded",
"onConfigInit",
"afterConfigsInitiated",
//databases //databases
"onDatabaseLoad", "onDatabaseLoad",
"afterDatabasesLoaded", "afterDatabasesLoaded",
"onDatabaseInit",
"afterDatabasesInitiated",
//languages //languages
"onLanguageLoad", "onLanguageLoad",
+8 -6
View File
@@ -8,24 +8,26 @@ export const loadAllTickets = async () => {
const tickets = await ticketDatabase.getCategory("openticket:ticket") const tickets = await ticketDatabase.getCategory("openticket:ticket")
if (!tickets) return if (!tickets) return
tickets.forEach((ticket) => { for (const ticket of tickets){
console.log(ticket.value)
try { try {
openticket.tickets.add(loadTicket(ticket.value)) openticket.tickets.add(await loadTicket(ticket.value))
}catch (err){ }catch (err){
process.emit("uncaughtException",err)
process.emit("uncaughtException",new api.ODSystemError("Failed to load ticket from database! => id: "+ticket.key+"\n ===> "+err)) process.emit("uncaughtException",new api.ODSystemError("Failed to load ticket from database! => id: "+ticket.key+"\n ===> "+err))
} }
}) }
} }
export const loadTicket = (ticket:api.ODTicketJson) => { export const loadTicket = async (ticket:api.ODTicketJson) => {
const backupOption = optionDatabase.exists("openticket:used-option",ticket.option) ? api.ODTicketOption.fromJson(optionDatabase.get("openticket:used-option",ticket.option) as api.ODOptionJson) : null const backupOption = (await optionDatabase.exists("openticket:used-option",ticket.option)) ? api.ODTicketOption.fromJson(await optionDatabase.get("openticket:used-option",ticket.option) as api.ODOptionJson) : null
const configOption = openticket.options.get(ticket.option) const configOption = openticket.options.get(ticket.option)
//check if option is of type "ticket" //check if option is of type "ticket"
if (configOption && !(configOption instanceof api.ODTicketOption)) throw new api.ODSystemError("Unable to load ticket because option is not of 'ticket' type!") if (configOption && !(configOption instanceof api.ODTicketOption)) throw new api.ODSystemError("Unable to load ticket because option is not of 'ticket' type!")
//manage backup option //manage backup option
if (configOption) optionDatabase.set("openticket:used-option",configOption.id.value,configOption.toJson(openticket.versions.get("openticket:version"))) if (configOption) await optionDatabase.set("openticket:used-option",configOption.id.value,configOption.toJson(openticket.versions.get("openticket:version")))
else if (backupOption) openticket.options.add(backupOption) else if (backupOption) openticket.options.add(backupOption)
else throw new api.ODSystemError("Unable to use backup option! Normal option not found in config!") else throw new api.ODSystemError("Unable to use backup option! Normal option not found in config!")
+14
View File
@@ -122,6 +122,13 @@ const main = async () => {
await openticket.events.get("onConfigLoad").emit([openticket.configs]) await openticket.events.get("onConfigLoad").emit([openticket.configs])
await openticket.events.get("afterConfigsLoaded").emit([openticket.configs]) await openticket.events.get("afterConfigsLoaded").emit([openticket.configs])
//initiate config
await openticket.events.get("onConfigInit").emit([openticket.configs])
if (openticket.defaults.getDefault("configInitiating")){
await openticket.configs.init()
await openticket.events.get("afterConfigsInitiated").emit([openticket.configs])
}
//UTILITY CONFIG //UTILITY CONFIG
const generalConfig = openticket.configs.get("openticket:general") const generalConfig = openticket.configs.get("openticket:general")
@@ -138,6 +145,13 @@ const main = async () => {
await openticket.events.get("onDatabaseLoad").emit([openticket.databases]) await openticket.events.get("onDatabaseLoad").emit([openticket.databases])
await openticket.events.get("afterDatabasesLoaded").emit([openticket.databases]) await openticket.events.get("afterDatabasesLoaded").emit([openticket.databases])
//initiate database
await openticket.events.get("onDatabaseInit").emit([openticket.databases])
if (openticket.defaults.getDefault("databaseInitiating")){
await openticket.databases.init()
await openticket.events.get("afterDatabasesInitiated").emit([openticket.databases])
}
//load sessions //load sessions
openticket.log("Loading sessions...","system") openticket.log("Loading sessions...","system")
if (openticket.defaults.getDefault("sessionLoading")){ if (openticket.defaults.getDefault("sessionLoading")){