This commit is contained in:
2026-08-26 20:06:13 +08:00
parent f15aa87523
commit 34b0082045
16 changed files with 133 additions and 110 deletions
+7 -7
View File
@@ -1,5 +1,5 @@
import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from "athena-prime";
import config from "../../config";
import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from 'athena-prime';
import config from '../../config';
// ----------
@@ -8,12 +8,12 @@ import config from "../../config";
.setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall)
.setContexts(Constants.InteractionContextType.Guild)
.setCommandType(Constants.ApplicationCommandType.ChatInput)
.setMemberPermission(Constants.PermissionFlagsBits.Administrator)
.setMemberPermission(Constants.PermissionFlagsBits.Administrator),
)
class InitCommand extends Command<CommandClient> {
users = [
'1363132678022631428', // nxbat
'454653142500507649' // bitdash
'454653142500507649', // bitdash
];
async #createInformationMessage(context: CommandClient<any, any>, interaction: CommandInteraction) {
@@ -37,9 +37,9 @@ class InitCommand extends Command<CommandClient> {
footer: {
text: `Made by nxbat @ Archwing`,
icon_url: 'https://femboytrain.ing/nxbat-archwing'
}
}
icon_url: 'https://femboytrain.ing/nxbat-archwing',
},
},
});
}
+5 -5
View File
@@ -1,8 +1,8 @@
import init from "./admin/init";
import leaderboard from "./leaderboard";
import optin from "./privacy/optin";
import optout from "./privacy/optout";
import profile from "./profile";
import init from './admin/init';
import leaderboard from './leaderboard';
import optin from './privacy/optin';
import optout from './privacy/optout';
import profile from './profile';
// ----------
+21 -21
View File
@@ -1,5 +1,5 @@
import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from "athena-prime";
import { getHighestPets, getUser } from "../utils";
import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from 'athena-prime';
import { getHighestPets } from '../utils';
// ----------
@@ -7,7 +7,7 @@ import { getHighestPets, getUser } from "../utils";
new CommandBuilder('leaderboard', 'Get the petting leaderboard.')
.setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall)
.setContexts(Constants.InteractionContextType.Guild)
.setCommandType(Constants.ApplicationCommandType.ChatInput)
.setCommandType(Constants.ApplicationCommandType.ChatInput),
)
class LeaderboardCommand extends Command<CommandClient> {
cooldown = 15;
@@ -18,29 +18,29 @@ class LeaderboardCommand extends Command<CommandClient> {
const _data = await getHighestPets();
const description = _data.length
? _data
.map((entry, index) =>
`**${index + 1}.** <@${entry.userId}> — **${entry.pets.toLocaleString()}** pets!`
)
.map((entry, index) => `**${index + 1}.** <@${entry.userId}> — **${entry.pets.toLocaleString()}** pets!`)
.join('\n')
: 'Nobody has any pets yet!';
await interaction.createMessage({
embeds: [{
author: {
name: interaction.user.username,
icon_url: interaction.user.avatarURL
embeds: [
{
author: {
name: interaction.user.username,
icon_url: interaction.user.avatarURL,
},
color: 0xe77ed1,
title: "Pond's Petting Leaderboard",
description: description,
footer: {
text: `Made by nxbat @ Archwing`,
icon_url: 'https://femboytrain.ing/nxbat-archwing',
},
},
color: 0xe77ed1,
title: "Pond's Petting Leaderboard",
description: description,
footer: {
text: `Made by nxbat @ Archwing`,
icon_url: 'https://femboytrain.ing/nxbat-archwing'
}
}]
],
});
}
}
+3 -3
View File
@@ -1,5 +1,5 @@
import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from "athena-prime";
import { getUser, updateUserSettings } from "../../utils";
import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from 'athena-prime';
import { updateUserSettings } from '../../utils';
// ----------
@@ -7,7 +7,7 @@ import { getUser, updateUserSettings } from "../../utils";
new CommandBuilder('optin', 'Stop counting your pet interactions.')
.setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall)
.setContexts(Constants.InteractionContextType.Guild)
.setCommandType(Constants.ApplicationCommandType.ChatInput)
.setCommandType(Constants.ApplicationCommandType.ChatInput),
)
class OptInCommand extends Command<CommandClient> {
cooldown = 5;
+4 -4
View File
@@ -1,5 +1,5 @@
import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from "athena-prime";
import { getUser, updateUserSettings } from "../../utils";
import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from 'athena-prime';
import { updateUserSettings } from '../../utils';
// ----------
@@ -7,7 +7,7 @@ import { getUser, updateUserSettings } from "../../utils";
new CommandBuilder('optout', 'Stop counting your pet interactions.')
.setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall)
.setContexts(Constants.InteractionContextType.Guild)
.setCommandType(Constants.ApplicationCommandType.ChatInput)
.setCommandType(Constants.ApplicationCommandType.ChatInput),
)
class OptOutCommand extends Command<CommandClient> {
cooldown = 5;
@@ -18,7 +18,7 @@ class OptOutCommand extends Command<CommandClient> {
await updateUserSettings(interaction.user.id, { participating: false });
await interaction.createMessage({
content: "Successfully opted out. You won't receive any points for petting :<"
content: "Successfully opted out. You won't receive any points for petting :<",
});
}
}
+36 -34
View File
@@ -1,5 +1,5 @@
import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from "athena-prime";
import { getPetPosition, getUser } from "../utils";
import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from 'athena-prime';
import { getPetPosition, getUser } from '../utils';
// ----------
@@ -7,7 +7,7 @@ import { getPetPosition, getUser } from "../utils";
new CommandBuilder('profile', 'View your profile.')
.setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall)
.setContexts(Constants.InteractionContextType.Guild)
.setCommandType(Constants.ApplicationCommandType.ChatInput)
.setCommandType(Constants.ApplicationCommandType.ChatInput),
)
class ProfileCommand extends Command<CommandClient> {
cooldown = 15;
@@ -19,38 +19,40 @@ class ProfileCommand extends Command<CommandClient> {
const position = await getPetPosition(interaction.user.id);
await interaction.createMessage({
embeds: [{
author: {
name: interaction.user.username,
icon_url: interaction.user.avatarURL
embeds: [
{
author: {
name: interaction.user.username,
icon_url: interaction.user.avatarURL,
},
color: 0xe77ed1,
title: `Your Profile | Pet the Pond`,
fields: [
{
name: 'Pets',
value: `${_user.statistics.pets}`,
inline: true,
},
{
name: 'Rank',
value: position ? `#${position}` : 'N/A',
inline: true,
},
{
name: 'Participating',
value: _user.settings.participating ? 'Yes' : 'No',
inline: false,
},
],
footer: {
text: `Made by nxbat @ Archwing`,
icon_url: 'https://femboytrain.ing/nxbat-archwing',
},
},
color: 0xe77ed1,
title: `Your Profile | Pet the Pond`,
fields: [
{
name: 'Pets',
value: `${_user.statistics.pets}`,
inline: true
},
{
name: 'Rank',
value: position ? `#${position}` : 'N/A',
inline: true
},
{
name: 'Participating',
value: _user.settings.participating ? 'Yes' : 'No',
inline: false
}
],
footer: {
text: `Made by nxbat @ Archwing`,
icon_url: 'https://femboytrain.ing/nxbat-archwing'
}
}]
],
});
}
}
+4 -4
View File
@@ -1,6 +1,6 @@
export default {
identifiers: {
emojiId: "448912932340891670",
targetId: "1363132678022631428"
}
}
emojiId: '448912932340891670',
targetId: '1363132678022631428',
},
};
+2 -2
View File
@@ -1,4 +1,4 @@
import { CommandClient, Event } from "athena-prime";
import { CommandClient, Event } from 'athena-prime';
// ----------
@@ -7,7 +7,7 @@ class ReadyEvent extends Event<CommandClient> {
async handle(context: CommandClient<any, any>) {
await context.deployCommands();
context.setCustomActivity("Petting the Pond!");
context.setCustomActivity('Petting the Pond!');
}
}
+3 -3
View File
@@ -1,6 +1,6 @@
import messageReactionAdd from "./message/messageReactionAdd";
import messageReactionRemove from "./message/messageReactionRemove";
import ready from "./client/ready";
import messageReactionAdd from './message/messageReactionAdd';
import messageReactionRemove from './message/messageReactionRemove';
import ready from './client/ready';
// ----------
+3 -4
View File
@@ -1,6 +1,6 @@
import { CommandClient, Constants, Event, Member, Message } from "athena-prime";
import { CommandClient, Constants, Event, Member, Message } from 'athena-prime';
import config from '../../config';
import { getUser, updateUserStatistics } from "../../utils";
import { getUser, updateUserStatistics } from '../../utils';
// ----------
@@ -12,9 +12,8 @@ class MessageReactionAddEvent extends Event<CommandClient> {
if (msg.author.id !== config.identifiers.targetId || emoji.id !== config.identifiers.emojiId) return;
const _user = await getUser(member.id);
if (_user.flags.blacklisted || !_user.settings.participating) return;
if (!_user.settings.participating) return;
// Update Statistics.
await updateUserStatistics(member.id, { pets: _user.statistics.pets + 1 });
}
}
+9 -5
View File
@@ -1,20 +1,24 @@
import { CommandClient, Constants, Event, Member, Message } from "athena-prime";
import { CommandClient, Constants, Event } from 'athena-prime';
import config from '../../config';
import { getUser, updateUserStatistics } from "../../utils";
import { getUser, updateUserStatistics } from '../../utils';
// ----------
class MessageReactionRemoveEvent extends Event<CommandClient> {
event: string = 'messageReactionRemove' as const;
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 msg = await context.getMessage(message.channel.id, message.id);
if (msg.author.id !== config.identifiers.targetId || emoji.id !== config.identifiers.emojiId) return;
const _user = await getUser(userId);
if (_user.flags.blacklisted || !_user.settings.participating) return;
if (!_user.settings.participating) return;
// Update Statistics.
if (_user.statistics.pets >= 0) return;
await updateUserStatistics(userId, { pets: _user.statistics.pets - 1 });
}
+4 -4
View File
@@ -13,7 +13,7 @@ const client: CommandClient = new CommandClient({
intents: [
Constants.GatewayIntentBits.Guilds,
Constants.GatewayIntentBits.GuildMessages,
Constants.GatewayIntentBits.GuildMessageReactions
Constants.GatewayIntentBits.GuildMessageReactions,
],
largeBotOptimizations: true,
@@ -22,13 +22,13 @@ const client: CommandClient = new CommandClient({
users: () => new NullCollection(User),
members: () => new NullCollection(Member),
messages: () => new NullCollection(Message),
guilds: () => new NullCollection(Guild)
guilds: () => new NullCollection(Guild),
},
},
});
commands.forEach(command => client.registerCommand(command, true));
events.forEach(event => client.registerEvent(event, true));
commands.forEach((command) => client.registerCommand(command, true));
events.forEach((event) => client.registerEvent(event, true));
// ----------
+1 -1
View File
@@ -19,4 +19,4 @@ export type User = {
* User statistics.
*/
statistics: UserStatistics;
}
};
+9 -13
View File
@@ -1,20 +1,16 @@
import postgres from "postgres";
import { User } from "../types";
import postgres from 'postgres';
import { User } from '../types';
const client = postgres(process.env.DATABASE_URL);
const getDefaultUser = (userId: string): User => ({
flags: {
blacklisted: false
},
settings: {
participating: true,
},
statistics: {
pets: 0
}
pets: 0,
},
});
export async function getUser(userId: string): Promise<User> {
@@ -50,7 +46,7 @@ export async function deleteUser(userId: string): Promise<void> {
`;
}
export async function updateUserSettings(userId: string, settings: Partial<User["settings"]>): Promise<void> {
export async function updateUserSettings(userId: string, settings: Partial<User['settings']>): Promise<void> {
await client`
UPDATE users
SET data = jsonb_set(
@@ -62,7 +58,7 @@ export async function updateUserSettings(userId: string, settings: Partial<User[
`;
}
export async function updateUserStatistics(userId: string, statistics: Partial<User["statistics"]>): Promise<void> {
export async function updateUserStatistics(userId: string, statistics: Partial<User['statistics']>): Promise<void> {
await client`
UPDATE users
SET data = jsonb_set(
@@ -76,7 +72,7 @@ export async function updateUserStatistics(userId: string, statistics: Partial<U
//#region Leaderboard
export async function getHighestPets(limit = 10): Promise<{ userId: string, pets: number }[]> {
export async function getHighestPets(limit = 10): Promise<{ userId: string; pets: number }[]> {
const users = await client<{ user_id: string; pets: number }[]>`
SELECT user_id, (data->'statistics'->>'pets')::integer AS pets
FROM users
@@ -87,9 +83,9 @@ export async function getHighestPets(limit = 10): Promise<{ userId: string, pets
LIMIT ${limit}
`;
return users.map(user => ({
return users.map((user) => ({
userId: user.user_id,
pets: user.pets
pets: user.pets,
}));
}