diff --git a/.env b/.env new file mode 100644 index 0000000..9d53095 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +DISCORD_TOKEN=MTAyODUyNDI3NDIzMjg2ODkyNg.GRkc8K.3IJk3BTDR4sQOyVExvZOUQ5lsgrbJNO97Lz1Pw \ No newline at end of file diff --git a/.gitignore b/.gitignore index cb71ff7..0e489bb 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,5 @@ npm-debug.log* yarn-debug.log* yarn-error.log* + +/.idea \ No newline at end of file diff --git a/configuration.yml b/configuration.yml new file mode 100644 index 0000000..d486c09 --- /dev/null +++ b/configuration.yml @@ -0,0 +1,5 @@ +databaseChangeLog: + - includeAll: + path: migrations + relativeToChangelogFile: true + errorIfMissingOrEmpty: true diff --git a/lib/postgresql-42.5.0.jar b/lib/postgresql-42.5.0.jar new file mode 100644 index 0000000..49b9556 Binary files /dev/null and b/lib/postgresql-42.5.0.jar differ diff --git a/lib/snakeyaml-1.23.jar b/lib/snakeyaml-1.23.jar new file mode 100644 index 0000000..71da666 Binary files /dev/null and b/lib/snakeyaml-1.23.jar differ diff --git a/liquibase.properties b/liquibase.properties new file mode 100644 index 0000000..778987e --- /dev/null +++ b/liquibase.properties @@ -0,0 +1,7 @@ +# PostgreSQL +classpath: lib/postgresql-42.5.0.jar +driver: org.postgresql.Driver +url: jdbc:postgresql://free-tier11.gcp-us-east1.cockroachlabs.cloud:26257/nomrpg-chesting?options=--cluster%3Ddeliciousreya-nom-rpg-2220&sslmode=verify-full +username: reya +changeLogFile: configuration.yml +liquibase.hub.mode=off diff --git a/migrations/.gitkeep b/migrations/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/migrations/0001-characters.sql b/migrations/0001-characters.sql new file mode 100644 index 0000000..864c723 --- /dev/null +++ b/migrations/0001-characters.sql @@ -0,0 +1,215 @@ +--liquibase formatted sql + +--changeset reya:users_table runInTransaction:false +CREATE TABLE IF NOT EXISTS users +( + id UUID NOT NULL PRIMARY KEY DEFAULT gen_random_uuid(), + discord_snowflake INT NOT NULL, + INDEX discord_users (discord_snowflake) +); +--rollback DROP TABLE IF EXISTS users; + +--changeset reya:types_table runInTransaction:false +CREATE TABLE IF NOT EXISTS types +( + id INT NOT NULL PRIMARY KEY, + name STRING NOT NULL, + color STRING NOT NULL, + display_order INT NOT NULL, + immunities INT[] NOT NULL DEFAULT '{}', + resistances INT[] NOT NULL DEFAULT '{}', + weaknesses INT[] NOT NULL DEFAULT '{}' +); +--rollback DROP TABLE IF EXISTS types; + +--changeset reya:types_values runInTransaction:true +INSERT INTO types (id, name, color, display_order) +VALUES (0, 'Basic', '', 0), + (1, 'Sassy', '', 1), + (2, 'Gentle', '', 2), + (3, 'Sexy', '', 3), + (4, 'Muscle', '', 4), + (5, 'Glam', '', 5), + (6, 'Punk', '', 6), + (7, 'Glutton', '', 7), + (8, 'Dumb', '', 8), + (9, 'Drone', '', 9), + (10, 'Spooky', '', 10), + (11, 'Lively', '', 11), + (12, 'Smart', '', 12), + (13, 'Cool', '', 13), + (14, 'Bully', '', 14), + (15, 'Mythic', '', 15), + (16, 'Toy', '', 16), + (17, 'Cute', '', 17); +--rollback DELETE FROM types WHERE id in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) + +--changeset reya:difficulties_table runInTransaction:false +CREATE TABLE IF NOT EXISTS difficulties +( + id INT NOT NULL PRIMARY KEY, + name STRING NOT NULL, + description STRING NOT NULL, + display_order INT NOT NULL, + endo_only BOOLEAN NOT NULL DEFAULT false, + regenerate_talent BOOLEAN NOT NULL DEFAULT false, + lose_proficiency_percent FLOAT NOT NULL DEFAULT 0, + lose_exp_percent FLOAT NOT NULL DEFAULT 0, + lose_money_percent FLOAT NOT NULL DEFAULT 0, + allow_reformation BOOLEAN NOT NULL DEFAULT true +); +--rollback DROP TABLE IF EXISTS difficulties; + +--changeset reya:difficulties_values runInTransaction:true +INSERT INTO difficulties +(id, name, description, display_order, endo_only, regenerate_talent, lose_proficiency_percent, lose_exp_percent, + lose_money_percent, allow_reformation) +VALUES (0, 'Endo Only', 'You can never be digested. You always come out sooner or later.', 0, true, false, 0, 0, 0, + true), + (1, 'Very Safe', + 'You''ll be completely safe. The only downsides to being digested? Inconvenience. And smug predators.', 1, + false, false, 0, 0, 0, true), + (2, 'Safe', + 'Your noggin will get rattled around, sure, and you might drop some of your cash, but it''s a small price to pay for being able to come back.', + 2, false, true, 10, 0, 10, true), + (3, 'Risky', + 'Getting digested is going to mess with your head, for sure. You''ll come back a bit weakened from the experience, and your wallet will notice. This is the recommended difficulty.', + 3, false, true, 25, 10, 25, true), + (4, 'Dangerous', + 'Digestion is something to be avoided at all costs. You''ll lose half your money, your stats will have atrophied, and you''ll lose some of your memories.', + 4, false, true, 50, 25, 50, true), + (5, 'Very Dangerous', + 'Being a meal is not just humiliating - it''s a nightmare. You''re lucky you get to hold on to anything.', 5, + false, true, 90, 50, 90, true), + (6, 'Extremely Dangerous', + 'If you get devoured and you don''t get out, you''ll lose just about everything. Be very, very careful...', 6, + false, true, 100, 100, 100, true), + (7, 'Impossible', + 'There is nothing to look forward to after digestion but an eternity on someone else''s thighs. When you''re digested, your life is over. There''s no coming back. Ever.', + 7, false, true, 100, 100, 100, false); +--rollback DELETE FROM difficulties WHERE id IN (0, 1, 2, 3, 4, 5, 6, 7); + +--changeset reya:preferences_table runInTransaction:false +CREATE TABLE IF NOT EXISTS preferences +( + id INT NOT NULL PRIMARY KEY, + name STRING NOT NULL, + description STRING NOT NULL, + display_order INT NOT NULL, + can_use_vore BOOLEAN NOT NULL, + can_receive_vore BOOLEAN NOT NULL +); +--rollback DROP TABLE IF EXISTS preferences; + +--changeset reya:preferences_values runInTransaction:true +INSERT INTO preferences (id, name, description, display_order, can_use_vore, can_receive_vore) +VALUES (0, 'Observer', 'You can neither eat nor be eaten.', 0, false, false), + (1, 'Prey Only', 'You can only be eaten, not eat.', 1, false, true), + (2, 'Pred Only', 'You can only eat, not be eaten.', 2, true, false), + (3, 'Switch', 'You can both eat and be eaten.', 3, true, true); +--rollback DELETE FROM preferences WHERE id IN (0, 1, 2, 3); + +--changeset reya:genders_table runInTransaction:false +CREATE TABLE IF NOT EXISTS genders +( + id INT NOT NULL PRIMARY KEY, + name STRING NOT NULL, + display_order INT NOT NULL, + use_plural BOOLEAN NOT NULL, + subjective STRING NOT NULL, + adjective STRING NOT NULL, + possessive STRING NOT NULL, + reflexive STRING NOT NULL, + objective STRING NOT NULL +); +--rollback DROP TABLE IF EXISTS genders; + +--changeset reya:genders_values runInTransaction:true +INSERT INTO genders (id, name, display_order, use_plural, subjective, adjective, possessive, reflexive, objective) +VALUES (0, 'Non-binary (name only)', 0, false, '@@', '@@''s', '@@''s', '@@''s self', '@@'), + (1, 'Female (she/her)', 1, false, 'she', 'her', 'hers', 'herself', 'her'), + (2, 'Non-binary (they/them)', 2, true, 'they', 'their', 'theirs', 'themself', 'them'), + (3, 'Male (he/him)', 3, false, 'he', 'his', 'his', 'himself', 'him'), + (4, 'Object (it/its)', 4, false, 'it', 'its', 'its', 'itself', 'it'), + (5, 'Herm (shi/hir)', 5, false, 'shi', 'hir', 'hirs', 'hirself', 'hir'), + (6, 'Non-binary (ae/aer)', 6, false, 'ae', 'aer', 'aers', 'aerself', 'aer'), + (7, 'Non-binary (fae/faer)', 7, false, 'fae', 'faer', 'faers', 'faerself', 'faer'), + (8, 'Non-binary (e/em)', 8, false, 'e', 'eir', 'eirs', 'emself', 'em'), + (9, 'Non-binary (ey/em)', 9, false, 'ey', 'eir', 'eirs', 'emself', 'em'), + (10, 'Non-binary (per/per)', 10, false, 'per', 'pers', 'pers', 'perself', 'per'), + (11, 'Non-binary (ve/ver)', 11, false, 've', 'vis', 'vis', 'verself', 'ver'), + (12, 'Non-binary (xe/xem)', 12, false, 'xe', 'xyr', 'xyrs', 'xemself', 'xem'), + (13, 'Non-binary (ze/hir)', 13, false, 'ze', 'hir', 'hirs', 'hirself', 'hir'), + (14, 'Non-binary (zie/hir)', 14, false, 'zie', 'hir', 'hirs', 'hirself', 'hir'), + (15, 'Non-binary (zie/zim)', 15, false, 'zie', 'zir', 'zis', 'zieself', 'zim'), + (16, 'Non-binary (sie/sie)', 16, false, 'sie', 'hir', 'hirs', 'hirself', 'sie'), + (17, 'Non-binary (te/ter)', 17, false, 'te', 'tem', 'ters', 'terself', 'ter'); +--rollback DELETE FROM genders WHERE id IN (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17); + +--changeset reya:characters_table runInTransaction:false +CREATE TABLE IF NOT EXISTS characters +( + id UUID NOT NULL PRIMARY KEY, + user_id UUID NOT NULL REFERENCES users (id) ON DELETE CASCADE, + name STRING NOT NULL, + title STRING NOT NULL, + profile STRING NOT NULL, + gender_id INT NOT NULL REFERENCES genders (id) ON DELETE RESTRICT, + difficulty_id INT NOT NULL REFERENCES difficulties (id) ON DELETE RESTRICT, + preference_id INT NOT NULL REFERENCES preferences (id) ON DELETE RESTRICT, + type1_id INT NOT NULL REFERENCES types (id) ON DELETE RESTRICT, + type2_id INT NOT NULL REFERENCES types (id) ON DELETE RESTRICT, + experience INT NOT NULL DEFAULT 0, + money INT NOT NULL DEFAULT 0, + + -- stats: base + base_confidence INT NOT NULL DEFAULT 70, + base_health INT NOT NULL DEFAULT 70, + base_stamina INT NOT NULL DEFAULT 70, + base_brawn INT NOT NULL DEFAULT 70, + base_durability INT NOT NULL DEFAULT 70, + base_intensity INT NOT NULL DEFAULT 70, + base_resilience INT NOT NULL DEFAULT 70, + base_speed INT NOT NULL DEFAULT 70, + -- stats: banked talent points + min_confidence_talent INT NOT NULL DEFAULT 0, + min_health_talent INT NOT NULL DEFAULT 0, + min_stamina_talent INT NOT NULL DEFAULT 0, + min_brawn_talent INT NOT NULL DEFAULT 0, + min_durability_talent INT NOT NULL DEFAULT 0, + min_intensity_talent INT NOT NULL DEFAULT 0, + min_resilience_talent INT NOT NULL DEFAULT 0, + min_speed_talent INT NOT NULL DEFAULT 0, + -- stats: current talent points + confidence_talent INT NOT NULL DEFAULT floor(random() * 32)::INT, --min_confidence_talent + floor(random() * (32 - min_confidence_talent)), + health_talent INT NOT NULL DEFAULT floor(random() * 32)::INT, --min_health_talent + floor(random() * (32 - min_health_talent)), + stamina_talent INT NOT NULL DEFAULT floor(random() * 32)::INT, --min_stamina_talent + floor(random() * (32 - min_stamina_talent)), + brawn_talent INT NOT NULL DEFAULT floor(random() * 32)::INT, --min_brawn_talent + floor(random() * (32 - min_brawn_talent)), + durability_talent INT NOT NULL DEFAULT floor(random() * 32)::INT, --min_durability_talent + floor(random() * (32 - min_durability_talent)), + intensity_talent INT NOT NULL DEFAULT floor(random() * 32)::INT, --min_intensity_talent + floor(random() * (32 - min_intensity_talent)), + resilience_talent INT NOT NULL DEFAULT floor(random() * 32)::INT, --min_resilience_talent + floor(random() * (32 - min_resilience_talent)), + speed_talent INT NOT NULL DEFAULT floor(random() * 32)::INT, --min_speed_talent + floor(random() * (32 - min_speed_talent)), + -- stats: current proficiency points + confidence_proficiency INT NOT NULL DEFAULT 0, + health_proficiency INT NOT NULL DEFAULT 0, + stamina_proficiency INT NOT NULL DEFAULT 0, + brawn_proficiency INT NOT NULL DEFAULT 0, + durability_proficiency INT NOT NULL DEFAULT 0, + intensity_proficiency INT NOT NULL DEFAULT 0, + resilience_proficiency INT NOT NULL DEFAULT 0, + speed_proficiency INT NOT NULL DEFAULT 0, + + FAMILY character_base (id, user_id, name, title, profile, gender_id, type1_id, type2_id, base_confidence, + base_health, + base_stamina, base_brawn, base_durability, base_intensity, base_resilience, base_speed), + FAMILY character_reformation_stats ( + min_confidence_talent, min_health_talent, min_stamina_talent, min_brawn_talent, + min_durability_talent, min_intensity_talent, min_resilience_talent, + min_speed_talent, + confidence_talent, health_talent, stamina_talent, brawn_talent, + durability_talent, intensity_talent, resilience_talent, speed_talent), + FAMILY character_live_stats (difficulty_id, preference_id, experience, money, confidence_proficiency, + health_proficiency, stamina_proficiency, brawn_proficiency, durability_proficiency, + intensity_proficiency, resilience_proficiency, speed_proficiency) +); +--rollback DROP TABLE IF EXISTS characters_table; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2b49ccd..66a127e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "discord-api-types": "^0.37.12", "discord.js": "^14.5.0", "dotenv": "^16.0.3", + "liquibase": "^4.4.0", "ts-postgres": "^1.3.0" }, "devDependencies": { @@ -2939,6 +2940,17 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/liquibase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/liquibase/-/liquibase-4.4.0.tgz", + "integrity": "sha512-oD/ZJgxpoR43V5Vt7o3r9ftYl16PyFco5l1EpKI4VKDQLtm1acHsyqxjA96S6c+rP51PafC4xug1Z6IJLyyAXA==", + "bin": { + "node-liquibase": "dist/cli.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -6421,6 +6433,11 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "liquibase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/liquibase/-/liquibase-4.4.0.tgz", + "integrity": "sha512-oD/ZJgxpoR43V5Vt7o3r9ftYl16PyFco5l1EpKI4VKDQLtm1acHsyqxjA96S6c+rP51PafC4xug1Z6IJLyyAXA==" + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", diff --git a/package.json b/package.json index cdce01a..36cecf1 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "discord-api-types": "^0.37.12", "discord.js": "^14.5.0", "dotenv": "^16.0.3", + "liquibase": "^4.4.0", "ts-postgres": "^1.3.0" }, "devDependencies": { diff --git a/src/main.ts b/src/main.ts index c9fd838..c546995 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,11 @@ -import {ApplicationCommandDataResolvable, ApplicationCommandOptionType, ApplicationCommandType} from 'discord.js' +import { + ApplicationCommandDataResolvable, + ApplicationCommandOptionType, + ApplicationCommandType, + Client, + GatewayIntentBits +} from 'discord.js' +import {config} from 'dotenv' const commands: ApplicationCommandDataResolvable[] = [ { @@ -23,7 +30,7 @@ const commands: ApplicationCommandDataResolvable[] = [ { name: "select", type: ApplicationCommandOptionType.Subcommand, - description: "Selects a character for use with other commands used in this server. Activates them on the current server.", + description: "Selects (and activates, if necessary) a character for use with other commands used in this server.", options: [ { name: "character", @@ -68,7 +75,7 @@ const commands: ApplicationCommandDataResolvable[] = [ { name: "character", type: ApplicationCommandOptionType.String, - description: "An existing character of yours to edit. Omit to see a list.", + description: "An existing character of yours to edit. Omit to edit the current character.", autocomplete: true, required: false, }, @@ -95,7 +102,7 @@ const commands: ApplicationCommandDataResolvable[] = [ { name: "character", type: ApplicationCommandOptionType.String, - description: "An existing character of yours to display in the current channel. Omit to display the current character.", + description: "An existing character of yours to display in this channel. Omit to display the current character.", autocomplete: true, required: false, }, @@ -110,7 +117,7 @@ const commands: ApplicationCommandDataResolvable[] = [ { name: "archive", type: ApplicationCommandOptionType.Subcommand, - description: "Removes a character from all servers and hides it from the default list view. Note that characters currently in battle cannot be archived.", + description: "Removes a character from all servers and hides it from the default list view.", options: [ { name: "character", @@ -124,7 +131,7 @@ const commands: ApplicationCommandDataResolvable[] = [ { name: "unarchive", type: ApplicationCommandOptionType.Subcommand, - description: "Unarchives a character. If used in a server, the character will automatically be added to that server.", + description: "Unarchives a character.", options: [ { name: "character", @@ -137,6 +144,23 @@ const commands: ApplicationCommandDataResolvable[] = [ }, ], }, + { + name: "playstyle", + type: ApplicationCommandType.ChatInput, + description: "Updates your play style.", + options: [ + { + name: "difficulty", + type: ApplicationCommandOptionType.Subcommand, + description: "Alters or displays the reformation difficulty of your currently selected character." + }, + { + name: "preference", + type: ApplicationCommandOptionType.Subcommand, + description: "Alters or displays the pred/prey preference of your currently selected character." + } + ] + }, { name: "team", type: ApplicationCommandType.ChatInput, @@ -145,7 +169,7 @@ const commands: ApplicationCommandDataResolvable[] = [ { name: "join", type: ApplicationCommandOptionType.Subcommand, - description: "Leaves the current team, if any, and requests to join the same team as another player. Joins the battle if not already participating." + description: "Leaves the current team, if any, and requests to join the same team (and battle) as another player." }, { name: "leave", @@ -154,21 +178,24 @@ const commands: ApplicationCommandDataResolvable[] = [ }, ], }, - { - name: "challenge", - type: ApplicationCommandType.ChatInput, - description: "Challenges another character to a battle.", - options: [ - { - name: "", - } - ] - }, { name: "battle", type: ApplicationCommandType.ChatInput, description: "Takes actions in battle.", options: [ + { + name: "challenge", + type: ApplicationCommandOptionType.Subcommand, + description: "Challenges another character to a battle.", + options: [ + { + name: "target", + type: ApplicationCommandOptionType.String, + description: "The character you want to challenge.", + autocomplete: true, + } + ] + }, { name: "menu", type: ApplicationCommandOptionType.Subcommand, @@ -243,7 +270,7 @@ const commands: ApplicationCommandDataResolvable[] = [ { name: "surrender", type: ApplicationCommandOptionType.Subcommand, - description: "Lets your opponent do as they will with you by your Confidence or Health to 0." + description: "Lets your opponent do as they will with you by reducing your Confidence or Health to 0." }, { name: "prey", @@ -269,49 +296,201 @@ const commands: ApplicationCommandDataResolvable[] = [ type: ApplicationCommandType.ChatInput, description: "Safety commands for protecting consent and user data.", options: [ - { - name: "decline", - type: ApplicationCommandOptionType.Subcommand, - description: "Declines a challenge for reasons of consent.", - }, { name: "exit", type: ApplicationCommandOptionType.SubcommandGroup, - description: "Exits battle(s) and reverts its/their effects on you for reasons of consent. To flee, use /battle escape.", + description: "Exits battle(s) and reverts its/their effects on you. To flee in-character, use /battle escape.", }, { name: "block", type: ApplicationCommandOptionType.SubcommandGroup, - description: "Prevents a user from challenging you.", + description: "Manages your block list.", + options: [ + { + name: "add", + type: ApplicationCommandOptionType.Subcommand, + description: "Prevents a user or character from challenging you or joining battles you're in.", + options: [ + { + name: "user", + type: ApplicationCommandOptionType.User, + description: "The user to block from challenging you or joining battles you're in.", + required: false + }, + { + name: "character", + type: ApplicationCommandOptionType.String, + description: "The character to block from challenging you or joining battles you're in.", + required: false, + autocomplete: true + }, + ], + }, + { + name: "remove", + type: ApplicationCommandOptionType.Subcommand, + description: "Allows a user or character to challenge you and join battles you're in once more.", + options: [ + { + name: "user", + type: ApplicationCommandOptionType.User, + description: "The user to allow to challenge you and join battles you're in once more.", + required: false + }, + { + name: "character", + type: ApplicationCommandOptionType.String, + description: "The character to allow to challenge you and join battles you're in once more.", + required: false, + autocomplete: true + }, + ], + }, + { + name: "list", + type: ApplicationCommandOptionType.Subcommand, + description: "Displays your current block list." + }, + ], }, { name: "kick", type: ApplicationCommandOptionType.SubcommandGroup, - description: "Kicks a user from a battle and prevents them from rejoining for reasons of consent.", + description: "Manages the list of users kicked from the current battle.", + options: [ + { + name: "add", + type: ApplicationCommandOptionType.Subcommand, + description: "Removes a user or character from the current battle and prevents them from rejoining.", + options: [ + { + name: "user", + type: ApplicationCommandOptionType.User, + description: "The user to remove from the current battle and prevent from rejoining.", + required: false + }, + { + name: "character", + type: ApplicationCommandOptionType.String, + description: "The character to remove from the current battle and prevent from rejoining.", + required: false, + autocomplete: true + }, + ], + }, + { + name: "remove", + type: ApplicationCommandOptionType.Subcommand, + description: "Allows a user or character to rejoin the current battle.", + options: [ + { + name: "user", + type: ApplicationCommandOptionType.User, + description: "The user to allow to rejoin the current battle.", + required: false + }, + { + name: "character", + type: ApplicationCommandOptionType.String, + description: "The user to allow to rejoin the current battle.", + required: false, + autocomplete: true + }, + ], + }, + { + name: "list", + type: ApplicationCommandOptionType.Subcommand, + description: "Displays the list of users forbidden from rejoining the current battle." + }, + ], }, { name: "ban", type: ApplicationCommandOptionType.SubcommandGroup, - description: "Prevents a user from participating in battles in the current server, and kicks them from any they're in.", + description: "Manages the ban list of the current server.", + options: [ + { + name: "add", + type: ApplicationCommandOptionType.Subcommand, + description: "Bans a user from participating in battles in the current server and kicks them from any they're in.", + options: [ + { + name: "user", + type: ApplicationCommandOptionType.User, + description: "The user to ban from participating in battles in the current server.", + required: true + }, + ], + }, + { + name: "remove", + type: ApplicationCommandOptionType.Subcommand, + description: "Allows a user to resume participating in battles in the current server.", + options: [ + { + name: "user", + type: ApplicationCommandOptionType.User, + description: "The user to allow to participate in battles in the current server once more.", + required: true + }, + ], + }, + { + name: "list", + type: ApplicationCommandOptionType.Subcommand, + description: "Displays this server's current ban list." + }, + ], }, { name: "delete", type: ApplicationCommandOptionType.Subcommand, - description: "PERMANENTLY deletes a character, aborting any battles they were part of. To hide characters without deleting them, use /character archive.", + description: "PERMANENTLY deletes a character, exiting any battles they were part of. See also /character archive.", }, { name: "wipe", type: ApplicationCommandOptionType.Subcommand, - description: "PERMANENTLY deletes all data about you in the system, aborting any battles you were part of and erasing you from the system's knowledge.", + description: "PERMANENTLY deletes ALL data about you in the system, erasing you from the system's knowledge.", }, ], } ] -function main() { - console.log("we're up and runnin'") +async function main() { + config() + const c = new Client({ + intents: [], + }) + c.on('ready', async () => { + const app = c.application + if (!c.application) { + console.log("Bot is ready, but no application") + } else { + try { + await c.application.commands.set(commands) + console.log("Commands established") + } catch (ex) { + console.log("Bot is ready, but setting commands failed: " + ex) + } + } + }) + c.on('error', async (ex) => { + console.log("Connection error: " + ex) + }) + c.on('interactionCreate', async (ev) => { + if (ev.isRepliable()) { + try { + await ev.reply("Huuuuuuuh? ... I don't know what to do with that yet.") + console.log("answered an interaction") + } catch (ex) { + console.log("failed answering an interaction: " + ex) + } + } else { + console.log("got an interaction but can't reply to it") + } + }) + await c.login(process.env.DISCORD_TOKEN || "") } -export {} - -main() +main().catch((ex) => {console.log("main thread failed: " + ex)}) \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 1b463c6..43e0999 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,13 +1,13 @@ { "compilerOptions": { - "target": "es5", + "target": "esnext", "lib": [ "esnext" ], "allowJs": true, "skipLibCheck": false, "esModuleInterop": true, - "allowSyntheticDefaultImports": false, + "allowSyntheticDefaultImports": true, "strict": true, "strictNullChecks": true, "forceConsistentCasingInFileNames": true, @@ -15,7 +15,7 @@ "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, - "isolatedModules": true, + "isolatedModules": false, "outDir": "build" }, "include": [