mirror of
https://gitlab.edgegamers.io/discord/ds-bot.git
synced 2025-12-06 00:42:41 -08:00
Begin work on overhauling config
This commit is contained in:
900
package-lock.json
generated
900
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,8 @@
|
||||
"@edgmrs/maul": "^1.1.1",
|
||||
"discord.js": "^14.9.0",
|
||||
"install": "^0.13.0",
|
||||
"npm": "^9.6.4"
|
||||
"npm": "^9.6.4",
|
||||
"sqlite": "^4.1.2",
|
||||
"sqlite3": "^5.1.6"
|
||||
}
|
||||
}
|
||||
|
||||
62
src/Bot.ts
62
src/Bot.ts
@@ -3,7 +3,6 @@ import { Client, MessageCreateOptions, MessagePayload, TextBasedChannel } from "
|
||||
import { DSBot } from "./api/DSBot";
|
||||
import { AbstractModuleManager } from "./api/ModuleManager";
|
||||
import { BotConfig } from "./api/data/BotConfig";
|
||||
import { FileConfig } from "./data/FileConfig";
|
||||
import { LogSettings, LogsConfig, Severity } from "./data/configs/Logs";
|
||||
import { MaulConfig, MaulEntry } from "./data/configs/MAUL";
|
||||
import { TokenEntry } from "./data/configs/Token";
|
||||
@@ -14,6 +13,8 @@ import { PermissionsManager } from "./modules/PermissionsManager";
|
||||
import { ReactRoles } from "./modules/ReactRoles";
|
||||
import { PingCommand } from "./modules/commands/PingCommand";
|
||||
import { VoiceCommand } from "./modules/commands/VoiceCommand";
|
||||
import { FileConfigStorage } from "./data/FileConfigStorage";
|
||||
import { ConfigManager } from "./api/data/ConfigManager";
|
||||
|
||||
export class Bot implements DSBot {
|
||||
maul: MaulAPI | undefined;
|
||||
@@ -25,40 +26,43 @@ export class Bot implements DSBot {
|
||||
|
||||
constructor() {
|
||||
this.modules = new ModuleManager();
|
||||
this.config = new FileConfig("configs/global.json");
|
||||
this.data = new FileConfig("data/data.json");
|
||||
|
||||
const tokenEntry = this.config.registerEntry(new TokenEntry());
|
||||
const maulEntry = this.config.registerEntry(new MaulEntry());
|
||||
const logEntry = this.config.registerEntry(new LogsConfig()) as LogsConfig;
|
||||
|
||||
// this.config = new FileConfig("configs/global.json");
|
||||
// this.data = new FileConfig("data/data.json");
|
||||
this.config = new ConfigManager(new FileConfigStorage("configs/global.json"));
|
||||
this.client = new Client({ intents: ["Guilds", "GuildMessageReactions", "GuildVoiceStates", "DirectMessages"] });
|
||||
this.config.load().then(() => {
|
||||
this.config.getValue(tokenEntry).then(token => {
|
||||
this.client.login(token as string);
|
||||
|
||||
async () => {
|
||||
const tokenEntry = await this.config.registerEntry(new TokenEntry());
|
||||
const maulEntry = await this.config.registerEntry(new MaulEntry());
|
||||
const logEntry = await this.config.registerEntry(new LogsConfig()) as LogsConfig;
|
||||
|
||||
this.config.load().then(() => {
|
||||
this.config.getValue(tokenEntry).then(token => {
|
||||
this.client.login(token as string);
|
||||
});
|
||||
|
||||
this.config.getValue(maulEntry).then((result) => {
|
||||
const conf = result as MaulConfig;
|
||||
this.maul = new MAUL(conf.URL, conf.TOKEN, conf.IP);
|
||||
});
|
||||
|
||||
this.logger = logEntry.value;
|
||||
});
|
||||
|
||||
this.config.getValue(maulEntry).then((result) => {
|
||||
const conf = result as MaulConfig;
|
||||
this.maul = new MAUL(conf.URL, conf.TOKEN, conf.IP);
|
||||
this.client.once("ready", () => {
|
||||
this.log(Severity.DEBUG, `Successfully logged in as ${this.client.user?.tag}.`);
|
||||
this.initModules();
|
||||
});
|
||||
|
||||
this.logger = logEntry.value;
|
||||
});
|
||||
this.client.on("error", (error) => {
|
||||
this.log(Severity.ERROR, `I ran into an API error: ${error.name}\n${error.message}\n${error.stack}`);
|
||||
});
|
||||
|
||||
this.client.once("ready", () => {
|
||||
this.log(Severity.DEBUG, `Successfully logged in as ${this.client.user?.tag}.`);
|
||||
this.initModules();
|
||||
});
|
||||
|
||||
this.client.on("error", (error) => {
|
||||
this.log(Severity.ERROR, `I ran into an API error: ${error.name}\n${error.message}\n${error.stack}`);
|
||||
});
|
||||
|
||||
process.on("unhandledRejection", (error) => {
|
||||
console.error(error);
|
||||
this.log(Severity.ERROR, `I ran into a process error: ${(error as any).stack}`);
|
||||
});
|
||||
process.on("unhandledRejection", (error) => {
|
||||
console.error(error);
|
||||
this.log(Severity.ERROR, `I ran into a process error: ${(error as any).stack}`);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
log(severity: Severity, message: string | MessagePayload | MessageCreateOptions): void {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Config } from "./Config";
|
||||
import { GuildConfig } from "./GuildConfig";
|
||||
import { Config, GuildConfig } from "./Config";
|
||||
|
||||
export interface BotConfig extends Config {
|
||||
getGuildConfig(guildId: string): Promise<GuildConfig>;
|
||||
|
||||
@@ -8,10 +8,10 @@ export interface GuildedConfigEntry<T = unknown> extends ConfigEntry<T> {
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
registerEntry(entry: ConfigEntry): ConfigEntry;
|
||||
registerEntry(entry: ConfigEntry): Promise<ConfigEntry>;
|
||||
removeEntry(entry: ConfigEntry): void;
|
||||
|
||||
getConfigEntry(name: string): ConfigEntry | undefined;
|
||||
getConfigEntry(name: string): Promise<ConfigEntry | undefined>;
|
||||
getEntries(): Promise<ConfigEntry[]>;
|
||||
|
||||
getValue(id: string | ConfigEntry): Promise<unknown>;
|
||||
@@ -19,7 +19,19 @@ export interface Config {
|
||||
|
||||
save(): Promise<void>;
|
||||
save<T extends ConfigEntry>(entry: T): Promise<T>;
|
||||
|
||||
|
||||
load(): Promise<void>;
|
||||
load<T extends ConfigEntry>(entry: T): Promise<T>;
|
||||
}
|
||||
|
||||
// export interface GuildConfig extends Config {
|
||||
// guildId: string;
|
||||
// }
|
||||
|
||||
export interface ConfigStorage {
|
||||
getEntry(id: string): Promise<ConfigEntry | undefined>;
|
||||
getEntries(): Promise<ConfigEntry[]>;
|
||||
saveEntry(entry: ConfigEntry): Promise<void>;
|
||||
removeEntry(entry: ConfigEntry): Promise<void>;
|
||||
load(): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
import { Config } from "./Config";
|
||||
import { ConfigManager } from "./ConfigManager";
|
||||
import { ConfigStorage } from "./Config";
|
||||
import { GuildedConfigEntry } from "./Config";
|
||||
|
||||
export interface GuildConfig extends Config {
|
||||
guildId: string;
|
||||
export class GuildConfig extends ConfigManager {
|
||||
constructor(private guildId: string, storage: ConfigStorage) {
|
||||
super(storage);
|
||||
}
|
||||
|
||||
async registerGuildEntry(entry: GuildedConfigEntry): Promise<GuildedConfigEntry> {
|
||||
entry.guildId = this.guildId;
|
||||
return await this.registerEntry(entry) as GuildedConfigEntry;
|
||||
}
|
||||
|
||||
async getGuildConfigEntry(name: string): Promise<GuildedConfigEntry | undefined> {
|
||||
const entry = this.getConfigEntry(name);
|
||||
if (entry && "guildId" in entry)
|
||||
return await entry as GuildedConfigEntry;
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
import * as fs from "fs";
|
||||
import { BotConfig } from "../api/data/BotConfig";
|
||||
import { ConfigEntry } from "../api/data/Config";
|
||||
import { GuildConfig } from "../api/data/GuildConfig";
|
||||
|
||||
export class FileConfig implements BotConfig {
|
||||
entries: ConfigEntry[] = [];
|
||||
configs: GuildConfig[] = [];
|
||||
file: string;
|
||||
parent: string;
|
||||
|
||||
constructor(file: string) {
|
||||
this.file = file;
|
||||
this.parent = file.split("/").slice(0, -1).join("/");
|
||||
}
|
||||
|
||||
getGuildConfigs(): Promise<GuildConfig[]> {
|
||||
return Promise.resolve(this.configs);
|
||||
}
|
||||
|
||||
addGuildConfig(config: GuildConfig): void {
|
||||
this.configs.push(config);
|
||||
}
|
||||
|
||||
getGuildConfig(guildId: string): Promise<GuildConfig> {
|
||||
let config = this.configs.find((c) => c.guildId === guildId);
|
||||
|
||||
if (!config) {
|
||||
console.log(`Creating new guild config: ${guildId}`);
|
||||
config = new FileGuildConfig(this.parent + `/guilds/${guildId}.json`, guildId);
|
||||
this.configs.push(config);
|
||||
}
|
||||
|
||||
return Promise.resolve(config);
|
||||
}
|
||||
|
||||
async getEntries(): Promise<ConfigEntry[]> {
|
||||
return this.entries;
|
||||
}
|
||||
|
||||
async getValue(id: string | ConfigEntry): Promise<unknown> {
|
||||
if (typeof id === "string")
|
||||
return this.getConfigEntry(id)?.value;
|
||||
for (const entry of this.entries) {
|
||||
if (entry.name === id.name)
|
||||
return entry.value;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async setValue(id: string | ConfigEntry<unknown>, value: unknown): Promise<void> {
|
||||
const entry = this.getConfigEntry((typeof id === "string") ? id : id.name);
|
||||
if (!entry)
|
||||
return Promise.reject(`Config entry not found: ${id}`);
|
||||
|
||||
entry.value = value;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
async load(): Promise<void> {
|
||||
const promise = new Promise<void>((resolve, reject) => {
|
||||
if (!fs.existsSync(this.file)) {
|
||||
console.log(`Creating new config file: ${this.file}`);
|
||||
fs.writeFileSync(this.file, "{}");
|
||||
}
|
||||
fs.open(this.file, "r", (err, fd) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
reject(err);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the file as JSON
|
||||
const data = JSON.parse(fs.readFileSync(fd, "utf8"));
|
||||
// For each key in the JSON object, create a new ConfigEntry
|
||||
for (const key in data) {
|
||||
const entry = this.getConfigEntry(key);
|
||||
if (!entry) {
|
||||
console.error(`Config entry not found: ${key}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
entry.value = data[key];
|
||||
}
|
||||
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
if (this.configs.length === 0 && !this.file.includes("guilds")) {
|
||||
const files = fs.readdirSync(this.parent + "/guilds");
|
||||
for (const file of files) {
|
||||
console.log(`Loading guild config: ${file}`);
|
||||
const config = new FileGuildConfig(this.parent + `/guilds/${file}`, file.split(".")[0]);
|
||||
this.configs.push(config);
|
||||
}
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
registerEntry(entry: ConfigEntry): ConfigEntry {
|
||||
this.entries.push(entry);
|
||||
return entry;
|
||||
}
|
||||
removeEntry(entry: ConfigEntry): void {
|
||||
this.entries.splice(this.entries.indexOf(entry), 1);
|
||||
}
|
||||
async save() {
|
||||
// JSON stringify entries and write to file
|
||||
const data: any = {};
|
||||
this.entries.forEach(entry => {
|
||||
data[entry.name] = entry.value;
|
||||
});
|
||||
|
||||
|
||||
fs.writeFileSync(this.file, JSON.stringify(data));
|
||||
}
|
||||
|
||||
getConfigEntry(name: string): ConfigEntry | undefined {
|
||||
return this.entries.find(entry => entry.name === name);
|
||||
}
|
||||
}
|
||||
|
||||
export class FileGuildConfig extends FileConfig implements GuildConfig {
|
||||
guildId: string;
|
||||
|
||||
constructor(file: string, guildId: string) {
|
||||
super(file);
|
||||
this.guildId = guildId;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user