Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
data
data/*
!data/mail
node_modules
.venv
.DS_Store
Expand Down
52 changes: 26 additions & 26 deletions bun.lock

Large diffs are not rendered by default.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion locales/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
"alreadyReported": "You've already reported this player's tag!",
"invalidReason": "You have to provide a valid reason!",
"validation": "Keep the \"reason\" field between <min> and <max> characters.",
"success": "The player was successfully reported!",
"success": "You have successfully created the report with the ID #<id>!",
"immune": "This player cannot be reported!",
"delete": {
"not_found": "The report was not found!",
Expand Down
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,26 @@
"dependencies": {
"@elysiajs/cors": "^1.3.3",
"@elysiajs/swagger": "1.3.0",
"@sentry/bun": "^9.29.0",
"axios": "^1.9.0",
"@sentry/bun": "^9.31.0",
"axios": "^1.10.0",
"chalk": "^5.4.1",
"change-case": "^5.4.4",
"croner": "^9.0.0",
"discord.js": "^14.19.3",
"croner": "^9.1.0",
"discord.js": "^14.20.0",
"dotenv": "^16.5.0",
"elysia": "1.3.4",
"elysia": "1.3.5",
"elysia-ip": "^1.0.10",
"jsonwebtoken": "^9.0.2",
"minimist": "^1.2.8",
"moment": "^2.30.1",
"mongoose": "^8.15.2",
"mongoose": "^8.16.0",
"ms": "^2.1.3",
"nodemailer": "^7.0.3",
"sharp": "^0.34.2"
},
"devDependencies": {
"@types/bun": "^1.2.16",
"@types/jsonwebtoken": "^9.0.9",
"@types/bun": "^1.2.17",
"@types/jsonwebtoken": "^9.0.10",
"@types/minimist": "^1.2.5",
"@types/nodemailer": "^6.4.17"
}
Expand Down
6 changes: 3 additions & 3 deletions src/auth/AuthProvider.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { existsSync, readdirSync } from "fs";
import { join } from "path";
import Logger from "../libs/Logger";
import players, { Player } from "../database/schemas/players";
import { Player, PlayerDocument } from "../database/schemas/Player";
import { stripUUID } from "../libs/game-profiles";

export type SessionData = {
uuid: string | null,
player: Player | null,
player: PlayerDocument | null,
self: boolean
}

Expand All @@ -22,7 +22,7 @@ export default abstract class AuthProvider {
const tokenUUID = await this.getUUID(token);
if(uuid) uuid = stripUUID(uuid);
if(!tokenUUID) return { uuid: null, player: null, self: false };
const data = await players.findOne({ uuid: tokenUUID });
const data = await Player.findOne({ uuid: tokenUUID });
if(!data) return { uuid: tokenUUID, player: null, self: tokenUUID == uuid };
return {
uuid: tokenUUID,
Expand Down
4 changes: 2 additions & 2 deletions src/auth/providers/ApiKeyProvider.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import players from "../../database/schemas/players";
import { Player } from "../../database/schemas/Player";
import AuthProvider from "../AuthProvider";

export default class ApiKeyProvider extends AuthProvider {
Expand All @@ -8,7 +8,7 @@ export default class ApiKeyProvider extends AuthProvider {

async getUUID(token: string): Promise<string | null> {
token = AuthProvider.trimTokenType(token);
const player = await players.findOne({ 'api_keys.key': token });
const player = await Player.findOne({ 'api_keys.key': token });
if(!player) return null;
const usedKey = player.api_keys.find(key => key.key === token);
if(usedKey) {
Expand Down
4 changes: 2 additions & 2 deletions src/bot/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const buttons = new Collection<string, Button>();
export const menus = new Collection<string, SelectMenu>();
export const modals = new Collection<string, Modal>();

(async () => {
export async function registerFeatures() {
const eventDir = join(__dirname, 'events');
const commandDir = join(__dirname, 'commands');
const buttonDir = join(__dirname, 'buttons');
Expand Down Expand Up @@ -73,7 +73,7 @@ export const modals = new Collection<string, Modal>();

modals.set(modal.id, modal);
});
})();
};

export const spawn = () => client.login(config.discordBot.token);
export const destroy = () => client.destroy();
Expand Down
4 changes: 2 additions & 2 deletions src/bot/buttons/Actions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ButtonInteraction, Message, GuildMember, ButtonStyle, ButtonBuilder, ActionRowBuilder, EmbedBuilder, MessageFlags } from "discord.js";
import Button from "../structs/Button";
import { colors } from "../bot";
import players, { Player } from "../../database/schemas/players";
import players, { PlayerDocument } from "../../database/schemas/Player";
import { Permission } from "../../types/Permission";
import { stripUUID, uuidRegex } from "../../libs/game-profiles";
import { config } from "../../libs/config";
Expand All @@ -19,7 +19,7 @@ export default class ActionsButton extends Button {
});
}

async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: Player) {
async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: PlayerDocument) {
if(!player.canManagePlayers()) return interaction.reply({ embeds: [new EmbedBuilder().setColor(colors.error).setDescription('❌ You\'re not allowed to perform this action!')], flags: [MessageFlags.Ephemeral] });
const uuid = interaction.customId.split('_')[1] || message.embeds[0]?.author?.name || message.embeds[0]?.fields[0]?.value.match(uuidRegex)?.[0];
if(!uuid) return interaction.reply({ embeds: [new EmbedBuilder().setColor(colors.error).setDescription('❌ Player not found!')], flags: [MessageFlags.Ephemeral] });
Expand Down
6 changes: 3 additions & 3 deletions src/bot/buttons/AddRole.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ButtonInteraction, Message, GuildMember, EmbedBuilder, ActionRowBuilder, StringSelectMenuBuilder, MessageFlags } from "discord.js";
import Button from "../structs/Button";
import players, { Player } from "../../database/schemas/players";
import players, { PlayerDocument } from "../../database/schemas/Player";
import { colors } from "../bot";
import { capitalCase, snakeCase } from "change-case";
import { Permission } from "../../types/Permission";
import { getCachedRoles } from "../../database/schemas/roles";
import { getCachedRoles } from "../../database/schemas/Role";

export default class AddRoleButton extends Button {
constructor() {
Expand All @@ -14,7 +14,7 @@ export default class AddRoleButton extends Button {
});
}

async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: Player) {
async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: PlayerDocument) {
const target = await players.findOne({ uuid: interaction.customId.split('_')[1] });
if(!target) return interaction.reply({ embeds: [new EmbedBuilder().setColor(colors.error).setDescription('❌ Player not found!')], flags: [MessageFlags.Ephemeral] });

Expand Down
4 changes: 2 additions & 2 deletions src/bot/buttons/Ban.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ButtonInteraction, Message, GuildMember, ModalBuilder, ActionRowBuilder, TextInputBuilder, TextInputStyle } from "discord.js";
import Button from "../structs/Button";
import { Permission } from "../../types/Permission";
import { Player } from "../../database/schemas/players";
import { PlayerDocument } from "../../database/schemas/Player";

export default class BanButton extends Button {
constructor() {
Expand All @@ -11,7 +11,7 @@ export default class BanButton extends Button {
});
}

public trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: Player) {
public trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: PlayerDocument) {
const modal = new ModalBuilder()
.setTitle('Ban player')
.setCustomId(`ban_${interaction.customId.split('_')[1]}`)
Expand Down
4 changes: 2 additions & 2 deletions src/bot/buttons/BanHistory.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ButtonInteraction, Message, GuildMember, EmbedBuilder, MessageFlags, ActionRowBuilder, StringSelectMenuBuilder } from "discord.js";
import Button from "../structs/Button";
import { colors } from "../bot";
import players, { Player } from "../../database/schemas/players";
import players, { PlayerDocument } from "../../database/schemas/Player";
import { GameProfile } from "../../libs/game-profiles";
import { Permission } from "../../types/Permission";

Expand All @@ -13,7 +13,7 @@ export default class BanHistoryButton extends Button {
});
}

async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: Player) {
async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: PlayerDocument) {
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
const target = await players.findOne({ uuid: interaction.customId.split('_')[1] });
if(!target) return interaction.editReply({ embeds: [new EmbedBuilder().setColor(colors.error).setDescription('❌ Player not found!')] });
Expand Down
4 changes: 2 additions & 2 deletions src/bot/buttons/ClearIconTexture.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ButtonInteraction, Message, GuildMember, EmbedBuilder, MessageFlags } from "discord.js";
import Button from "../structs/Button";
import players, { Player } from "../../database/schemas/players";
import players, { PlayerDocument } from "../../database/schemas/Player";
import { colors } from "../bot";
import { ModLogType, sendModLogMessage } from "../../libs/discord-notifier";
import { sendIconClearEmail } from "../../libs/mailer";
Expand All @@ -15,7 +15,7 @@ export default class ClearIconTextureButton extends Button {
});
}

async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: Player) {
async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: PlayerDocument) {
const target = await players.findOne({ uuid: interaction.customId.split('_')[1] });
if(!target) return interaction.reply({ embeds: [new EmbedBuilder().setColor(colors.error).setDescription('❌ Player not found!')], flags: [MessageFlags.Ephemeral] });
if(!target.icon.hash) return interaction.reply({ embeds: [new EmbedBuilder().setColor(colors.error).setDescription(`❌ This player does not have a custom icon!`)], flags: [MessageFlags.Ephemeral] });
Expand Down
4 changes: 2 additions & 2 deletions src/bot/buttons/ClearTag.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ButtonInteraction, Message, GuildMember, EmbedBuilder, MessageFlags } from "discord.js";
import Button from "../structs/Button";
import players, { Player } from "../../database/schemas/players";
import players, { PlayerDocument } from "../../database/schemas/Player";
import { colors } from "../bot";
import { ModLogType, sendModLogMessage } from "../../libs/discord-notifier";
import { sendTagClearEmail } from "../../libs/mailer";
Expand All @@ -15,7 +15,7 @@ export default class ClearTagButton extends Button {
});
}

async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: Player) {
async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: PlayerDocument) {
const target = await players.findOne({ uuid: interaction.customId.split('_')[1] });
if(!target) return interaction.reply({ embeds: [new EmbedBuilder().setColor(colors.error).setDescription('❌ Player not found!')], flags: [MessageFlags.Ephemeral] });
if(!target.tag) return interaction.reply({ embeds: [new EmbedBuilder().setColor(colors.error).setDescription('❌ This player does not have a tag!')], flags: [MessageFlags.Ephemeral] });
Expand Down
6 changes: 3 additions & 3 deletions src/bot/buttons/Clears.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { ButtonInteraction, Message, GuildMember, EmbedBuilder, MessageFlags } from "discord.js";
import Button from "../structs/Button";
import { colors } from "../bot";
import players, { Player } from "../../database/schemas/players";
import players, { PlayerDocument } from "../../database/schemas/Player";
import { GameProfile } from "../../libs/game-profiles";
import { Permission } from "../../types/Permission";
import { formatTimestamp } from "../../libs/discord-notifier";
import { stripColors } from "../../libs/chat-color";
import { getCustomIconUrl } from "../../routes/players/[uuid]/icon";
import { getCustomIconUrl } from "../../routes/players/[uuid]/icons";

export default class ClearsButton extends Button {
constructor() {
Expand All @@ -16,7 +16,7 @@ export default class ClearsButton extends Button {
});
}

async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: Player) {
async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: PlayerDocument) {
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
const target = await players.findOne({ uuid: interaction.customId.split('_')[1] });
if(!target) return interaction.editReply({ embeds: [new EmbedBuilder().setColor(colors.error).setDescription('❌ Player not found!')] });
Expand Down
4 changes: 2 additions & 2 deletions src/bot/buttons/CreateApiKey.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ButtonInteraction, Message, GuildMember, ActionRowBuilder, ModalBuilder, TextInputBuilder, TextInputStyle } from "discord.js";
import Button from "../structs/Button";
import { Permission } from "../../types/Permission";
import { Player } from "../../database/schemas/players";
import { PlayerDocument } from "../../database/schemas/Player";

export default class CreateApiKeyButton extends Button {
constructor() {
Expand All @@ -11,7 +11,7 @@ export default class CreateApiKeyButton extends Button {
});
}

async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: Player) {
async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: PlayerDocument) {
const modal = new ModalBuilder()
.setTitle('Create API key')
.setCustomId(`createApiKey_${interaction.customId.split('_')[1]}`)
Expand Down
6 changes: 3 additions & 3 deletions src/bot/buttons/CreateGiftCode.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ButtonInteraction, Message, GuildMember, User, EmbedBuilder, ActionRowBuilder, MessageFlags, StringSelectMenuBuilder } from "discord.js";
import Button from "../structs/Button";
import { Player } from "../../database/schemas/players";
import { PlayerDocument } from "../../database/schemas/Player";
import { colors } from "../bot";
import { Permission } from "../../types/Permission";
import { getCachedRoles } from "../../database/schemas/roles";
import { getCachedRoles } from "../../database/schemas/Role";
import { capitalCase } from "change-case";

export default class CreateGiftCodeButton extends Button {
Expand All @@ -14,7 +14,7 @@ export default class CreateGiftCodeButton extends Button {
});
}

async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: Player) {
async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: PlayerDocument) {
const embed = new EmbedBuilder()
.setColor(colors.gray)
.setTitle('Create gift code')
Expand Down
4 changes: 2 additions & 2 deletions src/bot/buttons/CreateNote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ButtonInteraction, Message, GuildMember, ModalBuilder, ActionRowBuilder
import Button from "../structs/Button";
import { config } from "../../libs/config";
import { Permission } from "../../types/Permission";
import { Player } from "../../database/schemas/players";
import { PlayerDocument } from "../../database/schemas/Player";

export default class CreateNoteButton extends Button {
constructor() {
Expand All @@ -12,7 +12,7 @@ export default class CreateNoteButton extends Button {
});
}

public trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: Player) {
public trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: PlayerDocument) {
const modal = new ModalBuilder()
.setTitle('Create note')
.setCustomId(`createNote_${interaction.customId.split('_')[1]}`)
Expand Down
4 changes: 2 additions & 2 deletions src/bot/buttons/CreateRole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ButtonInteraction, Message, GuildMember, ModalBuilder, ActionRowBuilder
import Button from "../structs/Button";
import { config } from "../../libs/config";
import { Permission } from "../../types/Permission";
import { Player } from "../../database/schemas/players";
import { PlayerDocument } from "../../database/schemas/Player";

export default class CreateRoleButton extends Button {
constructor() {
Expand All @@ -12,7 +12,7 @@ export default class CreateRoleButton extends Button {
});
}

public trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: Player) {
public trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: PlayerDocument) {
const modal = new ModalBuilder()
.setTitle('Create role')
.setCustomId('createRole')
Expand Down
4 changes: 2 additions & 2 deletions src/bot/buttons/DeleteApiKey.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ButtonInteraction, Message, GuildMember, EmbedBuilder, ActionRowBuilder, MessageFlags, StringSelectMenuBuilder, StringSelectMenuOptionBuilder } from "discord.js";
import Button from "../structs/Button";
import players, { Player } from "../../database/schemas/players";
import players, { PlayerDocument } from "../../database/schemas/Player";
import { colors } from "../bot";
import { Permission } from "../../types/Permission";

Expand All @@ -12,7 +12,7 @@ export default class DeleteApiKeyButton extends Button {
});
}

async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: Player) {
async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: PlayerDocument) {
const target = await players.findOne({ uuid: interaction.customId.split('_')[1] });
if(!target) return interaction.reply({ embeds: [new EmbedBuilder().setColor(colors.error).setDescription('❌ Player not found!')], flags: [MessageFlags.Ephemeral] });

Expand Down
8 changes: 4 additions & 4 deletions src/bot/buttons/DeleteGiftCode.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ButtonInteraction, Message, GuildMember, EmbedBuilder, ActionRowBuilder, MessageFlags, StringSelectMenuBuilder } from "discord.js";
import Button from "../structs/Button";
import { Player } from "../../database/schemas/players";
import { PlayerDocument } from "../../database/schemas/Player";
import { colors } from "../bot";
import { Permission } from "../../types/Permission";
import codeSchema from "../../database/schemas/gift-codes";
import { GiftCode } from "../../database/schemas/GiftCode";

export default class DeleteGiftCodeButton extends Button {
constructor() {
Expand All @@ -13,13 +13,13 @@ export default class DeleteGiftCodeButton extends Button {
});
}

async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: Player) {
async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: PlayerDocument) {
const embed = new EmbedBuilder()
.setColor(colors.gray)
.setTitle('Delete gift code')
.setDescription('Here you can select a gift code to be deleted.');

const codes = await codeSchema.find();
const codes = await GiftCode.find();
const codeMap = codes.filter((code) => code.isValid()).slice(0, 25).map((code) => ({
value: code.code,
label: code.name,
Expand Down
4 changes: 2 additions & 2 deletions src/bot/buttons/DeleteNote.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ButtonInteraction, Message, GuildMember, ActionRowBuilder, EmbedBuilder, StringSelectMenuBuilder, StringSelectMenuOptionBuilder, MessageFlags } from "discord.js";
import Button from "../structs/Button";
import { colors } from "../bot";
import players, { Player } from "../../database/schemas/players";
import players, { PlayerDocument } from "../../database/schemas/Player";
import { GameProfile } from "../../libs/game-profiles";
import { Permission } from "../../types/Permission";

Expand All @@ -13,7 +13,7 @@ export default class DeleteNoteButton extends Button {
});
}

async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: Player) {
async trigger(interaction: ButtonInteraction, message: Message, member: GuildMember, player: PlayerDocument) {
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
const target = await players.findOne({ uuid: interaction.customId.split('_')[1] });
if(!target) return interaction.editReply({ embeds: [new EmbedBuilder().setColor(colors.error).setDescription('❌ Player not found!')] });
Expand Down
Loading
Loading