TravBot-v3/src/structures.ts

178 lines
6 KiB
TypeScript
Raw Normal View History

import FileManager from "./modules/storage";
import {select, GenericJSON, GenericStructure} from "./lib";
2020-12-15 01:44:28 +00:00
import {watch} from "fs";
2020-12-31 16:10:56 +00:00
import {Guild as DiscordGuild, Snowflake} from "discord.js";
2020-10-15 09:23:24 +00:00
// Maybe use getters and setters to auto-save on set?
2020-10-15 09:23:24 +00:00
class ConfigStructure extends GenericStructure {
2020-12-15 01:44:28 +00:00
public token: string;
public prefix: string;
public owner: string;
public admins: string[];
public support: string[];
public systemLogsChannel: string | null;
2020-12-15 01:44:28 +00:00
constructor(data: GenericJSON) {
super("config");
this.token = select(data.token, "<ENTER YOUR TOKEN HERE>", String);
this.prefix = select(data.prefix, "$", String);
this.owner = select(data.owner, "", String);
this.admins = select(data.admins, [], String, true);
this.support = select(data.support, [], String, true);
this.systemLogsChannel = select(data.systemLogsChannel, null, String);
2020-12-15 01:44:28 +00:00
}
}
2020-10-15 09:23:24 +00:00
class User {
2020-12-15 01:44:28 +00:00
public money: number;
public lastReceived: number;
2020-12-16 07:24:26 +00:00
public lastMonday: number;
public timezone: number | null; // This is for the standard timezone only, not the daylight savings timezone
public daylightSavingsRegion: "na" | "eu" | "sh" | null;
public todoList: {[timestamp: string]: string};
2021-04-06 06:02:52 +00:00
public ecoBetInsurance: number;
2020-10-15 09:23:24 +00:00
2020-12-15 01:44:28 +00:00
constructor(data?: GenericJSON) {
this.money = select(data?.money, 0, Number);
this.lastReceived = select(data?.lastReceived, -1, Number);
2020-12-16 07:24:26 +00:00
this.lastMonday = select(data?.lastMonday, -1, Number);
this.timezone = data?.timezone ?? null;
this.daylightSavingsRegion = /^((na)|(eu)|(sh))$/.test(data?.daylightSavingsRegion)
? data?.daylightSavingsRegion
: null;
this.todoList = {};
this.ecoBetInsurance = select(data?.ecoBetInsurance, 0, Number);
if (data) {
for (const timestamp in data.todoList) {
const note = data.todoList[timestamp];
if (typeof note === "string") {
this.todoList[timestamp] = note;
}
}
}
2020-12-15 01:44:28 +00:00
}
}
2020-10-15 09:23:24 +00:00
class Guild {
2020-12-15 01:44:28 +00:00
public prefix: string | null;
2021-04-01 13:41:49 +00:00
public welcomeType: "none" | "text" | "graphical";
public welcomeChannel: string | null;
public welcomeMessage: string | null;
public streamingChannel: string | null;
2020-10-15 09:23:24 +00:00
2020-12-15 01:44:28 +00:00
constructor(data?: GenericJSON) {
this.prefix = select(data?.prefix, null, String);
2021-04-01 13:41:49 +00:00
this.welcomeChannel = select(data?.welcomeChannel, null, String);
this.welcomeMessage = select(data?.welcomeMessage, null, String);
this.streamingChannel = select(data?.streamingChannel, null, String);
2021-04-01 13:41:49 +00:00
switch (data?.welcomeType) {
case "text":
this.welcomeType = "text";
break;
case "graphical":
this.welcomeType = "graphical";
break;
default:
this.welcomeType = "none";
break;
}
2020-12-15 01:44:28 +00:00
}
}
2020-10-15 09:23:24 +00:00
class StorageStructure extends GenericStructure {
2020-12-15 01:44:28 +00:00
public users: {[id: string]: User};
public guilds: {[id: string]: Guild};
constructor(data: GenericJSON) {
super("storage");
this.users = {};
this.guilds = {};
2020-12-15 07:56:09 +00:00
for (let id in data.users) if (/\d{17,19}/g.test(id)) this.users[id] = new User(data.users[id]);
2020-12-15 01:44:28 +00:00
2020-12-15 07:56:09 +00:00
for (let id in data.guilds) if (/\d{17,19}/g.test(id)) this.guilds[id] = new Guild(data.guilds[id]);
2020-10-15 09:23:24 +00:00
}
2020-12-15 01:44:28 +00:00
/** Gets a user's profile if they exist and generate one if not. */
public getUser(id: string): User {
if (!/\d{17,19}/g.test(id))
console.warn(`"${id}" is not a valid user ID! It will be erased when the data loads again.`);
2020-12-15 01:44:28 +00:00
if (id in this.users) return this.users[id];
else {
const user = new User();
this.users[id] = user;
return user;
}
}
/** Gets a guild's settings if they exist and generate one if not. */
public getGuild(id: string): Guild {
if (!/\d{17,19}/g.test(id))
console.warn(`"${id}" is not a valid guild ID! It will be erased when the data loads again.`);
2020-12-15 01:44:28 +00:00
if (id in this.guilds) return this.guilds[id];
else {
const guild = new Guild();
this.guilds[id] = guild;
return guild;
}
2020-10-15 09:23:24 +00:00
}
}
// Exports instances. Don't worry, importing it from different files will load the same instance.
2020-12-15 01:44:28 +00:00
export let Config = new ConfigStructure(FileManager.read("config"));
export let Storage = new StorageStructure(FileManager.read("storage"));
// This part will allow the user to manually edit any JSON files they want while the program is running which'll update the program's cache.
// However, fs.watch is a buggy mess that should be avoided in production. While it helps test out stuff for development, it's not a good idea to have it running outside of development as it causes all sorts of issues.
if (IS_DEV_MODE) {
2020-12-15 01:44:28 +00:00
watch("data", (event, filename) => {
console.debug("File Watcher:", event, filename);
2020-12-15 01:44:28 +00:00
const header = filename.substring(0, filename.indexOf(".json"));
switch (header) {
case "config":
Config = new ConfigStructure(FileManager.read("config"));
break;
case "storage":
Storage = new StorageStructure(FileManager.read("storage"));
break;
}
});
}
2020-10-15 09:23:24 +00:00
export function getPrefix(guild: DiscordGuild | null): string {
let prefix = Config.prefix;
if (guild) {
const possibleGuildPrefix = Storage.getGuild(guild.id).prefix;
// Here, lossy comparison works in our favor because you wouldn't want an empty string to trigger the prefix.
if (possibleGuildPrefix) {
prefix = possibleGuildPrefix;
}
}
return prefix;
2020-10-15 09:23:24 +00:00
}
2020-12-31 16:10:56 +00:00
export interface EmoteRegistryDumpEntry {
ref: string;
2020-12-31 16:10:56 +00:00
id: Snowflake;
name: string;
requires_colons: boolean;
animated: boolean;
url: string;
guild_id: Snowflake;
2020-12-31 16:10:56 +00:00
guild_name: string;
}
export interface EmoteRegistryDump {
version: number;
list: EmoteRegistryDumpEntry[];
}