Skip to content

Commit

Permalink
Complete race bot logic.
Browse files Browse the repository at this point in the history
  • Loading branch information
roncli committed Jan 19, 2024
1 parent 1cbb627 commit edf48be
Show file tree
Hide file tree
Showing 24 changed files with 1,885 additions and 13 deletions.
47 changes: 47 additions & 0 deletions node/src/discord/commands/close.js
@@ -0,0 +1,47 @@
/**
* @typedef {import("discord.js").GuildMember} DiscordJs.GuildMember
* @typedef {import("discord.js").TextChannel} DiscordJs.TextChannel
*/

const Discord = require(".."),
Race = require("../../models/race");

// ### ## ### #
// # # # # # #
// # # ### ### ### # ## # ## #
// # # # # # # # # # # # # ##
// # # # # ### ##### # # # # # #
// # # # # # # # # # # # # # ##
// ### ### ### #### ### ### # # ## #
/**
* A class that handles the close command.
*/
class CloseCmd {
// # # ##
// # # #
// ### ### ### ### # ##
// # # # # # # # # # # ##
// # # # ## # # # # # ##
// # # # # # # ### ### ##
/**
* Handles the command.
* @param {DiscordJs.GuildMember} member The member using the command.
* @param {DiscordJs.TextChannel} channel The channel the command is being used in.
* @returns {Promise} A promise that returns when the command is done executing.
*/
static async handle(member, channel) {
if (!member.roles.cache.has(Discord.staffRole.id)) {
return;
}

const race = Race.getByChannel(channel);

if (race) {
await race.close(member);
} else if (channel.parent && channel.parent.id === Discord.raceCategory.id) {
await channel.delete(`The stale race room ${channel.name} was closed by ${member}.`);
}
}
}

module.exports = CloseCmd;
1 change: 1 addition & 0 deletions node/src/discord/commands/d.js
@@ -0,0 +1 @@
module.exports = require("./done");
42 changes: 42 additions & 0 deletions node/src/discord/commands/done.js
@@ -0,0 +1,42 @@
/**
* @typedef {import("discord.js").GuildMember} DiscordJs.GuildMember
* @typedef {import("discord.js").TextChannel} DiscordJs.TextChannel
*/

const Race = require("../../models/race");

// #### ### #
// # # # # #
// # # ### # ## ### # ## # ## #
// # # # # ## # # # # # # # # ##
// # # # # # # ##### # # # # # #
// # # # # # # # # # # # # # ##
// #### ### # # ### ### # # ## #
/**
* A class that handles the done command.
*/
class DoneCmd {
// # # ##
// # # #
// ### ### ### ### # ##
// # # # # # # # # # # ##
// # # # ## # # # # # ##
// # # # # # # ### ### ##
/**
* Handles the command.
* @param {DiscordJs.GuildMember} member The member using the command.
* @param {DiscordJs.TextChannel} channel The channel the command is being used in.
* @returns {Promise} A promise that returns when the command is done executing.
*/
static async handle(member, channel) {
const race = Race.getByChannel(channel);

if (!race) {
return;
}

await race.done(member);
}
}

module.exports = DoneCmd;
1 change: 1 addition & 0 deletions node/src/discord/commands/e.js
@@ -0,0 +1 @@
module.exports = require("./enter");
42 changes: 42 additions & 0 deletions node/src/discord/commands/enter.js
@@ -0,0 +1,42 @@
/**
* @typedef {import("discord.js").GuildMember} DiscordJs.GuildMember
* @typedef {import("discord.js").TextChannel} DiscordJs.TextChannel
*/

const Race = require("../../models/race");

