user registration, bal, change_bal, transfer

This commit is contained in:
stjet
2024-07-25 05:25:40 +00:00
parent f8780249ce
commit 9226debee2
14 changed files with 328 additions and 19 deletions

35
commands/bal.ts Normal file
View File

@@ -0,0 +1,35 @@
import type { ChatInputCommandInteraction } from "discord.js";
import { EmbedBuilder } from "discord.js";
import type { CommandData } from "./index";
import type { User } from "../db";
import config from "../config.json";
import { get_user } from "../db";
import { BotError } from "./error";
async function run(interaction: ChatInputCommandInteraction, user: User) {
const options = interaction.options;
const target = (await options.get("target"))?.user;
let embeds = [];
let bal_embed = new EmbedBuilder();
let bal_target = target ?? interaction.user;
let bal_user = target ? await get_user(target.id) : user;
if (!bal_user) throw new BotError("Target is not registered"); //must be target
bal_embed.setTitle(`${bal_target.tag}'s Balance`);
bal_embed.setDescription(`${bal_user.balance} ${ bal_user.balance === 1 ? config.currency : config.currency_plural }`);
embeds.push(bal_embed);
return await interaction.editReply({ embeds });
}
const data: CommandData = {
name: "bal",
description: "Show you or someone else's balance",
registered_only: true,
ephemeral: false,
admin_only: false,
run,
};
export default data;

34
commands/change_bal.ts Normal file
View File

@@ -0,0 +1,34 @@
import type { ChatInputCommandInteraction } from "discord.js";
import type { CommandData } from "./index";
import type { User } from "../db";
import { get_user, add_balance, sub_balance } from "../db";
import { BotError } from "./error";
async function run(interaction: ChatInputCommandInteraction, _user: User) {
const options = interaction.options;
const target_id: string = (await options.get("target")).user.id;
const amount: number = (await options.get("amount")).value as number;
const negative_allowed: boolean = ((await options.get("negative_allowed"))?.value ?? false) as boolean;
let change_user = await get_user(target_id);
if (!change_user) throw new BotError("Target is not registered");
if (amount >= 0) {
await add_balance(target_id, amount);
} else {
const success = await sub_balance(target_id, -amount, negative_allowed);
if (!success) throw new BotError("Failed because would make target balance negative, so `negative_allowed` must be true to do this");
}
return await interaction.editReply(`Changed <@${target_id}> balance by ${amount}`);
}
const data: CommandData = {
name: "change_bal",
description: "Change a user's balance",
registered_only: true,
ephemeral: false,
admin_only: true,
run,
};
export default data;

View File

@@ -1,28 +1,31 @@
import type { ChatInputCommandInteraction, GuildMember } from "discord.js";
import { EmbedBuilder } from "discord.js";
import type { ChatInputCommandInteraction } from "discord.js";
import type { User } from "../db";
import { get_user } from "../db";
import { BotError } from "./error";
import config from "../config.json";
import say from "./say";
import roll from "./roll";
import register_user from "./register_user";
import bal from "./bal";
import change_bal from "./change_bal";
import transfer from "./transfer";
export interface CommandData {
name: string;
description: string;
registered_only: boolean; //also means interaction will get deferReply()ed
ephemeral: boolean;
admin_only: boolean;
run: (interaction: ChatInputCommandInteraction) => Promise<any>;
//
run: (interaction: ChatInputCommandInteraction, user?: User) => Promise<any>;
};
const commands: CommandData[] = [say, roll];
const commands: CommandData[] = [say, roll, register_user, bal, change_bal, transfer];
//todo: look from config. also, have a config
function is_admin(interaction: ChatInputCommandInteraction): boolean {
//
//placeholder
return true;
return (interaction.member as GuildMember).roles.cache.some((r) => r.id === config.admin_role);
}
export default async function run(interaction: ChatInputCommandInteraction) {
@@ -59,7 +62,15 @@ export default async function run(interaction: ChatInputCommandInteraction) {
try {
//admin stuff should be ideally handled by register.ts, but this is a fallback
if (found.admin_only && !is_admin(interaction)) throw new BotError("Admin permission needed to run that command");
if (found.registered_only) {
await interaction.deferReply();
const user = await get_user(interaction.user.id);
if (!user) throw new BotError("You must be registered by an admin to use this command");
await found.run(interaction, user);
return;
}
await found.run(interaction);
return;
} catch (e) {
if (e instanceof BotError) {
//send error message to that channel

26
commands/register_user.ts Normal file
View File

@@ -0,0 +1,26 @@
import type { ChatInputCommandInteraction } from "discord.js";
import type { CommandData } from "./index";
import { get_user, add_new_user } from "../db";
import { BotError } from "./error";
async function run(interaction: ChatInputCommandInteraction) {
await interaction.deferReply();
const options = interaction.options;
const target_id = (await options.get("target")).user.id;
if (await get_user(target_id)) throw new BotError("Target is already registered");
await add_new_user(target_id);
return await interaction.editReply({ content: `Registered <@${target_id}>`, allowedMentions: { users: [] } });
}
const data: CommandData = {
name: "register_user",
description: "Register a user so they can participate in the bot economy",
registered_only: false,
ephemeral: false,
admin_only: true,
run,
};
export default data;

View File

@@ -29,10 +29,10 @@ async function run(interaction: ChatInputCommandInteraction) {
const data: CommandData = {
name: "roll",
description: "Roll dice",
registered_only: false,
ephemeral: false,
admin_only: false,
run,
//
};
export default data;

View File

@@ -25,10 +25,10 @@ async function run(interaction: ChatInputCommandInteraction) {
const data: CommandData = {
name: "say",
description: "Have the bot say something in a channel",
registered_only: false,
ephemeral: true,
admin_only: true,
run,
//
};
export default data;

34
commands/transfer.ts Normal file
View File

@@ -0,0 +1,34 @@
import type { ChatInputCommandInteraction } from "discord.js";
import type { CommandData } from "./index";
import type { User } from "../db";
import config from "../config.json";
import { get_user, add_balance, sub_balance } from "../db";
import { BotError } from "./error";
async function run(interaction: ChatInputCommandInteraction, user: User) {
const options = interaction.options;
const target_id: string = (await options.get("target")).user.id;
const amount: number = (await options.get("amount")).value as number;
if (amount <= 0) throw new BotError("Transfer account cannot be zero or negative");
let trans_user = await get_user(target_id);
if (!trans_user) throw new BotError("Target is not registered");
//no checks, baby! well, let db.ts handle it
const enough_balance = await sub_balance(user.user, amount);
if (!enough_balance) throw new BotError(`You do not have enough ${config.currency_plural} to transfer that amount`);
await add_balance(target_id, amount);
return await interaction.editReply(`<@${user.user}> transferred ${amount} ${ amount === 1 ? config.currency : config.currency_plural } to <@${target_id}>`);
}
const data: CommandData = {
name: "transfer",
description: "Send currency to another user",
registered_only: true,
ephemeral: false,
admin_only: false,
run,
};
export default data;