From 8948019e09f554f7282820346afa8f33227dca23 Mon Sep 17 00:00:00 2001 From: zkldi <20380519+zkldi@users.noreply.github.com> Date: Sun, 7 Apr 2024 21:05:53 +0100 Subject: [PATCH] feat: get config all in one place --- bot/src/config.ts | 9 ++++----- bot/src/main.ts | 6 +++--- bot/src/slashCommands/commands.ts | 4 ++-- bot/src/slashCommands/commands/faq.ts | 22 +++++++++++----------- bot/src/slashCommands/commands/ping.ts | 4 ++-- bot/src/slashCommands/commands/sync.ts | 2 +- bot/src/slashCommands/commands/whois.ts | 2 +- bot/src/utils/embeds.ts | 8 ++------ bot/src/utils/options.ts | 2 +- bot/src/utils/returnTypes.ts | 14 +------------- client/src/lib/config.ts | 12 ++---------- common/src/types.ts | 14 ++++++++++++++ server/src/lib/setup/config.ts | 10 ++-------- 13 files changed, 46 insertions(+), 63 deletions(-) diff --git a/bot/src/config.ts b/bot/src/config.ts index 2300ed974..fec146626 100644 --- a/bot/src/config.ts +++ b/bot/src/config.ts @@ -8,8 +8,7 @@ import { p } from "prudence"; // @ts-expect-error No types available... import fetchSync from "sync-fetch"; import fs from "fs"; -import type { ServerConfig as ServerConfigType } from "./utils/returnTypes"; -import type { Game, integer } from "tachi-common"; +import type { Game, integer, TachiServerCoreConfig } from "tachi-common"; // Initialise .env. config(); @@ -160,7 +159,7 @@ function GetServerConfig() { process.exit(1); } - return res.body as ServerConfigType; + return res.body as TachiServerCoreConfig; } export const ServerConfig = GetServerConfig(); @@ -169,10 +168,10 @@ export const ProcessEnv = ParseEnvVars(); // General warnings for config misuse. // This warns people if their parent server supports games that they aren't acknowledging. -for (const game of ServerConfig.games) { +for (const game of ServerConfig.GAMES) { if (!Object.prototype.hasOwnProperty.call(BotConfig.DISCORD.GAME_CHANNELS, game)) { logger.warn( - `${ServerConfig.name} declares support for ${game}, but no channel is mapped to it in your conf.json5.` + `${ServerConfig.NAME} declares support for ${game}, but no channel is mapped to it in your conf.json5.` ); } } diff --git a/bot/src/main.ts b/bot/src/main.ts index d25af97c8..3f6d4e0f1 100644 --- a/bot/src/main.ts +++ b/bot/src/main.ts @@ -32,7 +32,7 @@ client.on("guildMemberAdd", async (member) => { const channel = GetLimboChannel(client); await channel.send( - `Hello! If you already have an account on ${ServerConfig.name}, run \`/letmein\` in #limbo to be let in. Otherwise, ask for an invite in #limbo.` + `Hello! If you already have an account on ${ServerConfig.NAME}, run \`/letmein\` in #limbo to be let in. Otherwise, ask for an invite in #limbo.` ); } }); @@ -66,9 +66,9 @@ async function RequireUserAuth(interaction: CommandInteraction | SelectMenuInter const dmChannel = await interaction.user.createDM(); - await dmChannel.send(`Click this link to authenticate with ${ServerConfig.name}: ${oAuthLink}`); + await dmChannel.send(`Click this link to authenticate with ${ServerConfig.NAME}: ${oAuthLink}`); return interaction.reply({ - content: `To use the bot, your discord account must be linked to ${ServerConfig.name}. + content: `To use the bot, your discord account must be linked to ${ServerConfig.NAME}. We've sent you a DM with instructions on how to link your account.`, ephemeral: true, }); diff --git a/bot/src/slashCommands/commands.ts b/bot/src/slashCommands/commands.ts index 073a71c9d..cbdc7da42 100644 --- a/bot/src/slashCommands/commands.ts +++ b/bot/src/slashCommands/commands.ts @@ -20,11 +20,11 @@ if (BotConfig.DISCORD.APPROVED_ROLE) { } // kamaitachi or omni specific commands -if (ServerConfig.type !== "boku") { +if (ServerConfig.TYPE !== "boku") { SLASH_COMMANDS.set("sync", sync); } // bokutachi or omni specific commands -if (ServerConfig.type !== "kamai") { +if (ServerConfig.TYPE !== "kamai") { SLASH_COMMANDS.set("invite", invite); } diff --git a/bot/src/slashCommands/commands/faq.ts b/bot/src/slashCommands/commands/faq.ts index 16e6c5d67..8630d8b38 100644 --- a/bot/src/slashCommands/commands/faq.ts +++ b/bot/src/slashCommands/commands/faq.ts @@ -5,14 +5,14 @@ import deepmerge from "deepmerge"; import type { SlashCommand } from "../types"; const NEUTRAL_FAQ_ENTRIES: Record = { - duplicates: `Scores on ${ServerConfig.name} are deduplicated based on your score and lamp (and some other things). -If you happen to get the exact same score twice, ${ServerConfig.name} will **ignore** the second one! + duplicates: `Scores on ${ServerConfig.NAME} are deduplicated based on your score and lamp (and some other things). +If you happen to get the exact same score twice, ${ServerConfig.NAME} will **ignore** the second one! There are legitimate reasons for this -- it's very common for people to import the same scores twice through file uploads or import scripts. -For more info on why this is a fundamental limitation of ${ServerConfig.name}, check [the documentation](https://docs.tachi.ac/wiki/score-oddities/#deduplication-false-positives-all-games).`, - contribute: `Contributing to ${ServerConfig.name} in any way will get you the Contributor role, and a cool green name.\n +For more info on why this is a fundamental limitation of ${ServerConfig.NAME}, check [the documentation](https://docs.tachi.ac/wiki/score-oddities/#deduplication-false-positives-all-games).`, + contribute: `Contributing to ${ServerConfig.NAME} in any way will get you the Contributor role, and a cool green name.\n Contributors who save us hours (or more) of dev time, or are just generally really supportive will get the Significant Contributor role, and an even cooler orange name. -${ServerConfig.name} is an Open Source project. Feel free to read our [contribution guide](https://docs.tachi.ac/contributing/), or just generally ask for stuff to help out with!`, - docs: `Documentation for ${ServerConfig.name} is stored at https://docs.tachi.ac.`, +${ServerConfig.NAME} is an Open Source project. Feel free to read our [contribution guide](https://docs.tachi.ac/contributing/), or just generally ask for stuff to help out with!`, + docs: `Documentation for ${ServerConfig.NAME} is stored at https://docs.tachi.ac.`, pbs: `A PB is all of your best scores on that specific chart joined together. For most games, this means joining your best score with your best lamp. Read more about this [here](https://docs.tachi.ac/wiki/pbs-scores/)`, @@ -104,7 +104,7 @@ You should also avoid redundant goals -- all the goals in the quest should ideal I'm ideally looking for something that the average player can just set and have fun checking off. The questline itself should have the quests fairly distinguished, players shouldn't be pushing multiple quests in the same questline at the same time. -Since I don't play a lot of the the games that ${ServerConfig.name} supports, we need your help to come up with some good drafts! Your game might have a dedicated \`-quests\` channel. Check it out and discuss with others!`, +Since I don't play a lot of the the games that ${ServerConfig.NAME} supports, we need your help to come up with some good drafts! Your game might have a dedicated \`-quests\` channel. Check it out and discuss with others!`, }; // Server specific FAQ stuff. @@ -113,13 +113,13 @@ const KAMAI_FAQ_ENTRIES: Record = { bokutachi: `Bokutachi is our public sister website for home games and simulators. Feel free to check out [the discord](${ Buffer.from("aHR0cHM6Ly9kaXNjb3JkLmdnL3N3VkJUanhtUFk=", "base64") // Note: obfuscating this for obvious reasons so we don't get garbage bot spam. })`, - sdvx_1259: `Automation Paradise is song ID 1259. It is not a real song, and it is not supported by ${ServerConfig.name}. Related autopara-only songs are not supported, either.`, + sdvx_1259: `Automation Paradise is song ID 1259. It is not a real song, and it is not supported by ${ServerConfig.NAME}. Related autopara-only songs are not supported, either.`, invites: `To invite your friends, go to your profile and select 'Invites'. From there, you can create an invite code. Your friend can then go to ${BotConfig.TACHI_SERVER_LOCATION} and sign up with the code! You can also invite them to the discord.`, }; const BOKU_FAQ_ENTRIES: Record = { - usc_hard_mode: `Hard Mode windows are not supported on ${ServerConfig.name}. Your scores **will be ignored** if they are played on non-standard windows.`, + usc_hard_mode: `Hard Mode windows are not supported on ${ServerConfig.NAME}. Your scores **will be ignored** if they are played on non-standard windows.`, ir_login: `You **must** put your API Key in the password field for the Bokutachi IR, **NOT your real password!**. See instructions here: ${BotConfig.TACHI_SERVER_LOCATION}/import/beatoraja-ir. (This is because putting your real password in there is a security nightmare.)`, lr2: `Support for LR2 (the LR2Hook) are **not officially maintained** and therefore **not managed by bokutachi developers**. @@ -129,11 +129,11 @@ Beatoraja is actively developed and integrates properly with the Bokutachi IR, i let faqEntries = NEUTRAL_FAQ_ENTRIES; -if (ServerConfig.type !== "boku") { +if (ServerConfig.TYPE !== "boku") { faqEntries = deepmerge(faqEntries, KAMAI_FAQ_ENTRIES); } -if (ServerConfig.type !== "kamai") { +if (ServerConfig.TYPE !== "kamai") { faqEntries = deepmerge(faqEntries, BOKU_FAQ_ENTRIES); } diff --git a/bot/src/slashCommands/commands/ping.ts b/bot/src/slashCommands/commands/ping.ts index b63fb7473..e61f56be8 100644 --- a/bot/src/slashCommands/commands/ping.ts +++ b/bot/src/slashCommands/commands/ping.ts @@ -17,11 +17,11 @@ const command: SlashCommand = { ); if (!serverStatus.success) { - return `Failed to reach ${ServerConfig.name}. (${serverStatus.description})`; + return `Failed to reach ${ServerConfig.NAME}. (${serverStatus.description})`; } return `Pong! We're live, and running ${VERSION_PRETTY}. -${ServerConfig.name} is up, and running ${serverStatus.body.version}.`; +${ServerConfig.NAME} is up, and running ${serverStatus.body.version}.`; }, }; diff --git a/bot/src/slashCommands/commands/sync.ts b/bot/src/slashCommands/commands/sync.ts index 1334d596a..30be5b0cb 100644 --- a/bot/src/slashCommands/commands/sync.ts +++ b/bot/src/slashCommands/commands/sync.ts @@ -21,7 +21,7 @@ const choices: Array<[string, string]> = ( ) // @ts-expect-error god i hate the includes signature - .filter((e) => ServerConfig.importTypes.includes(e[1])); + .filter((e) => ServerConfig.IMPORT_TYPES.includes(e[1])); const command: SlashCommand = { info: new SlashCommandBuilder() diff --git a/bot/src/slashCommands/commands/whois.ts b/bot/src/slashCommands/commands/whois.ts index abf5707c8..b2470c236 100644 --- a/bot/src/slashCommands/commands/whois.ts +++ b/bot/src/slashCommands/commands/whois.ts @@ -8,7 +8,7 @@ import type { SlashCommand } from "../types"; const command: SlashCommand = { info: new SlashCommandBuilder() .setName("whois") - .setDescription(`Return the ${ServerConfig.name} profile of a discord user.`) + .setDescription(`Return the ${ServerConfig.NAME} profile of a discord user.`) .addUserOption((user) => user.setName("user").setDescription("The user to check for.").setRequired(true) ) diff --git a/bot/src/utils/embeds.ts b/bot/src/utils/embeds.ts index d9b9c369c..e81f1ad6d 100644 --- a/bot/src/utils/embeds.ts +++ b/bot/src/utils/embeds.ts @@ -6,7 +6,7 @@ import type { ImportDocument, UserDocument, integer } from "tachi-common"; export function CreateEmbed(userID?: integer) { const embed = new MessageEmbed() - .setColor(ServerConfig.type === "kamai" ? "#e61c6e" : "#527acc") + .setColor(ServerConfig.TYPE === "kamai" ? "#e61c6e" : "#527acc") .setTimestamp(); if (userID !== undefined) { @@ -24,11 +24,7 @@ export function CreateImportEmbed(importDoc: ImportDocument) { "score" )}!` ) - .addField( - "Created Sessions", - importDoc.createdSessions.length.toString(), - true - ) + .addField("Created Sessions", importDoc.createdSessions.length.toString(), true) .addField("Errors", importDoc.errors.length.toString(), true) .addField( "Your Profile", diff --git a/bot/src/utils/options.ts b/bot/src/utils/options.ts index 3be1a8ba2..696709e90 100644 --- a/bot/src/utils/options.ts +++ b/bot/src/utils/options.ts @@ -8,7 +8,7 @@ import type { SlashCommandStringOption } from "@discordjs/builders"; */ const GPTChoices: Array<[string, string]> = []; -for (const game of ServerConfig.games) { +for (const game of ServerConfig.GAMES) { const gameConfig = GetGameConfig(game); for (const playtype of gameConfig.playtypes) { diff --git a/bot/src/utils/returnTypes.ts b/bot/src/utils/returnTypes.ts index 93328389a..43bcf54cf 100644 --- a/bot/src/utils/returnTypes.ts +++ b/bot/src/utils/returnTypes.ts @@ -1,10 +1,8 @@ import type { APIPermissions, ChartDocument, - Game, GPTString, ImportDocument, - ImportTypes, integer, ProfileRatingAlgorithms, ScoreDocument, @@ -12,13 +10,6 @@ import type { UserGameStats, } from "tachi-common"; -export interface ServerConfig { - games: Array; - importTypes: Array; - name: string; - type: "boku" | "kamai" | "omni"; -} - export interface ServerStatus { serverTime: number; startTime: number; @@ -50,10 +41,7 @@ export interface UGPTStats { firstScore: ScoreDocument; mostRecentScore: ScoreDocument; totalScores: integer; - rankingData: Record< - ProfileRatingAlgorithms[GPT], - { ranking: integer; outOf: integer } - >; + rankingData: Record; } export interface ChartQueryReturns { diff --git a/client/src/lib/config.ts b/client/src/lib/config.ts index a64cc64e8..fa6810921 100644 --- a/client/src/lib/config.ts +++ b/client/src/lib/config.ts @@ -1,5 +1,5 @@ import { ToAPIURL } from "util/api"; -import { Game, ImportTypes } from "tachi-common"; +import { Game, ImportTypes, TachiServerCoreConfig } from "tachi-common"; // @ts-expect-error No types available... import syncFetch from "sync-fetch"; @@ -9,14 +9,6 @@ if (!mode) { throw new Error("No VITE_TCHIC_MODE set in Process Environment, refusing to boot."); } -export interface TachiConfig { - NAME: string; - TYPE: "kamai" | "boku" | "omni"; - GAMES: Game[]; - IMPORT_TYPES: ImportTypes[]; - SIGNUPS_ENABLED: boolean; -} - let configRes; try { configRes = syncFetch(ToAPIURL("/config")).json(); @@ -71,7 +63,7 @@ try { throw new Error(`Site is (probably) down. Sorry. (${(err as Error).message})`); } -const conf: TachiConfig = configRes.body; +const conf: TachiServerCoreConfig = configRes.body; const colourConf = { background: "#131313", lightground: "#2b292b", diff --git a/common/src/types.ts b/common/src/types.ts index cde496b25..0d3dec33f 100644 --- a/common/src/types.ts +++ b/common/src/types.ts @@ -1,3 +1,6 @@ +import type { Game } from "./types/game-config"; +import type { ImportTypes } from "./types/import-types"; + /** * An alias for number, that makes part of the code self-documenting. * Note that if it were possible to enforce integer-y ness, then I would absolutely do so here @@ -12,6 +15,17 @@ export enum UserAuthLevels { ADMIN = 3, } +/** + * The config the server expects, and emits on /api/v1/config. + */ +export interface TachiServerCoreConfig { + GAMES: Array; + IMPORT_TYPES: Array; + NAME: string; + TYPE: "boku" | "kamai" | "omni"; + SIGNUPS_ENABLED: boolean; +} + export * from "./types/api"; export * from "./types/batch-manual"; export * from "./types/documents"; diff --git a/server/src/lib/setup/config.ts b/server/src/lib/setup/config.ts index bf0726a4d..2909601c8 100644 --- a/server/src/lib/setup/config.ts +++ b/server/src/lib/setup/config.ts @@ -9,7 +9,7 @@ import { FormatPrError } from "utils/prudence"; import fs from "fs"; import { URL } from "url"; import type { SendMailOptions } from "nodemailer"; -import type { Game, ImportTypes, integer } from "tachi-common"; +import type { TachiServerCoreConfig, integer } from "tachi-common"; // imports things like NODE_ENV from a local .env file if one is present. dotenv.config(); @@ -112,13 +112,7 @@ export interface TachiServerConfig { INVITE_CAP: integer; BETA_USER_BONUS: integer; }; - TACHI_CONFIG: { - NAME: string; - TYPE: "boku" | "kamai" | "omni"; - GAMES: Array; - IMPORT_TYPES: Array; - SIGNUPS_ENABLED: boolean; - }; + TACHI_CONFIG: TachiServerCoreConfig; LOGGER_CONFIG: { LOG_LEVEL: "crit" | "debug" | "error" | "info" | "severe" | "verbose" | "warn"; CONSOLE: boolean;