mirror of
https://github.com/nx-bat/pet-the-pond.git
synced 2026-09-22 10:29:11 -04:00
implement db into code where needed instead.
This commit is contained in:
@@ -0,0 +1,82 @@
|
|||||||
|
import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from "athena-prime";
|
||||||
|
import database from "../../database";
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
@SlashCommand(
|
||||||
|
new CommandBuilder('points', "Adjust a user's points.")
|
||||||
|
.setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall)
|
||||||
|
.setContexts(Constants.InteractionContextType.Guild)
|
||||||
|
.setCommandType(Constants.ApplicationCommandType.ChatInput)
|
||||||
|
.setMemberPermission(Constants.PermissionFlagsBits.ManageGuild)
|
||||||
|
|
||||||
|
.addSubcommand('give', 'Give points to a user.', builder => {
|
||||||
|
builder.addUserOption('target', 'The user to modify.', true);
|
||||||
|
builder.addNumberOption({ name: 'points', description: 'The points to give.', required: true, min_value: 1 })
|
||||||
|
})
|
||||||
|
.addSubcommand('take', 'Take points from a user.', builder => {
|
||||||
|
builder.addUserOption('target', 'The user to modify.', true);
|
||||||
|
builder.addNumberOption({ name: 'points', description: 'The points to take.', required: true, min_value: 1 })
|
||||||
|
})
|
||||||
|
.addSubcommand('set', 'Set the points of a user.', builder => {
|
||||||
|
builder.addUserOption('target', 'The user to modify.', true);
|
||||||
|
builder.addNumberOption({ name: 'points', description: 'The new points value.', required: true })
|
||||||
|
})
|
||||||
|
)
|
||||||
|
class RankCommand extends Command<CommandClient> {
|
||||||
|
users = [
|
||||||
|
'1363132678022631428', // Nix.
|
||||||
|
'454653142500507649', // Ann.
|
||||||
|
'147433323503943680' // Pond.
|
||||||
|
];
|
||||||
|
|
||||||
|
async handleCommand(context: CommandClient<any, any>, interaction: CommandInteraction) {
|
||||||
|
if (!interaction.inGuild()) return;
|
||||||
|
|
||||||
|
const target = interaction.getRequiredUser('target');
|
||||||
|
const points = interaction.getRequiredNumber('points');
|
||||||
|
|
||||||
|
switch (interaction.subcommand) {
|
||||||
|
case 'give':
|
||||||
|
await database`
|
||||||
|
INSERT INTO points AS p (user_id, guild_id, points)
|
||||||
|
VALUES (${target.id}, ${interaction.guild.id}, ${points})
|
||||||
|
ON CONFLICT (user_id, guild_id)
|
||||||
|
DO UPDATE SET points = p.points + ${points}
|
||||||
|
`;
|
||||||
|
|
||||||
|
return await interaction.createMessage({
|
||||||
|
content: `Done! *${target.username}* has been given **${points}** points.`,
|
||||||
|
flags: Constants.MessageFlags.Ephemeral
|
||||||
|
});
|
||||||
|
|
||||||
|
case 'take':
|
||||||
|
await database`
|
||||||
|
INSERT INTO points AS p (user_id, guild_id, points)
|
||||||
|
VALUES ${target.id}, ${interaction.guild.id}, 0)
|
||||||
|
ON CONFLICT (user_id, guild_id)
|
||||||
|
DO UPDATE SET points = GREATEST(p.points - ${points}, 0)
|
||||||
|
`;
|
||||||
|
|
||||||
|
return await interaction.createMessage({
|
||||||
|
content: `Done! *${target.username}* has lost **${points}** points.`,
|
||||||
|
flags: Constants.MessageFlags.Ephemeral
|
||||||
|
});
|
||||||
|
|
||||||
|
case 'set':
|
||||||
|
await database`
|
||||||
|
INSERT INTO points (user_id, guild_id, points)
|
||||||
|
VALUES (${target.id}, ${interaction.guild.id}, ${points})
|
||||||
|
ON CONFLICT (user_id, guild_id)
|
||||||
|
DO UPDATE SET points = ${points}
|
||||||
|
`;
|
||||||
|
|
||||||
|
return await interaction.createMessage({
|
||||||
|
content: `Done! *${target.username}*'s points has been set to **${points}**.`,
|
||||||
|
flags: Constants.MessageFlags.Ephemeral
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new RankCommand('rank');
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from "athena-prime";
|
||||||
|
import database from "../../database";
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
@SlashCommand(
|
||||||
|
new CommandBuilder('wipe', 'Wipes all points for the guild or specific user. THIS DOES NOT ASK FOR CONFIRMATION!')
|
||||||
|
.setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall)
|
||||||
|
.setContexts(Constants.InteractionContextType.Guild)
|
||||||
|
.setCommandType(Constants.ApplicationCommandType.ChatInput)
|
||||||
|
.setMemberPermission(Constants.PermissionFlagsBits.ManageGuild)
|
||||||
|
.addUserOption('target', "Optional. The user to wipe.", false)
|
||||||
|
)
|
||||||
|
class RankCommand extends Command<CommandClient> {
|
||||||
|
users = [
|
||||||
|
'1363132678022631428', // Nix.
|
||||||
|
'454653142500507649', // Ann.
|
||||||
|
'147433323503943680' // Pond.
|
||||||
|
];
|
||||||
|
|
||||||
|
async handleCommand(context: CommandClient<any, any>, interaction: CommandInteraction) {
|
||||||
|
if (!interaction.inGuild()) return;
|
||||||
|
|
||||||
|
const target = interaction.getUser('target');
|
||||||
|
|
||||||
|
if (!target) {
|
||||||
|
await database` UPDATE points SET points = 0 WHERE guild_id = ${interaction.guild.id}`;
|
||||||
|
|
||||||
|
return await interaction.createMessage({
|
||||||
|
content: 'Done! All points for this guild have been cleared.',
|
||||||
|
flags: Constants.MessageFlags.Ephemeral
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await database` UPDATE points SET points = 0 WHERE user_id = ${target.id} AND guild_id = ${interaction.guild.id} `;
|
||||||
|
|
||||||
|
return await interaction.createMessage({
|
||||||
|
content: `Done! *${target.username}*'s points have been wiped.`,
|
||||||
|
flags: Constants.MessageFlags.Ephemeral
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new RankCommand('rank');
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
|
import points from './admin/points';
|
||||||
|
import wipe from './admin/wipe';
|
||||||
import leaderboard from './leaderboard';
|
import leaderboard from './leaderboard';
|
||||||
import rank from './rank';
|
import rank from './rank';
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
|
||||||
export default [leaderboard, rank];
|
export default [points, wipe, leaderboard, rank];
|
||||||
|
|||||||
@@ -3,6 +3,19 @@ import database from '../database';
|
|||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
|
||||||
|
async function getLeaderboard(guild_id: string, limit: number = 10): Promise<{ user_id: string; points: number }[]> {
|
||||||
|
return await database`
|
||||||
|
SELECT user_id, points
|
||||||
|
FROM points
|
||||||
|
WHERE guild_id = ${guild_id}
|
||||||
|
AND points > 0
|
||||||
|
ORDER BY points DESC, user_id ASC
|
||||||
|
LIMIT ${limit}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
@SlashCommand(
|
@SlashCommand(
|
||||||
new CommandBuilder('leaderboard', 'Get the petting leaderboard.')
|
new CommandBuilder('leaderboard', 'Get the petting leaderboard.')
|
||||||
.setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall)
|
.setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall)
|
||||||
@@ -14,7 +27,7 @@ class LeaderboardCommand extends Command<CommandClient> {
|
|||||||
if (!interaction.inGuild()) return;
|
if (!interaction.inGuild()) return;
|
||||||
await interaction.defer();
|
await interaction.defer();
|
||||||
|
|
||||||
const data = await database.leaderboard.getLeaderboard(interaction.guild.id);
|
const data = await getLeaderboard(interaction.guild.id);
|
||||||
const description = data.length
|
const description = data.length
|
||||||
? data
|
? data
|
||||||
.map((entry, index) => `**${index + 1}.** <@${entry.user_id}> — **${entry.points}** points!`)
|
.map((entry, index) => `**${index + 1}.** <@${entry.user_id}> — **${entry.points}** points!`)
|
||||||
@@ -39,4 +52,6 @@ class LeaderboardCommand extends Command<CommandClient> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
export default new LeaderboardCommand('leaderboard');
|
export default new LeaderboardCommand('leaderboard');
|
||||||
|
|||||||
+34
-2
@@ -3,6 +3,36 @@ import database from "../database";
|
|||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
|
||||||
|
async function getPoints(id: string, guild_id: string): Promise<number> {
|
||||||
|
const [row] = await database`
|
||||||
|
SELECT points
|
||||||
|
FROM points
|
||||||
|
WHERE user_id = ${id}
|
||||||
|
AND guild_id = ${guild_id}
|
||||||
|
`;
|
||||||
|
|
||||||
|
return row?.points ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getLeaderboardPosition(id: string, guild_id: string): Promise<number | null> {
|
||||||
|
const [row] = await database`
|
||||||
|
SELECT position
|
||||||
|
FROM (
|
||||||
|
SELECT
|
||||||
|
user_id,
|
||||||
|
RANK() OVER (ORDER BY points DESC) AS position
|
||||||
|
FROM points
|
||||||
|
WHERE guild_id = ${guild_id}
|
||||||
|
AND points > 0
|
||||||
|
) leaderboard
|
||||||
|
WHERE user_id = ${id}
|
||||||
|
`;
|
||||||
|
|
||||||
|
return row?.position ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
@SlashCommand(
|
@SlashCommand(
|
||||||
new CommandBuilder('rank', 'See your rank information.')
|
new CommandBuilder('rank', 'See your rank information.')
|
||||||
.setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall)
|
.setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall)
|
||||||
@@ -14,8 +44,8 @@ class RankCommand extends Command<CommandClient> {
|
|||||||
if (!interaction.inGuild()) return;
|
if (!interaction.inGuild()) return;
|
||||||
await interaction.defer();
|
await interaction.defer();
|
||||||
|
|
||||||
const _points = await database.points.getPoints(interaction.member.id, interaction.guild.id);
|
const _points = await getPoints(interaction.member.id, interaction.guild.id);
|
||||||
const _rank = await database.leaderboard.getLeaderboardPosition(interaction.member.id, interaction.guild.id);
|
const _rank = await getLeaderboardPosition(interaction.member.id, interaction.guild.id);
|
||||||
|
|
||||||
await interaction.createMessage({
|
await interaction.createMessage({
|
||||||
embeds: [{
|
embeds: [{
|
||||||
@@ -36,4 +66,6 @@ class RankCommand extends Command<CommandClient> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
export default new RankCommand('rank');
|
export default new RankCommand('rank');
|
||||||
+1
-88
@@ -2,91 +2,4 @@ import postgres from "postgres";
|
|||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
|
||||||
const client = postgres(process.env.DATABASE_URL);
|
export default postgres(process.env.DATABASE_URL);
|
||||||
|
|
||||||
async function init() {
|
|
||||||
await client`
|
|
||||||
CREATE TABLE IF NOT EXISTS points (
|
|
||||||
user_id TEXT NOT NULL,
|
|
||||||
guild_id TEXT NOT NULL,
|
|
||||||
points INTEGER NOT NULL DEFAULT 0 CHECK (points >= 0),
|
|
||||||
|
|
||||||
PRIMARY KEY (user_id, guild_id)
|
|
||||||
)
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getPoints(id: string, guild_id: string): Promise<number> {
|
|
||||||
const [row] = await client`
|
|
||||||
SELECT points
|
|
||||||
FROM points
|
|
||||||
WHERE user_id = ${id}
|
|
||||||
AND guild_id = ${guild_id}
|
|
||||||
`;
|
|
||||||
|
|
||||||
return row?.points ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function addPoints(id: string, guild_id: string, count: number) {
|
|
||||||
await client`
|
|
||||||
INSERT INTO points AS p (user_id, guild_id, points)
|
|
||||||
VALUES (${id}, ${guild_id}, ${count})
|
|
||||||
ON CONFLICT (user_id, guild_id)
|
|
||||||
DO UPDATE SET points = p.points + ${count}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function takePoints(id: string, guild_id: string, count: number) {
|
|
||||||
await client`
|
|
||||||
INSERT INTO points AS p (user_id, guild_id, points)
|
|
||||||
VALUES (${id}, ${guild_id}, 0)
|
|
||||||
ON CONFLICT (user_id, guild_id)
|
|
||||||
DO UPDATE SET points = GREATEST(p.points - ${count}, 0)
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
|
|
||||||
async function getLeaderboard(guild_id: string, limit: number = 10): Promise<{ user_id: string; points: number }[]> {
|
|
||||||
return await client`
|
|
||||||
SELECT user_id, points
|
|
||||||
FROM points
|
|
||||||
WHERE guild_id = ${guild_id}
|
|
||||||
AND points > 0
|
|
||||||
ORDER BY points DESC, user_id ASC
|
|
||||||
LIMIT ${limit}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getLeaderboardPosition(id: string, guild_id: string): Promise<number | null> {
|
|
||||||
const [row] = await client`
|
|
||||||
SELECT position
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
user_id,
|
|
||||||
RANK() OVER (ORDER BY points DESC) AS position
|
|
||||||
FROM points
|
|
||||||
WHERE guild_id = ${guild_id}
|
|
||||||
AND points > 0
|
|
||||||
) leaderboard
|
|
||||||
WHERE user_id = ${id}
|
|
||||||
`;
|
|
||||||
|
|
||||||
return row?.position ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
|
|
||||||
export default {
|
|
||||||
points: {
|
|
||||||
init,
|
|
||||||
getPoints,
|
|
||||||
addPoints,
|
|
||||||
takePoints
|
|
||||||
},
|
|
||||||
|
|
||||||
leaderboard: {
|
|
||||||
getLeaderboard,
|
|
||||||
getLeaderboardPosition
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -8,7 +8,13 @@ class MessageReactionAddEvent extends Event<CommandClient> {
|
|||||||
|
|
||||||
async handle(context: CommandClient<any, any>, message: Message, emoji: Constants.APIEmoji, member: Member) {
|
async handle(context: CommandClient<any, any>, message: Message, emoji: Constants.APIEmoji, member: Member) {
|
||||||
if (!message.guildID || emoji.id != '1547870117080342548' || member.id == message.author.id) return;
|
if (!message.guildID || emoji.id != '1547870117080342548' || member.id == message.author.id) return;
|
||||||
await database.points.addPoints(message.author.id, member.guild.id, 1);
|
|
||||||
|
await database`
|
||||||
|
INSERT INTO points AS p (user_id, guild_id, points)
|
||||||
|
VALUES (${message.author.id}, ${member.guild.id}, 1)
|
||||||
|
ON CONFLICT (user_id, guild_id)
|
||||||
|
DO UPDATE SET points = p.points + 1
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,14 @@ class MessageReactionRemoveEvent extends Event<CommandClient> {
|
|||||||
|
|
||||||
async handle(context: CommandClient<any, any>, message: { id: string; channel: { id: string } }, emoji: Constants.APIEmoji, userId: string) {
|
async handle(context: CommandClient<any, any>, message: { id: string; channel: { id: string } }, emoji: Constants.APIEmoji, userId: string) {
|
||||||
const _message = await context.getMessage(message.channel.id, message.id);
|
const _message = await context.getMessage(message.channel.id, message.id);
|
||||||
|
|
||||||
if (!_message.guildID || emoji.id != '1547870117080342548' || userId == _message.author.id) return;
|
if (!_message.guildID || emoji.id != '1547870117080342548' || userId == _message.author.id) return;
|
||||||
await database.points.takePoints(_message.author.id, _message.guildID, 1);
|
|
||||||
|
await database`
|
||||||
|
INSERT INTO points AS p (user_id, guild_id, points)
|
||||||
|
VALUES ${_message.author.id}, ${_message.guildID}, 0)
|
||||||
|
ON CONFLICT (user_id, guild_id)
|
||||||
|
DO UPDATE SET points = GREATEST(p.points - 1, 0)
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-1
@@ -26,5 +26,16 @@ events.forEach((event) => client.registerEvent(event, true));
|
|||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
|
||||||
database.points.init();
|
database`
|
||||||
|
CREATE TABLE IF NOT EXISTS points (
|
||||||
|
user_id TEXT NOT NULL,
|
||||||
|
guild_id TEXT NOT NULL,
|
||||||
|
points INTEGER NOT NULL DEFAULT 0 CHECK (points >= 0),
|
||||||
|
|
||||||
|
PRIMARY KEY (user_id, guild_id)
|
||||||
|
)
|
||||||
|
`;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
client.connect();
|
client.connect();
|
||||||
|
|||||||
Reference in New Issue
Block a user