// ##### # ### #
// # # # # #
// # # ## #### ### # ## # ## # ## #
// #### ## # # # # ## # # # # # # ##
// # # # # ##### # # # # # # #
// # # # # # # # # # # # # # ##
// ##### # # ## ### # ### # # ## #
/**
* A class that handles the enter command.
*/
class EnterCmd {
// # # ##
// # # #
// ### ### ### ### # ##
// # # # # # # # # # # ##
// # # # ## # # # # # ##
// # # # # # # ### ### ##
/**
* Handles the command.
* @param {DiscordJs.GuildMember} member The member using the command.
* @param {DiscordJs.TextChannel} channel The channel the command is being used in.
* @returns {Promise} A promise that returns when the command is done executing.
*/
static async handle(member, channel) {
const race = Race.getByChannel(channel);

if (!race) {
return;
}

await race.enter(member);
}
}

module.exports = EnterCmd;
1 change: 1 addition & 0 deletions node/src/discord/commands/f.js
@@ -0,0 +1 @@
module.exports = require("./forfeit");
42 changes: 42 additions & 0 deletions node/src/discord/commands/forfeit.js
@@ -0,0 +1,42 @@
/**
* @typedef {import("discord.js").GuildMember} DiscordJs.GuildMember
* @typedef {import("discord.js").TextChannel} DiscordJs.TextChannel
*/

const Race = require("../../models/race");

// ##### ## # # ### #
// # # # # # # #
// # ### # ## # ### ## #### # ## # ## #
// #### # # ## # #### # # # # # # # # # ##
// # # # # # ##### # # # # # # # #
// # # # # # # # # # # # # # # # ##
// # ### # # ### ### ## ### # # ## #
/**
* A class that handles the forfeit command.
*/
class ForfeitCmd {
// # # ##
// # # #
// ### ### ### ### # ##
// # # # # # # # # # # ##
// # # # ## # # # # # ##
// # # # # # # ### ### ##
/**
* Handles the command.
* @param {DiscordJs.GuildMember} member The member using the command.
* @param {DiscordJs.TextChannel} channel The channel the command is being used in.
* @returns {Promise} A promise that returns when the command is done executing.
*/
static async handle(member, channel) {
const race = Race.getByChannel(channel);

if (!race) {
return;
}

await race.forfeit(member);
}
}

module.exports = ForfeitCmd;
73 changes: 73 additions & 0 deletions node/src/discord/commands/help.js
@@ -0,0 +1,73 @@
/**
* @typedef {import("discord.js").GuildMember} DiscordJs.GuildMember
* @typedef {import("discord.js").TextChannel} DiscordJs.TextChannel
*/

const Discord = require(".."),
pjson = require("../../../package.json");

// # # ## ### #
// # # # # # #
// # # ### # # ## # ## # ## #
// ##### # # # ## # # # # # # ##
// # # ##### # ## # # # # # # #
// # # # # # ## # # # # # # ##
// # # ### ### # ### # # ## #
// #
// #
/**
* A class that handles the help command.
*/
class HelpCmd {
// # # ##
// # # #
// ### ### ### ### # ##
// # # # # # # # # # # ##
// # # # ## # # # # # ##
// # # # # # # ### ### ##
/**
* Handles the command.
* @param {DiscordJs.GuildMember} member The member using the command.
* @param {DiscordJs.TextChannel} channel The channel the command is being used in.
* @returns {Promise} A promise that returns when the command is done executing.
*/
static async handle(member, channel) {
await Discord.richQueue(
Discord.embedBuilder({
title: `SPRINT Racebot v${pjson.version}`,
description: "A Discord bot for racing Star of Providence.",
fields: [
{
name: "General Commands",
value: "`.help` - This help text.\n`.race` - Start a new race.",
inline: true
},
{
name: "Race Room Commands - Before the Race",
value: "`.enter`/`.e` - Enter the race.\n`.ready`/`.r` - Indicate that you are ready to start the race.\n`.unready`/`.u` - Indicate you are not ready and need more time before the race starts.\n`.withdraw`/`.w` - Withdraw from the race."
},
{
name: "Race Room Commands - During the Race",
value: "`.done`/`.d` - Indicate that you have finished the race.\n`.forfeit`/`.f` - Forfeit the race.\n`.notdone`/`.n` - If you did `.done` or `.forfeit`, this undoes that, re-entering you into the race.\n`.time` - Get the current elapsed time of the race."
},
{
name: "Race Room Commands - After the Race",
value: "`.notdone`/`.n` - If you did `.done` or `.forfeit`, this undoes that, continuing the race and re-entering you into it.\n`.rematch` - Starts a new race in the same race channel."
},
{
name: "Staff Commands",
value: "`.close` - Immediately close the race room you are in.\n`.kick <@user>` - Kick a player out of the race in the room you are in. You must mention the player. They can rejoin, if the race is still accepting entries.",
inline: true
},
{
name: "Bugs?",
value: "Please report bugs on GitHub, https://github.com/roncli/sprint-racebot"
}
]
}),
channel
);
}
}

