diff --git a/src/apis/economy/format.ts b/src/apis/economy/format.ts index adc07c6..7656fa1 100644 --- a/src/apis/economy/format.ts +++ b/src/apis/economy/format.ts @@ -4,6 +4,7 @@ import { EconomyExecutor } from './action.ts'; import Money from '@/util/money.ts'; import { Ternary } from '@/defs.ts'; import { cfg } from '@/bot/cfg.ts'; +import m from '@/util/mentions.ts'; export interface EconomyActionsFormatterConfig { indentStep?: string; @@ -40,7 +41,7 @@ export class MinimalActionsFormatter implements EconomyActionsFormatter { case 'has-role': { const role = this.ctx.getRoleById(cond.roleId); if (!role) return null; - return `masz rolę <@&${role.discordRoleId}>`; + return `masz rolę ${m.role(role)}`; } case 'has-item': { @@ -87,7 +88,7 @@ export class MinimalActionsFormatter implements EconomyActionsFormatter { case 'rem-role': { const role = this.ctx.getRoleById(action.roleId); if (!role) break; - return `${this.isGood(action) ? 'rolę' : '**usunięcie** roli'} <@&${role.discordRoleId}>`; + return `${this.isGood(action) ? 'rolę' : '**usunięcie** roli'} ${m.role(role)}`; } case 'add-item': diff --git a/src/apis/mod/bans.ts b/src/apis/mod/bans.ts index 9f06e30..fed2614 100644 --- a/src/apis/mod/bans.ts +++ b/src/apis/mod/bans.ts @@ -5,6 +5,7 @@ import { PredefinedColors } from '@/util/color.ts'; import { sendLog } from '@/log/send-log.ts'; import User from '@/apis/db/user.ts'; +import m from '@/util/mentions.ts'; export default async function ban( member: dsc.GuildMember, @@ -38,7 +39,7 @@ export default async function ban( { color: PredefinedColors.DarkGrey, title: 'Zbanowano członka', - description: `Użytkownik <@${smember.id}> (${smember.user.username}) został zbanowany z serwera przez <@${data.mod}>!`, + description: `Użytkownik ${m.user(smember)} (${smember.user.username}) został zbanowany z serwera przez ${m.user(data.mod)}!`, fields: [{ name: 'Powód', value: data.reason }], }, ); diff --git a/src/apis/mod/kicks.ts b/src/apis/mod/kicks.ts index c847c1f..911af60 100644 --- a/src/apis/mod/kicks.ts +++ b/src/apis/mod/kicks.ts @@ -4,6 +4,8 @@ import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; import { PredefinedColors } from '@/util/color.ts'; import { sendLog } from '@/log/send-log.ts'; +import m from '@/util/mentions.ts'; + export default async function kick( member: dsc.GuildMember, data: { reason: string; mod: dsc.Snowflake }, @@ -22,7 +24,7 @@ export default async function kick( sendLog({ color: PredefinedColors.DarkGrey, title: 'Wywalono członka', - description: `Użytkownik <@${member.id}> (${member.user.username}) został wyrzucony z serwera przez <@${data.mod}>!`, + description: `Użytkownik ${m.user(member)} (${member.user.username}) został wyrzucony z serwera przez ${m.user(data.mod)}!`, fields: [{ name: 'Powód', value: data.reason }], }); return bannedMember; diff --git a/src/apis/mod/muting.ts b/src/apis/mod/muting.ts index cd9cfc5..16a5efc 100644 --- a/src/apis/mod/muting.ts +++ b/src/apis/mod/muting.ts @@ -1,8 +1,11 @@ import * as dsc from 'discord.js'; + import { sendLog } from '@/log/send-log.ts'; import { PredefinedColors } from '@/util/color.ts'; import { cfg } from '@/bot/cfg.ts'; +import m from '@/util/mentions.ts'; + export default function mute( member: dsc.GuildMember, data: { reason: string; duration?: number; moderator: string; }, @@ -10,8 +13,8 @@ export default function mute( sendLog({ color: PredefinedColors.Purple, title: 'Użytkownik dostał mute', - description: `Użytkownik <@${member.id}> został wyciszony przez <@${data.moderator}>.`, - fields: [{ name: 'Powód', value: data.reason }, { name: 'Wygasa', value: `` }], + description: `Użytkownik ${m.user(member)} został wyciszony przez ${m.user(data.moderator)}.`, + fields: [{ name: 'Powód', value: data.reason }, { name: 'Wygasa', value: `` }], }, [ cfg.channels.mod.punishments ]); return member.timeout(data.duration ?? null, data.reason); diff --git a/src/bot/level.ts b/src/bot/level.ts index 19fabd0..2ab4588 100644 --- a/src/bot/level.ts +++ b/src/bot/level.ts @@ -1,7 +1,5 @@ import * as dsc from 'discord.js'; -import User from '@/apis/db/user.ts'; - import actionsManager, { Action } from '@/features/actions.ts'; import { mkProgressBar } from '@/util/progressbar.ts'; import { findLowerClosestKey } from '@/util/objects/lower-closest-key.ts'; @@ -10,6 +8,9 @@ import { cfg } from '@/bot/cfg.ts'; import { client } from '@/client.ts'; import { output } from './logging.ts'; +import User from '@/apis/db/user.ts'; +import m from '@/util/mentions.ts'; + export const OnSetXpEvent = actionsManager.mkEvent('OnSetXpEvent'); export interface XpEventCtx { userID: dsc.Snowflake; @@ -31,10 +32,6 @@ export function levelToXp(level: number, levelDivider: number = cfg.features.lev export const lvlRoles = Object.values(cfg.features.leveling.milestoneRoles); -function getMention(user: dsc.GuildMember) { - return `<@${user.user.id}>`; -} - export function mkLvlProgressBar(xp: number, levelDivider: number, totalLength: number = 10): string { const level = xpToLevel(xp, levelDivider); const xpCurrentLevel = levelToXp(level, levelDivider); @@ -138,7 +135,7 @@ export async function addExperiencePoints(msg: dsc.OmitPartialGroupDMChannel = { const newLevel = xpToLevel(newXp, cfg.features.leveling.levelDivider); if (newLevel > prevLevel) { - content = `Level użytkownika ${getMention(member)} został zmieniony i teraz ma aż ${newLevel} level!`; + content = `Level użytkownika ${m.user(member)} został zmieniony i teraz ma aż ${newLevel} level!`; await addLvlRole(member.guild, newLevel, member.id); } else if (newLevel < prevLevel) { - content = `Level użytkownika ${getMention(member)} został zmieniony, przez co cofnął się do levela ${newLevel}!`; + content = `Level użytkownika ${m.user(member)} został zmieniony, przez co cofnął się do levela ${newLevel}!`; await addLvlRole(member.guild, newLevel, member.id); } else { if (prevXp == newXp) { - content = `Administrator próbował zmienić level użytkownika ${getMention(member)}, ale ma autyzm i ustawił dokladnie taki sam jaki był wcześniej czyli ${prevLevel} level. Nic tylko pogratulować`; + content = `Administrator próbował zmienić level użytkownika ${m.user(member)}, ale ma autyzm i ustawił dokladnie taki sam jaki był wcześniej czyli ${prevLevel} level. Nic tylko pogratulować`; } else { - content = `Level użytkownika ${getMention(member)} został zmieniony, co prawda dalej ma ${prevLevel} level, ale tym razem ${newXp}xp zamiast ${prevXp}xp?` + + content = `Level użytkownika ${m.user(member)} został zmieniony, co prawda dalej ma ${prevLevel} level, ale tym razem ${newXp}xp zamiast ${prevXp}xp?` + ` Dobra przestane yappowac tych nerdowskich liczb i dam ci progress bar do następnego levela:` + '\n' + mkLvlProgressBar(newXp, cfg.features.leveling.levelDivider); } diff --git a/src/cmd/4fun/random.ts b/src/cmd/4fun/random.ts index 5dcc2c9..5264690 100644 --- a/src/cmd/4fun/random.ts +++ b/src/cmd/4fun/random.ts @@ -3,6 +3,8 @@ import { CommandFlags } from '@/bot/command/misc.ts'; import { db, ContentEntry } from '@/apis/db/bot-db.ts'; import { cfg } from '@/bot/cfg.ts'; +import m from '@/util/mentions.ts'; + export default { name: 'random', aliases: ['rand'], @@ -54,10 +56,10 @@ export default { } return api.reply({ - content: `polecam zasugerowane przez <@${content.authorId}> ${content.contentUrl}`, + content: `polecam zasugerowane przez ${m.user(content.authorId)}: ${content.contentUrl}`, allowedMentions: { parse: [], }, }); }, -} satisfies Command; \ No newline at end of file +} satisfies Command; diff --git a/src/cmd/4fun/votepin.ts b/src/cmd/4fun/votepin.ts index 5b098de..6bb5d88 100644 --- a/src/cmd/4fun/votepin.ts +++ b/src/cmd/4fun/votepin.ts @@ -7,6 +7,7 @@ import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; import User from '@/apis/db/user.ts'; import sleep from '@/util/sleep.ts'; +import m from '@/util/mentions.ts'; const MIN_VOTES = 5; const TIME = 120_000; @@ -41,7 +42,7 @@ export default { new ReplyEmbed() .setTitle('📌 Przypnij wiadomość') .setDescription([ - `Użytkownik <@${api.executor.id}> chce przypiąć wiadomość od <@${quoted.author.id}>: https://discord.com/channels/${quoted.guildId}/${quoted.channelId}/${quoted.id}`, + `Użytkownik ${m.user(api.executor)} chce przypiąć wiadomość od ${m.user(quoted.author)}: https://discord.com/channels/${quoted.guildId}/${quoted.channelId}/${quoted.id}`, '', `**Głosów:** ${votes}/${MIN_VOTES}`, `**Głosowanie wygasa** ` diff --git a/src/cmd/dev/reset.ts b/src/cmd/dev/reset.ts index 29b70e0..08c9999 100644 --- a/src/cmd/dev/reset.ts +++ b/src/cmd/dev/reset.ts @@ -1,13 +1,20 @@ import * as dsc from 'discord.js'; + +import { + getErrorEmbed, getSuccessEmbed, getWarnEmbed, +} from '@/util/log.ts'; + import { Command } from '@/bot/command.ts'; import { CommandFlags } from '@/bot/command/misc.ts'; import { CommandPermissions } from '@/bot/command/permissions.ts'; import { CommandAPI } from '@/bot/command/api.ts'; + import { db } from '@/apis/db/bot-db.ts'; import { output } from '@/bot/logging.ts'; -import { getErrorEmbed, getSuccessEmbed, getWarnEmbed } from '@/util/log.ts'; import { cfg } from '@/bot/cfg.ts'; +import m from '@/util/mentions.ts'; + export default { name: 'reset', aliases: [], @@ -106,7 +113,7 @@ export default { break; } - const scopeText = userId ? `dla użytkownika <@${userId}>` : 'dla WSZYSTKICH użytkowników'; + const scopeText = userId ? `dla użytkownika ${m.user(userId)}` : 'dla WSZYSTKICH użytkowników'; await interaction.update({ embeds: [getSuccessEmbed('Reset zakończony', `Pomyślnie zresetowano tabele **${table}** ${scopeText}.`)], components: [], diff --git a/src/cmd/economy/ecomod.ts b/src/cmd/economy/ecomod.ts index acc0fbe..c04771a 100644 --- a/src/cmd/economy/ecomod.ts +++ b/src/cmd/economy/ecomod.ts @@ -1,10 +1,12 @@ import { cfg } from '@/bot/cfg.ts'; import { db } from '@/apis/db/bot-db.ts'; + import { Command } from '@/bot/command.ts'; import { CommandFlags } from '@/bot/command/misc.ts'; -import User from '@/apis/db/user.ts'; +import User from '@/apis/db/user.ts'; import Money from '@/util/money.ts'; +import m from '@/util/mentions.ts'; export default { name: 'ecomod', @@ -88,6 +90,9 @@ export default { await targetUser.economy.setBalance(bal); }); - return api.log.replySuccess(api, 'Operacja zakończona!', `Pomyślnie zmodyfikowałeś balans użytkownika <@${targetId}>, tak że ${actionToString()}. Przed tą operacją w tej lokalizacji miał ${before!.format()}.`) + return api.log.replySuccess( + api, 'Operacja zakończona!', + `Pomyślnie zmodyfikowałeś balans użytkownika ${m.user(targetId)}, tak że ${actionToString()}. Przed tą operacją w tej lokalizacji miał ${before!.format()}.` + ) }, } satisfies Command; diff --git a/src/cmd/economy/rob.ts b/src/cmd/economy/rob.ts index 277bd53..0dcc296 100644 --- a/src/cmd/economy/rob.ts +++ b/src/cmd/economy/rob.ts @@ -1,14 +1,15 @@ import { db } from '@/apis/db/bot-db.ts'; +import { output } from '@/bot/logging.ts'; import { getRandomFloat } from '@/util/math/rand.ts'; import { Command } from '@/bot/command.ts'; import { CommandFlags } from '@/bot/command/misc.ts'; import { PredefinedColors } from '@/util/color.ts'; -import { output } from '@/bot/logging.ts'; import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; -import Money from '@/util/money.ts'; -import User from '@/apis/db/user.ts'; +import Money from '@/util/money.ts'; +import User from '@/apis/db/user.ts'; +import m from '@/util/mentions.ts'; const CooldownMs = 5 * 60 * 1000; const BaseSuccessChance = 0.5; @@ -115,7 +116,7 @@ export default { const embed = new ReplyEmbed() .setColor(PredefinedColors.Yellow) .setTitle('Cel jest zbyt biedny') - .setDescription(`<@${targetMember.id}> ma za mało pieniędzy (mniej niż ${MinStealable.format()}).`); + .setDescription(`${m.user(targetMember)} ma za mało pieniędzy (mniej niż ${MinStealable.format()}).`); return api.reply({ embeds: [embed] }); } @@ -125,7 +126,11 @@ export default { const embed = new ReplyEmbed() .setColor(result.success ? PredefinedColors.Green : PredefinedColors.Red) .setTitle(result.success ? 'TAAAAAAAAAAAAAAAAK!' : 'System ochrony w banku się włączył.') - .setDescription(result.success ? `Udało Ci się ukraść <@${targetMember.id}> **${result.amount?.format()}** (${result.percent}%).` : `Nie udało Ci się nic ukraść od <@${targetMember.id}>!`); + .setDescription( + result.success + ? `Udało Ci się ukraść ${m.user(targetMember)} **${result.amount?.format()}** (${result.percent}%).` + : `Nie udało Ci się nic ukraść od ${m.user(targetMember)}!` + ); return api.reply({ embeds: [embed] }); } catch (error) { @@ -133,4 +138,4 @@ export default { return api.log.replyError(api, 'Coś się odwaliło...', 'Proszę, pytaj sqlite3 a nie mnie obwiniasz.'); } }, -} satisfies Command; \ No newline at end of file +} satisfies Command; diff --git a/src/cmd/economy/topeco.ts b/src/cmd/economy/topeco.ts index 7ce2e65..04c4ad3 100644 --- a/src/cmd/economy/topeco.ts +++ b/src/cmd/economy/topeco.ts @@ -2,12 +2,14 @@ import * as dsc from 'discord.js'; import { Command } from '@/bot/command.ts'; import { CommandFlags } from '@/bot/command/misc.ts'; +import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; import { db } from '@/apis/db/bot-db.ts'; import { output } from '@/bot/logging.ts'; -import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; import { cfg } from '@/bot/cfg.ts'; +import m from '@/util/mentions.ts'; + const ecoRoles = cfg.features.economy.roles.filter((x) => x.id.includes('vip')).map((x) => x.discordRoleId); export default { @@ -47,7 +49,7 @@ export default { fields.push({ name: `${i} » ${member.user.username}`, value: [ - `${userEcoRole ? `<@&${userEcoRole}>` : `<@&${cfg.features.welcomer.freeRolesForEveryone[0]}>`}`, + userEcoRole ? m.role(userEcoRole) : m.role(cfg.features.welcomer.freeRolesForEveryone[0]), `**${balance.wallet.add(balance.bank).format()}**`, ].join('\n'), inline: true, diff --git a/src/cmd/economy/use.ts b/src/cmd/economy/use.ts index a62157f..ef3d97b 100644 --- a/src/cmd/economy/use.ts +++ b/src/cmd/economy/use.ts @@ -1,15 +1,17 @@ +import * as config from '@/bot/config/schema.ts'; + import { Command } from '@/bot/command.ts'; import { CommandFlags } from '@/bot/command/misc.ts'; import { CommandAPI } from '@/bot/command/api.ts'; import { PredefinedColors } from '@/util/color.ts'; import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; + import { output } from '@/bot/logging.ts'; import { formatEmoji } from 'discord.js'; import { cfg } from '@/bot/cfg.ts'; -import * as config from '@/bot/config/schema.ts'; - import Money from '@/util/money.ts'; +import m from '@/util/mentions.ts'; export function formatAction(api: CommandAPI, action: config.economy.Action): ReplyEmbed | null { const SuccessColor = PredefinedColors.Green; @@ -41,7 +43,7 @@ export function formatAction(api: CommandAPI, action: config.economy.Action): Re if (!role) return null; return new ReplyEmbed() .setTitle(`${SuccessEmoji} Dodano rolę`) - .setDescription(`Otrzymałeś rolę <@&${role.discordRoleId}>!\n\n**Opis:** ${role.desc}`) + .setDescription(`Otrzymałeś rolę ${m.role(role)}!\n\n**Opis:** ${role.desc}`) .setColor(SuccessColor); } case 'rem-role': { @@ -49,7 +51,7 @@ export function formatAction(api: CommandAPI, action: config.economy.Action): Re if (!role) return null; return new ReplyEmbed() .setTitle(`${LossEmoji} Usunięto rolę`) - .setDescription(`Straciłeś rolę <@&${role.discordRoleId}>!\n\n**Opis:** ${role.desc}`) + .setDescription(`Straciłeś rolę ${m.role(role)}!\n\n**Opis:** ${role.desc}`) .setColor(LossColor); } @@ -153,4 +155,4 @@ export default { ); } }, -} satisfies Command; \ No newline at end of file +} satisfies Command; diff --git a/src/cmd/general/add-primary-account.ts b/src/cmd/general/add-primary-account.ts index f815c67..e1e334a 100644 --- a/src/cmd/general/add-primary-account.ts +++ b/src/cmd/general/add-primary-account.ts @@ -1,12 +1,15 @@ +import * as dsc from 'discord.js'; + import { Command } from '@/bot/command.ts'; import { CommandFlags } from '@/bot/command/misc.ts'; import { CommandPermissions } from '@/bot/command/permissions.ts'; -import * as dsc from 'discord.js'; import { db } from '@/apis/db/bot-db.ts'; -import User from '@/apis/db/user.ts'; import { addLvlRole, xpToLevel } from '@/bot/level.ts'; +import User from '@/apis/db/user.ts'; +import m from '@/util/mentions.ts'; + export default { name: 'add-primary-account', aliases: [], @@ -63,7 +66,7 @@ export default { embeds: [ api.log.getWarnEmbed( 'Ostrzeżenie', - `Właśnie zamierzasz **ODDAĆ CAŁY SWÓJ PROGRESS NA RZECZ UŻYTKOWNIKA <@${primary.id}>!**. Zasoby będą współdzielone pomiędzy Tymi dwoma kontami, co oznacza, że będziesz w stanie z dwóch kont korzystać np. ze swoich pieniędzy na ekonomii. Po transferze, cały twój indywidualny postęp **zostanie bezpowrotnie usunięty** z bazy danych, sprawiając, że jeżeli będziesz chciał się odłączyć, będziesz musiał to przeprowadzić z pomocą administracji i zaczynać od nowa...\n\n` + + `Właśnie zamierzasz **ODDAĆ CAŁY SWÓJ PROGRESS NA RZECZ UŻYTKOWNIKA ${m.user(primary)}!**. Zasoby będą współdzielone pomiędzy Tymi dwoma kontami, co oznacza, że będziesz w stanie z dwóch kont korzystać np. ze swoich pieniędzy na ekonomii. Po transferze, cały twój indywidualny postęp **zostanie bezpowrotnie usunięty** z bazy danych, sprawiając, że jeżeli będziesz chciał się odłączyć, będziesz musiał to przeprowadzić z pomocą administracji i zaczynać od nowa...\n\n` + 'Ta operacja jest **nieodwracalna**.', ), ], @@ -152,7 +155,7 @@ export default { embeds: [ api.log.getSuccessEmbed( 'Sukces', - `Od teraz <@${primary.id}> jest oficjalnie twym głównem kontem.\nJeżeli czegoś nie masz, poproś administrację o dodanie Ci tego na alcie.`, + `Od teraz ${m.user(primary)} jest oficjalnie twym głównem kontem.\nJeżeli czegoś nie masz, poproś administrację o dodanie Ci tego na alcie.`, ), ], components: [], @@ -170,4 +173,4 @@ export default { } }); }, -} satisfies Command; \ No newline at end of file +} satisfies Command; diff --git a/src/cmd/general/man.ts b/src/cmd/general/man.ts index d8f7d87..e320743 100644 --- a/src/cmd/general/man.ts +++ b/src/cmd/general/man.ts @@ -3,8 +3,9 @@ import { CommandFlags } from '@/bot/command/misc.ts'; import { PredefinedColors } from '@/util/color.ts'; import { cfg } from '@/bot/cfg.ts'; -import findCommand from '@/util/cmd/find-command.ts'; +import findCommand from '@/util/cmd/find-command.ts'; import canExecuteCmd from '@/util/cmd/can-execute.ts'; +import m from '@/util/mentions.ts'; import { Category } from '@/bot/command.ts'; import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; @@ -78,8 +79,8 @@ export default { const allowedRoles = command.permissions.allowedRoles == null ? null : [...new Set(command.permissions.allowedRoles)]; const allowedUsers = command.permissions.allowedUsers == null ? null : [...new Set(command.permissions.allowedUsers)]; - const formattedAllowedRoles: string[] = allowedRoles != null ? allowedRoles.map((role: string) => `<@&${role}>`) : ['każda rola']; - const formattedAllowedUsers: string[] = allowedUsers != null ? allowedUsers.map((user: string) => `<@${user}>`) : ['każdy użytkownik']; + const formattedAllowedRoles: string[] = allowedRoles != null ? allowedRoles.map(m.role) : ['każda rola']; + const formattedAllowedUsers: string[] = allowedUsers != null ? allowedUsers.map(m.user) : ['każdy użytkownik']; const canUseCommand = canExecuteCmd(command, api.invoker.member ?? api.invoker.user); @@ -106,4 +107,4 @@ export default { return api.reply({ embeds: [embed] }); }, -} satisfies Command; \ No newline at end of file +} satisfies Command; diff --git a/src/cmd/general/manage-accounts.ts b/src/cmd/general/manage-accounts.ts index 40b011a..08db2af 100644 --- a/src/cmd/general/manage-accounts.ts +++ b/src/cmd/general/manage-accounts.ts @@ -1,14 +1,25 @@ +import { + ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, + ComponentType, StringSelectMenuBuilder, StringSelectMenuInteraction, +} from 'discord.js'; + +import { + addLvlRole, xpToLevel +} from '@/bot/level.ts'; + import { Command } from '@/bot/command.ts'; import { CommandFlags } from '@/bot/command/misc.ts'; import { CommandPermissions } from '@/bot/command/permissions.ts'; import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; import { PredefinedColors } from '@/util/color.ts'; + +import { db } from '@/apis/db/bot-db.ts'; import { client } from '@/client.ts'; +import { assert } from '@std/assert'; + +import User from '@/apis/db/user.ts'; import logError from '@/util/log-error.ts'; -import { ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, ComponentType, StringSelectMenuBuilder, StringSelectMenuInteraction } from 'discord.js'; -import { db } from '@/apis/db/bot-db.ts'; -import { addLvlRole, xpToLevel } from '@/bot/level.ts'; -import User from '@/apis/db/user.ts'; +import m from '@/util/mentions.ts'; function getMainAccount(id: string) { try { @@ -32,11 +43,13 @@ export default { permissions: CommandPermissions.everyone(), async execute(api) { - const alternative_accounts = (await Promise.all( + const altAccs = (await Promise.all( (await api.executor.fetchAlternativeAccounts()) .map(async (id) => { try { return await client.users.fetch(id); } catch (e) { logError('stdwarn', e, 'Alternative account fetching'); return null; } }) )).filter((u) => u !== null); - const main_account = await getMainAccount(api.executor.id); + + const mainAcc = await getMainAccount(api.executor.id); + assert(mainAcc != null); const msg = await api.reply({ embeds: [ @@ -46,12 +59,12 @@ export default { .setDescription([ 'Oto wszystkie konta, które połączyłeś w naszym rewolucyjnym bocie. Współdzielisz pomiędzy nimi pieniądze na ekonomii, poziom i dużo różnego rodzaju stanu.', '', - `**Główne konto:** \`${main_account?.username ?? 'nieznane'}\``, - alternative_accounts.length > 0 - ? `**Twoje multikonta:** \`${alternative_accounts.map((a) => a.username).join('`, `')}\`` + `**Główne konto:** \`${mainAcc.username ?? 'nieznane'}\``, + altAccs.length > 0 + ? `**Twoje multikonta:** \`${altAccs.map((a) => a.username).join('`, `')}\`` : '**Nie posiadasz multikont.** Możesz je dodać za pomocą komendy `add-primary-account`.' ].join('\n')) - .setThumbnail(main_account?.displayAvatarURL() ?? client.user!.displayAvatarURL()) + .setThumbnail(mainAcc.displayAvatarURL() ?? client.user!.displayAvatarURL()) ], components: [ new ActionRowBuilder() @@ -68,7 +81,7 @@ export default { ] }); - const filter = (i: ButtonInteraction | StringSelectMenuInteraction) => [...alternative_accounts, main_account].filter(Boolean).map(u => u!.id).includes(i.user.id); + const filter = (i: ButtonInteraction | StringSelectMenuInteraction) => [...altAccs, mainAcc].filter(Boolean).map(u => u!.id).includes(i.user.id); const collector = msg.createMessageComponentCollector({ filter, time: 90000 }); collector.on('collect', async (i) => { @@ -76,23 +89,36 @@ export default { if ( [ 'leave-group', 'leave-group-final', 'move-primary', 'move-primary-selected' ].includes(i.customId) && - alternative_accounts.length <= 0 + altAccs.length <= 0 ) { - return await msg.edit({ embeds: [ - api.log.getErrorEmbed('Nie masz tu altów.', 'Te funkcje są dozwolone tylko dla osób, które posiadają tu alternatywne konta.') - ], components: [] }); + return await msg.edit({ + embeds: [ + api.log.getErrorEmbed( + 'Nie masz tu altów.', + 'Te funkcje są dozwolone tylko dla osób, które posiadają tu alternatywne konta.') + ], + components: [] + }); } if (i.customId == 'leave-group' && i.isButton()) { if (api.executor.id == i.user.id) { - return await msg.edit({ embeds: [ - api.log.getErrorEmbed('Masz problem', 'Jako główne konto nie możesz opuścić grupy multikont. Najpierw musisz przenieść tę pozycję na inne konto.') - ], components: [] }) + return await msg.edit({ + embeds: [ + api.log.getErrorEmbed( + 'Masz problem', + 'Jako główne konto nie możesz opuścić grupy multikont. Najpierw musisz przenieść tę pozycję na inne konto.') + ], + components: [], + }); } await msg.edit({ embeds: [ - api.log.getWarnEmbed('Zamierzasz zresetować cały swój progress!', `Kiedy dodałeś te konto jako alta użytkownika <@${main_account?.id}>, nieodwracalnie przekazałeś cały swój progress na rzecz tego konta. **Jeżeli teraz opuścisz grupę, stracisz dostęp do Twojego postępu i będziesz musiał zaczynać od nowa**. Czy na pewno chcesz to zrobić?`) + api.log.getWarnEmbed( + 'Zamierzasz zresetować cały swój progress!', + `Kiedy dodałeś te konto jako alta użytkownika ${m.user(mainAcc)}, nieodwracalnie przekazałeś cały swój progress na rzecz tego konta. **Jeżeli teraz opuścisz grupę, stracisz dostęp do Twojego postępu i będziesz musiał zaczynać od nowa**. Czy na pewno chcesz to zrobić?` + ), ], components: [ new ActionRowBuilder() @@ -116,7 +142,12 @@ export default { addLvlRole(i.guild!, 1, i.user.id); return await msg.edit({ - embeds: [ api.log.getSuccessEmbed('Proszę bardzo', `Pomyślnie opuściłeś grupę. Nie jesteś już uznawany za alta użytkownika <@${main_account?.id}>`) ], + embeds: [ + api.log.getSuccessEmbed( + 'Proszę bardzo', + `Pomyślnie opuściłeś grupę. Nie jesteś już uznawany za alta użytkownika ${m.user(mainAcc.id)}`, + ), + ], components: [] }); } else if (i.customId == 'move-primary' && i.isButton()) { @@ -130,7 +161,7 @@ export default { new StringSelectMenuBuilder() .setPlaceholder('Wybierz konto') .setCustomId('move-primary-selected') - .setOptions(alternative_accounts.map((ac) => { return { label: ac.displayName, description: `${ac.username} (id: ${ac.id})`, value: ac.id }; })) + .setOptions(altAccs.map((ac) => { return { label: ac.displayName, description: `${ac.username} (id: ${ac.id})`, value: ac.id }; })) ]) ] }); @@ -175,4 +206,4 @@ export default { } }); }, -} satisfies Command; \ No newline at end of file +} satisfies Command; diff --git a/src/cmd/leveling/toplvl.ts b/src/cmd/leveling/toplvl.ts index eb04228..3a9ca00 100644 --- a/src/cmd/leveling/toplvl.ts +++ b/src/cmd/leveling/toplvl.ts @@ -1,13 +1,15 @@ import * as dsc from 'discord.js'; -import { cfg } from '@/bot/cfg.ts'; -import { lvlRoles } from '@/bot/level.ts'; - import { Command } from '@/bot/command.ts'; import { CommandFlags } from '@/bot/command/misc.ts'; -import { output } from '@/bot/logging.ts'; import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; +import { cfg } from '@/bot/cfg.ts'; +import { output } from '@/bot/logging.ts'; +import { lvlRoles } from '@/bot/level.ts'; + +import m from '@/util/mentions.ts'; + function calculateLevel(xp: number, levelDivider: number): number { return Math.floor( (1 + Math.sqrt(1 + 8 * xp / levelDivider)) / 2, @@ -55,7 +57,11 @@ export default { const userLvlRole = lvlRoles.filter((id) => member.roles.cache.has(id)).at(-1); fields.push({ name: `${absCounter} » ${member.user.username}`, - value: `${userLvlRole ? `<@&${userLvlRole}>` : `<@&${cfg.features.welcomer.freeRolesForEveryone[0]}>`}\n**Lvl**: ${calculateLevel(row.xp, cfg.features.leveling.levelDivider)}\n**XP**: ${row.xp}`, + value: [ + userLvlRole ? m.role(userLvlRole) : m.role(cfg.features.welcomer.freeRolesForEveryone[0]), + `**Lvl**: ${calculateLevel(row.xp, cfg.features.leveling.levelDivider)}`, + `**XP**: ${row.xp}` + ].join('\n'), inline: true, }); } catch (e) { diff --git a/src/cmd/mod/ban.ts b/src/cmd/mod/ban.ts index a6eeb29..da3f893 100644 --- a/src/cmd/mod/ban.ts +++ b/src/cmd/mod/ban.ts @@ -8,6 +8,7 @@ import { PredefinedColors } from '@/util/color.ts'; import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; import ban from '@/apis/mod/bans.ts'; +import m from '@/util/mentions.ts'; export default { name: 'ban', @@ -59,9 +60,9 @@ export default { .setTitle(`📢 ${targetUser.user.username} został zbanowany!`) .setDescription(`Multikonto? Już po nim... Wkurzający chłop? Uciszony na zawsze... Ktokolwiek? Nie może wbić, chyba że zrobi alta...`) .addFields( - { name: 'Moderator', value: `<@${api.invoker.id}>`, inline: true }, - { name: 'Użytkownik', value: `<@${targetUser.id}>`, inline: true }, - { name: 'Powód', value: reason, inline: false }, + { name: 'Moderator', value: m.user(api.invoker), inline: true }, + { name: 'Użytkownik', value: m.user(targetUser), inline: true }, + { name: 'Powód', value: reason, inline: false }, ) .setColor(PredefinedColors.Orange), ], diff --git a/src/cmd/mod/gifban.ts b/src/cmd/mod/gifban.ts index f21b342..b79fd08 100644 --- a/src/cmd/mod/gifban.ts +++ b/src/cmd/mod/gifban.ts @@ -1,7 +1,9 @@ import { Command } from '@/bot/command.ts'; import { CommandFlags } from '@/bot/command/misc.ts'; import { CommandPermissions } from '@/bot/command/permissions.ts'; + import { cfg } from '@/bot/cfg.ts'; +import m from '@/util/mentions.ts'; export default { name: 'gifban', @@ -13,7 +15,7 @@ export default { flags: CommandFlags.Important, permissions: CommandPermissions.adminPlus(), - + expectedArgs: [ { name: 'action', type: { base: 'enum', options: [ 'rem', 'add', 'global-rem', 'global-add' ] }, @@ -34,17 +36,17 @@ export default { return api.log.replyError(api, "Masz problem", "Wszystko co nie jest globalne, wymaga użytkownika."); } - const forTime: string = + const forTime: string = action.startsWith('global') - ? `do ponownego uruchomienia bota` - : `do momentu usunięcia roli <@&${role}> przez adminów`; + ? `do ponownego uruchomienia bota` + : `do momentu usunięcia roli ${m.role(role)} przez adminów`; - const userName: string = + const userName: string = action.startsWith('global') ? `każdy użytkownik na serwerze` - : `użytkownik <@${user.id}>`; + : `użytkownik ${m.user(user)}`; - const generalText: string = + const generalText: string = action.includes('add') ? `będzie torturowany banem na GIFy ${forTime}` : 'będzie mógł cieszyć się brakiem bana na GIFy'; @@ -61,7 +63,7 @@ export default { cfg.features.automod.gifban.global = true; break; } - + return api.log.replySuccess( api, "Sukces guys!", `Od teraz ${userName} ${generalText}! To świetnie, wiem.` diff --git a/src/cmd/mod/kick.ts b/src/cmd/mod/kick.ts index b938680..10b57ae 100644 --- a/src/cmd/mod/kick.ts +++ b/src/cmd/mod/kick.ts @@ -3,10 +3,12 @@ import * as dsc from 'discord.js'; import { Command } from '@/bot/command.ts'; import { CommandFlags } from '@/bot/command/misc.ts'; import { PredefinedColors } from '@/util/color.ts'; -import kick from '@/apis/mod/kicks.ts'; import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; import { CommandPermissions } from '@/bot/command/permissions.ts'; +import kick from '@/apis/mod/kicks.ts'; +import m from '@/util/mentions.ts' + export default { name: 'kick', aliases: [], @@ -62,9 +64,9 @@ export default { .setTitle(`📢 ${targetUser.user.username} został wywalony!`) .setDescription(`Ukróciłem jego zagrania! Miejmy nadzieję, że nie wbije znowu...`) .addFields( - { name: 'Moderator', value: `<@${api.invoker.id}>`, inline: true }, - { name: 'Użytkownik', value: `<@${targetUser.id}>`, inline: true }, - { name: 'Powód', value: reason, inline: false }, + { name: 'Moderator', value: m.user(api.invoker), inline: true }, + { name: 'Użytkownik', value: m.user(targetUser), inline: true }, + { name: 'Powód', value: reason, inline: false }, ) .setColor(PredefinedColors.Orange), ], diff --git a/src/cmd/mod/mute.ts b/src/cmd/mod/mute.ts index 99999db..ed42382 100644 --- a/src/cmd/mod/mute.ts +++ b/src/cmd/mod/mute.ts @@ -6,6 +6,8 @@ import { PredefinedColors } from '@/util/color.ts'; import { Hour, Timestamp } from '@/util/parse-timestamp.ts'; import mute from '@/apis/mod/muting.ts'; +import m from '@/util/mentions.ts'; + import { watchMute } from '@/bot/watchdog.ts'; import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; import { CommandPermissions } from '@/bot/command/permissions.ts'; @@ -71,8 +73,8 @@ export default { .setTitle(`📢 Na ${targetUser.user.username} przymusowo nałożono kłódkę na buzię!`) .setDescription(`Ciekawe czy wyjdzie z serwera... A, racja! Mogłem tego nie mówić.`) .addFields( - { name: 'Moderator', value: `<@${api.invoker.id}>`, inline: true }, - { name: 'Użytkownik', value: `<@${targetUser.id}>`, inline: true }, + { name: 'Moderator', value: m.user(api.invoker.id), inline: true }, + { name: 'Użytkownik', value: m.user(targetUser.id), inline: true }, { name: 'Powód', value: reason }, { name: 'Czas', value: ``, inline: true }, ) diff --git a/src/cmd/mod/unmute.ts b/src/cmd/mod/unmute.ts index 1161b69..cab29d2 100644 --- a/src/cmd/mod/unmute.ts +++ b/src/cmd/mod/unmute.ts @@ -2,8 +2,10 @@ import { Command } from '@/bot/command.ts'; import { CommandFlags } from '@/bot/command/misc.ts'; import { CommandPermissions } from '@/bot/command/permissions.ts'; import { PredefinedColors } from '@/util/color.ts'; -import { sendLog } from '@/log/send-log.ts'; import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; +import { sendLog } from '@/log/send-log.ts'; + +import m from '@/util/mentions.ts'; export default { name: 'unmute', @@ -49,7 +51,7 @@ export default { sendLog({ title: 'Odciszono użytkownika', - description: `Użytkownik <@${targetUser.id}> został odciszony przez <@${api.invoker.id}>.`, + description: `Użytkownik ${m.user(targetUser)} został odciszony przez ${m.user(api.invoker)}.`, fields: [{ name: 'Powód', value: reason }], color: PredefinedColors.Pink, }); diff --git a/src/cmd/mod/warn-clear.ts b/src/cmd/mod/warn-clear.ts index 2822557..7e9079a 100644 --- a/src/cmd/mod/warn-clear.ts +++ b/src/cmd/mod/warn-clear.ts @@ -1,13 +1,16 @@ import { Command } from '@/bot/command.ts'; import { CommandFlags } from '@/bot/command/misc.ts'; -import { db } from '@/apis/db/bot-db.ts'; import { PredefinedColors } from '@/util/color.ts'; -import { output } from '@/bot/logging.ts'; -import { sendLog } from '@/log/send-log.ts'; import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; import { CommandPermissions } from '@/bot/command/permissions.ts'; import { WarnRaw } from '@/apis/db/db-defs.ts'; +import { db } from '@/apis/db/bot-db.ts'; +import { output } from '@/bot/logging.ts'; +import { sendLog } from '@/log/send-log.ts'; + +import m from '@/util/mentions.ts'; + export default { name: 'warn-clear', aliases: ['clearwarn', 'warnusun'], @@ -56,15 +59,9 @@ export default { title: 'Pozbyto się warna!', description: `Usunięto warna o ID \`${warnId}\`.`, fields: [ - { - name: 'Powód', value: row.reason_string - }, - { - name: 'Dla', value: `<@${row.user_id}>`, inline: true - }, - { - name: 'Od', value: `<@${row.moderator_id}>`, inline: true - } + { name: 'Powód', value: row.reason_string, inline: false }, + { name: 'Dla', value: m.user(row.user_id), inline: true }, + { name: 'Od', value: m.user(row.moderator_id), inline: true }, ] }); @@ -75,15 +72,9 @@ export default { .setTitle(':white_check_mark: Warn usunięty') .setDescription(`Warn o ID \`${warnId}\` został pomyślnie usunięty.`) .addFields([ - { - name: 'Powód', value: row.reason_string - }, - { - name: 'Dla', value: `<@${row.user_id}>` - }, - { - name: 'Od', value: `<@${row.moderator_id}>` - } + { name: 'Powód', value: row.reason_string }, + { name: 'Dla', value: m.user(row.user_id) }, + { name: 'Od', value: m.user(row.moderator_id) }, ]) .setColor(PredefinedColors.Green), ], diff --git a/src/cmd/mod/warn.ts b/src/cmd/mod/warn.ts index 8d5e215..cce0c98 100644 --- a/src/cmd/mod/warn.ts +++ b/src/cmd/mod/warn.ts @@ -1,15 +1,17 @@ +import * as dsc from 'discord.js'; + import { Command } from '@/bot/command.ts'; import { CommandFlags } from '@/bot/command/misc.ts'; import { CommandPermissions } from '@/bot/command/permissions.ts'; import { PredefinedColors } from '@/util/color.ts'; -import * as dsc from 'discord.js'; - -import warn from '@/apis/mod/warns.ts'; import parseTimestamp, { Timestamp } from '@/util/parse-timestamp.ts'; -import clamp from '@/util/math/clamp.ts'; import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; +import clamp from '@/util/math/clamp.ts'; +import warn from '@/apis/mod/warns.ts'; +import m from '@/util/mentions.ts'; + export default { name: 'warn', aliases: [], @@ -93,10 +95,10 @@ export default { .setTitle(`📢 Masz warna, ${targetUser.user.username}!`) .setDescription(`Właśnie dostałeś darmoweeego warna (punktów: ${points})!`) .addFields( - { name: 'Moderator', value: `<@${api.invoker.id}>`, inline: true }, - { name: 'Użytkownik', value: `<@${targetUser.id}>`, inline: true }, - { name: 'Powód', value: reason, inline: false }, - { name: 'Punkty', value: points.toString(), inline: true }, + { name: 'Moderator', value: m.user(api.invoker.id), inline: true }, + { name: 'Użytkownik', value: m.user(targetUser.id), inline: true }, + { name: 'Powód', value: reason, inline: false }, + { name: 'Punkty', value: points.toString(), inline: true }, ) .setColor(PredefinedColors.Orange); @@ -106,4 +108,4 @@ export default { await api.reply({ embeds: [embed] }); }, -} satisfies Command; \ No newline at end of file +} satisfies Command; diff --git a/src/cmd/mod/warnlist.ts b/src/cmd/mod/warnlist.ts index 2cb6e26..a19be6a 100644 --- a/src/cmd/mod/warnlist.ts +++ b/src/cmd/mod/warnlist.ts @@ -1,11 +1,15 @@ +import * as dsc from 'discord.js'; + import { Command } from '@/bot/command.ts'; import { CommandFlags } from '@/bot/command/misc.ts'; -import { db, WarnRaw } from '@/apis/db/bot-db.ts'; -import * as dsc from 'discord.js'; import { PredefinedColors } from '@/util/color.ts'; -import { client as cl } from '../../client.ts'; import { CommandPermissions } from '@/bot/command/permissions.ts'; + +import { client } from '@/client.ts'; +import { db, WarnRaw } from '@/apis/db/bot-db.ts'; + import User from '@/apis/db/user.ts'; +import m from '@/util/mentions.ts'; export default { name: 'warnlist', @@ -28,7 +32,6 @@ export default { permissions: CommandPermissions.everyone(), async execute(api) { - const client: dsc.Client = cl; const guild: dsc.Guild = api.guild!; const targetUser = api.getTypedArg('user', 'user-mention')?.value as dsc.GuildMember | undefined; @@ -65,7 +68,7 @@ export default { const moderator = row.moderator_id ? await guild.members.fetch(row.moderator_id).catch(() => null) : null; let value = `\`${row.reason_string}\`\nWarn #${row.id}, punktów: \`${row.points}\` `; - if (moderator) value += `, od <@${moderator.id}>`; + if (moderator) value += `, od ${m.user(moderator)}`; if (row.expires_at) value += ` (wygasa )`; fields.push({ @@ -131,4 +134,4 @@ export default { await msg.edit({ components: [] }).catch(() => {}); }); }, -} satisfies Command; \ No newline at end of file +} satisfies Command; diff --git a/src/features/4fun/ask.ts b/src/features/4fun/ask.ts index 0682d73..f43ec56 100644 --- a/src/features/4fun/ask.ts +++ b/src/features/4fun/ask.ts @@ -1,4 +1,5 @@ import { MessageEventCtx, PredefinedActionEventTypes } from '../actions.ts'; +import { MessageType } from 'discord.js'; import { executeAsk } from '@/features/ei/ask.ts'; @@ -6,7 +7,7 @@ import { Action } from '../actions.ts'; import { client } from '@/client.ts'; import { cfg } from '@/bot/cfg.ts'; -import { MessageType } from 'discord.js'; +import m from '@/util/mentions.ts'; export const askAction: Action = { name: '4fun/ask', @@ -18,7 +19,7 @@ export const askAction: Action = { const referenced = typeof ctx.reference?.messageId == 'string' && typeof ctx.reference?.guildId == 'string' && !ctx.flags.has('HasSnapshot') ? await ctx.fetchReference() : false; - return ctx.content.trim().startsWith(`<@${client.user?.id}>`) || + return ctx.content.trim().startsWith(`${client.user?.id}>`) || (referenced ? ( referenced.author.id == client.user?.id && @@ -37,7 +38,11 @@ export const askAction: Action = { callbacks: [ (msg) => { - const question = msg.content.trim().startsWith(`<@${client.user!.id}>`) ? msg.content.trim().replace(`<@${client.user!.id}>`, '') : msg.content; + const question = + msg.content.trim().startsWith(m.user(client.user!)) + ? msg.content.trim().replace(m.user(client.user!), '') + : msg.content; + return executeAsk(msg, question, cfg.features.ai.contextDefaultMessages); }, ], diff --git a/src/features/4fun/ping-dead-chat.ts b/src/features/4fun/ping-dead-chat.ts index fa0f153..326da90 100644 --- a/src/features/4fun/ping-dead-chat.ts +++ b/src/features/4fun/ping-dead-chat.ts @@ -6,6 +6,8 @@ import { cfg } from '@/bot/cfg.ts'; import { Hour } from '@/util/parse-timestamp.ts'; import { db } from '@/apis/db/bot-db.ts'; +import m from '@/util/mentions.ts'; + let deadChatTimeout: ReturnType; const DEAD_CHAT_ROLE_ID = '1511009335877046364'; @@ -68,7 +70,7 @@ export const actionPing: Action = { if (!msg.channel.isSendable()) return; if (await db.deadchat.count() == DeadChatQuestions.length) { - await msg.channel.send(`${cfg.hierarchy.developers.allowedUsers.map(id => `<@${id}>`).join(', ')} pytania się wam skończyły`); + await msg.channel.send(`${cfg.hierarchy.developers.allowedUsers.map(m.role).join(', ')} pytania się wam skończyły`); return; } @@ -90,7 +92,7 @@ export const actionPing: Action = { } while (await db.deadchat.had(question)); await db.deadchat.add(question); - msg.channel.send(`<@&${DEAD_CHAT_ROLE_ID}> ${capitalizeFirst(question)}${question.endsWith('?') ? '' : '?'}`); + msg.channel.send(`${m.role(DEAD_CHAT_ROLE_ID)} ${capitalizeFirst(question)}${question.endsWith('?') ? '' : '?'}`); } }, DEAD_CHAT_AUTO_WAIT_INTERVAL * 1000); }, diff --git a/src/features/mod/automod.ts b/src/features/mod/automod.ts index 871a635..030494b 100644 --- a/src/features/mod/automod.ts +++ b/src/features/mod/automod.ts @@ -5,6 +5,8 @@ import { mkAutoreplyAction } from '../autoreply.ts'; import { cfg } from '@/bot/cfg.ts'; import { client } from '@/client.ts'; +import m from '@/util/mentions.ts'; + export default class AutoModRules { static readonly msgAuthorIsNotImmuneToAutomod = (msg: MessageEventCtx) => { for (const role of [...cfg.hierarchy.automodBypassRoles, cfg.hierarchy.administration.headAdmin]) { @@ -21,7 +23,7 @@ export default class AutoModRules { { type: 'contains', keyword: '@here' }, { type: 'contains', keyword: 'małpa here' }, ], - reply: (msg) => `Upomnienie dla <@${msg.author.id}> za próbe pingu everyone!!11!1@!!`, + reply: (msg) => `Upomnienie dla ${m.user(msg.author)} za próbe pingu everyone!!11!1@!!`, additionalConstraints: [AutoModRules.msgAuthorIsNotImmuneToAutomod], additionalCallbacks: [PredefinedActionCallbacks.deleteMsgAutomod], }); @@ -37,7 +39,7 @@ export default class AutoModRules { keyword: '(?:discord\\.gg|discord\\.com\\/invite)\\/[A-Za-z0-9]{4,}', }, ], - reply: (msg) => `<@${msg.author.id}> ładnie proszę, wypier*alaj ze swoją reklamą na serwery reklamowe ;)'`, + reply: (msg) => `${m.user(msg.author)} ładnie proszę, wypier*alaj ze swoją reklamą na serwery reklamowe ;)'`, additionalCallbacks: [PredefinedActionCallbacks.deleteMsgAutomod], additionalConstraints: [AutoModRules.msgAuthorIsNotImmuneToAutomod, (ctx) => !(ctx.channel.isThread() && ctx.channel.parentId == '1510999452192866485')], }); diff --git a/src/features/mod/honeypot.ts b/src/features/mod/honeypot.ts index 8a83c27..fb714c6 100644 --- a/src/features/mod/honeypot.ts +++ b/src/features/mod/honeypot.ts @@ -1,13 +1,16 @@ import { PredefinedActionEventTypes, type Action, type MessageEventCtx } from '@/features/actions.ts'; -import AutoModRules from '@/features/mod/automod.ts'; -import { cfg } from '@/bot/cfg.ts'; import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; import { PredefinedColors } from '@/util/color.ts'; +import { GuildTextBasedChannel } from 'discord.js'; + import { sendLog } from '@/log/send-log.ts'; -import warn from '@/apis/mod/warns.ts'; import { mkMessageReferenceEmbed } from '@/bot/templates/message-reference.ts'; import { client } from '@/client.ts'; -import { GuildTextBasedChannel } from 'discord.js'; +import { cfg } from '@/bot/cfg.ts'; + +import AutoModRules from '@/features/mod/automod.ts'; +import warn from '@/apis/mod/warns.ts'; +import m from '@/util/mentions.ts'; async function internal() { const channel = await client.channels.fetch(cfg.channels.important.honeypot) as GuildTextBasedChannel; @@ -18,7 +21,7 @@ async function internal() { .setDescription([ '# NIE WYSYŁAJ WIADOMOŚCI NA TYM KANALE', 'Ten kanał jest używany by łapać boty. Pisanie tutaj skończy się **natychmiastowym mute na 24 godziny**!', - `Zamiast tego, napisz na <#${cfg.channels.general.general}> lub <#${cfg.channels.general.programming}>.` + `Zamiast tego, napisz na ${m.chan(cfg.channels.general.general)} lub ${m.chan(cfg.channels.general.programming)}.` ].join('\n')) ] }); @@ -65,8 +68,8 @@ export default function setupHoneypotAction() { sendLog({ title: 'Kolejny spam-bot wysłał coś na honeypocie', fields: [ - { name: 'Użytkownik', value: `<@${msg.member!.id}>`, inline: true }, - { name: 'Wysłano DM', value: dmSendSuccessfull ? 'Tak' : 'Nie', inline: true } + { name: 'Użytkownik', value: m.user(msg.member!), inline: true }, + { name: 'Wysłano DM', value: dmSendSuccessfull ? 'Tak' : 'Nie', inline: true }, ], color: PredefinedColors.Red, description: 'W skrócie to ten user dostał mute na 24 godziny za trigerrnięcie tego, trzeba było tak nie robić ig.', diff --git a/src/features/mod/polls-mod.ts b/src/features/mod/polls-mod.ts index 7559e1b..b630f6c 100644 --- a/src/features/mod/polls-mod.ts +++ b/src/features/mod/polls-mod.ts @@ -4,6 +4,7 @@ import { replyWarn } from '@/util/log.ts'; import randomElement from '@/util/random-element.ts'; import sleep from '@/util/sleep.ts'; +import m from '@/util/mentions.ts'; const ThreadNames = [ 'Kanał commentary na YT', @@ -47,12 +48,12 @@ export const pollsModerator: Action = { Date.now() - lastMessage.createdTimestamp >= 30 * 60 * 1000 ) { await msg.channel.send( - `${msg.poll?.question.text ?? 'nowa ankieta guys! ^^^'} <@&1511009438994141194>` + `${msg.poll?.question.text ?? 'nowa ankieta guys! ^^^'} ${m.role('1511009438994141194')}` ); } const thread = await msg.startThread({ - name: + name: (msg.poll?.question.text ?? randomElement(ThreadNames)) .slice(0, 100), reason: 'yes bum bum bum bum' diff --git a/src/features/others/welcomer.ts b/src/features/others/welcomer.ts index e4276ad..24efad0 100644 --- a/src/features/others/welcomer.ts +++ b/src/features/others/welcomer.ts @@ -8,6 +8,7 @@ import { watchNewMember } from '@/bot/watchdog.ts'; import { output } from '@/bot/logging.ts'; import randomElement from '@/util/random-element.ts'; +import m from '@/util/mentions.ts'; const StartItId = '572906387382861835'; @@ -25,7 +26,7 @@ export const welcomeNewUserAction: Action = { try { await member.roles.add(role); } catch { - output.warn("welcomer: can't apply role <@&" + role + '> to <@' + member.id + '>'); + output.warn(`welcomer: can't apply role ${m.role(role)} to ${m.user(member)}`); } } @@ -41,10 +42,10 @@ export const welcomeNewUserAction: Action = { } else { await welcomeChannel.send({ content: '<:join:1510910009368641667>' + - randomElement(cfg.features.welcomer.welcomeMsgs).replace('', `<@${member.user.id}>`), + randomElement(cfg.features.welcomer.welcomeMsgs).replace('', m.user(member.user)), allowedMentions: cfg.features.welcomer.mentionNewPeopleInLobby ? {} : { parse: [] }, }); - await generalChannel.send(`witaj <@${member.user.id}>, będzie nam miło jak się przywitasz czy coś <:emoji_a_radosci_nie_bylo_konca:1510697737920839680>`); + await generalChannel.send(`witaj ${m.user(member.user)}, będzie nam miło jak się przywitasz czy coś <:emoji_a_radosci_nie_bylo_konca:1510697737920839680>`); } }, ], @@ -68,7 +69,7 @@ export const sayGoodbyeAction: Action = { await channel.send({ content: '<:leave:1510910039777345576>' + - randomElement(cfg.features.welcomer.goodbyeMsgs).replace('', `<@${member.user.id}> (${member.user.username})`), + randomElement(cfg.features.welcomer.goodbyeMsgs).replace('', `${m.user(member.user)} (${member.user.username})`), allowedMentions: cfg.features.welcomer.mentionNewPeopleInLobby ? {} : { parse: [] }, }); }, diff --git a/src/features/reminders.ts b/src/features/reminders.ts index 9f03454..d2024e0 100644 --- a/src/features/reminders.ts +++ b/src/features/reminders.ts @@ -1,11 +1,14 @@ -import logError from '@/util/log-error.ts'; -import { client } from '@/client.ts'; -import { cfg } from '@/bot/cfg.ts'; -import { db } from '@/apis/db/bot-db.ts'; import { GuildTextBasedChannel } from 'discord.js'; import { ReplyEmbed } from '@/apis/translations/reply-embed.ts'; import { PredefinedColors } from '@/util/color.ts'; +import { client } from '@/client.ts'; +import { cfg } from '@/bot/cfg.ts'; +import { db } from '@/apis/db/bot-db.ts'; + +import logError from '@/util/log-error.ts'; +import m from '@/util/mentions.ts'; + export async function reminderHandler() { try { const general = await client.channels.fetch(cfg.channels.general.general) as GuildTextBasedChannel; @@ -26,7 +29,7 @@ export async function reminderHandler() { ) .setColor(PredefinedColors.Gold) ], - content: `<@${reminder.for_user}>` + content: m.user(reminder.for_user), }); await db.reminders.deleteReminder(reminder.id); } diff --git a/src/util/mentions.ts b/src/util/mentions.ts new file mode 100644 index 0000000..4b23982 --- /dev/null +++ b/src/util/mentions.ts @@ -0,0 +1,51 @@ +import * as dsc from 'discord.js'; +import * as config from '@/bot/config/schema.ts'; + +import { CommandAPI } from '@/bot/command.ts'; +import User from '@/apis/db/user.ts'; + +export type UserIdResolvable = dsc.Snowflake | dsc.User | dsc.GuildMember | CommandAPI['invoker'] | User; +export type RoleIdResolvable = dsc.Snowflake | dsc.Role | config.economy.Role; +export type ChanIdResolvable = dsc.Snowflake | dsc.BaseChannel; + +function mentionUser(user: UserIdResolvable): dsc.UserMention { + const id: string = + user instanceof dsc.User || user instanceof User + ? user.id + : user instanceof dsc.GuildMember + ? user.user.id + : typeof user == 'object' && 'id' in user + ? user.id + : user; + + return `<@${id}>`; +} + +function mentionRole(role: RoleIdResolvable): dsc.RoleMention { + const id: string = + role instanceof dsc.Role + ? role.id + : typeof role == 'object' && 'discordRoleId' in role + ? role.discordRoleId + : role; + + return `<@&${id}>`; +} + +function mentionChannel(chan: ChanIdResolvable): dsc.ChannelMention { + const id: string = + chan instanceof dsc.BaseChannel + ? chan.id + : chan; + + return `<#${id}>`; +} + +const m = { + user: mentionUser, + role: mentionRole, + chan: mentionChannel, +} as const; + +export default m; +