module.exports = HelpCmd;
60 changes: 60 additions & 0 deletions node/src/discord/commands/kick.js
@@ -0,0 +1,60 @@
/**
* @typedef {import("discord.js").GuildMember} DiscordJs.GuildMember
* @typedef {import("discord.js").TextChannel} DiscordJs.TextChannel
*/

const Discord = require(".."),
Race = require("../../models/race"),

idParse = /^<@!?(?<id>\d+)>$/;

// # # # # ### #
// # # # # # #
// # # ## ### # # # ## # ## #
// ## # # # # # # # # # # ##
// # # # # ### # # # # # #
// # # # # # # # # # # # # # ##
// # # ### ### # # ### # # ## #
/**
* A class that handles the kick command.
*/
class KickCmd {
// # # ##
// # # #
// ### ### ### ### # ##
// # # # # # # # # # # ##
// # # # ## # # # # # ##
// # # # # # # ### ### ##
/**
* Handles the command.
* @param {DiscordJs.GuildMember} member The member using the command.
* @param {DiscordJs.TextChannel} channel The channel the command is being used in.
* @param {string} param The command parameters.
* @returns {Promise} A promise that returns when the command is done executing.
*/
static async handle(member, channel, param) {
if (!member.roles.cache.has(Discord.staffRole.id)) {
return;
}

const race = Race.getByChannel(channel);

if (!race) {
return;
}

if (!idParse.test(param)) {
return;
}

const kickedMember = Discord.findGuildMemberById(idParse.exec(param).groups.id);

if (!kickedMember) {
return;
}

await race.kick(member, kickedMember);
}
}

module.exports = KickCmd;
1 change: 1 addition & 0 deletions node/src/discord/commands/n.js
@@ -0,0 +1 @@
module.exports = require("./notdone");
42 changes: 42 additions & 0 deletions node/src/discord/commands/notdone.js
@@ -0,0 +1,42 @@
/**
* @typedef {import("discord.js").GuildMember} DiscordJs.GuildMember
* @typedef {import("discord.js").TextChannel} DiscordJs.TextChannel
*/

const Race = require("../../models/race");

// # # # #### ### #
// # # # # # # # #
// ## # ### #### # # ### # ## ### # ## # ## #
// # # # # # # # # # # ## # # # # # # # # ##
// # ## # # # # # # # # # ##### # # # # # #
// # # # # # # # # # # # # # # # # # # # ##
// # # ### ## #### ### # # ### ### # # ## #
/**
* A class that handles the notdone command.
*/
class NotDoneCmd {
// # # ##
// # # #
// ### ### ### ### # ##
// # # # # # # # # # # ##
// # # # ## # # # # # ##
// # # # # # # ### ### ##
/**
* Handles the command.
* @param {DiscordJs.GuildMember} member The member using the command.
* @param {DiscordJs.TextChannel} channel The channel the command is being used in.
* @returns {Promise} A promise that returns when the command is done executing.
*/
static async handle(member, channel) {
const race = Race.getByChannel(channel);

if (!race) {
return;
}

await race.notdone(member);
}
}

module.exports = NotDoneCmd;
1 change: 1 addition & 0 deletions node/src/discord/commands/r.js
@@ -0,0 +1 @@
module.exports = require("./ready");

0 comments on commit edf48be

Please sign in to comment.