Compare commits
5 commits
archive-re
...
main
Author | SHA1 | Date | |
---|---|---|---|
088693d2d2 | |||
929312e0ed | |||
e4d1e307df | |||
767612a000 | |||
23d3918459 |
26 changed files with 1273 additions and 268 deletions
1217
package-lock.json
generated
1217
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -19,12 +19,13 @@
|
|||
"dependencies": {
|
||||
"@discord-player/extractor": "^4.5.1",
|
||||
"@discordjs/rest": "^2.4.0",
|
||||
"@distube/ytdl-core": "^4.14.4",
|
||||
"@types/sqlite3": "^3.1.11",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"discord-player": "^6.7.1",
|
||||
"discord-player-youtubei": "^1.3.1",
|
||||
"discord.js": "^14.16.2",
|
||||
"mediaplex": "^0.0.9",
|
||||
"puppeteer": "^23.4.0",
|
||||
"sqlite3": "^5.1.7",
|
||||
"typescript": "^5.6.2",
|
||||
"uuid": "^10.0.0"
|
||||
|
|
|
@ -10,9 +10,9 @@ import { getLocale } from "../utils/locales";
|
|||
|
||||
export default async (client: Client) => {
|
||||
// Dossier des buttons
|
||||
const buttons_categories = (await readdir(__dirname)).filter(
|
||||
(element) => !element.endsWith(".js") && !element.endsWith(".ts"),
|
||||
);
|
||||
const buttons_categories = (await readdir(__dirname, { withFileTypes: true }))
|
||||
.filter((element) => element.isDirectory())
|
||||
.map((element) => element.name);
|
||||
|
||||
await Promise.all(
|
||||
// For each categorie
|
||||
|
|
|
@ -4,7 +4,6 @@ import {
|
|||
ButtonStyle,
|
||||
Client,
|
||||
MessageComponentInteraction,
|
||||
User,
|
||||
} from "discord.js";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { getLocale } from "../../utils/locales";
|
||||
|
@ -18,11 +17,11 @@ export default {
|
|||
},
|
||||
interaction: async (interaction: MessageComponentInteraction, client: Client) => {
|
||||
const loc = getLocale(client, interaction.locale);
|
||||
const embed_desc = interaction.message.embeds.at(0)?.description as string;
|
||||
const embed_desc = interaction.message.embeds.at(0)?.description;
|
||||
|
||||
// Retrieve Pages
|
||||
const pageMax = Number(/(\d+)(?!.*\d)/gm.exec(embed_desc)?.[0]);
|
||||
let page = Number(/(?!• \s+)\d(?=\/)/gm.exec(embed_desc)?.[0]);
|
||||
const pageMax = Number(/(\d+)(?!.*\d)/gm.exec(embed_desc!)?.[0]);
|
||||
let page = Number(/(?!• \s+)\d(?=\/)/gm.exec(embed_desc!)?.[0]);
|
||||
if (page + 1 > pageMax) {
|
||||
page = 1;
|
||||
} else {
|
||||
|
@ -30,8 +29,8 @@ export default {
|
|||
}
|
||||
|
||||
// Retrieve user
|
||||
const userId = /(?!<@)\d+(?=>)/gm.exec(embed_desc)?.[0] as string;
|
||||
const user = client.users.cache.get(userId) as User;
|
||||
const userId = /(?!<@)\d+(?=>)/gm.exec(embed_desc!)?.[0];
|
||||
const user = client.users.cache.get(userId!)!;
|
||||
|
||||
// Fetch list
|
||||
const list = await embedListReminders(
|
||||
|
|
|
@ -4,7 +4,6 @@ import {
|
|||
ButtonStyle,
|
||||
Client,
|
||||
MessageComponentInteraction,
|
||||
User,
|
||||
} from "discord.js";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { getLocale } from "../../utils/locales";
|
||||
|
@ -18,20 +17,20 @@ export default {
|
|||
},
|
||||
interaction: async (interaction: MessageComponentInteraction, client: Client) => {
|
||||
const loc = getLocale(client, interaction.locale);
|
||||
const embed_desc = interaction.message.embeds.at(0)?.description as string;
|
||||
const embed_desc = interaction.message.embeds.at(0)?.description;
|
||||
|
||||
// Retrieve Pages
|
||||
const pageMax = Number(/(\d+)(?!.*\d)/gm.exec(embed_desc)?.[0]);
|
||||
let page = Number(/(?!• \s+)\d(?=\/)/gm.exec(embed_desc)?.[0]);
|
||||
if (page - 1 == 0) {
|
||||
const pageMax = Number(/(\d+)(?!.*\d)/gm.exec(embed_desc!)?.[0]);
|
||||
let page = Number(/(?!• \s+)\d(?=\/)/gm.exec(embed_desc!)?.[0]);
|
||||
if (page - 1 === 0) {
|
||||
page = pageMax;
|
||||
} else {
|
||||
page--;
|
||||
}
|
||||
|
||||
// Retrieve user
|
||||
const userId = /(?!<@)\d+(?=>)/gm.exec(embed_desc)?.[0] as string;
|
||||
const user = client.users.cache.get(userId) as User;
|
||||
const userId = /(?!<@)\d+(?=>)/gm.exec(embed_desc!)?.[0];
|
||||
const user = client.users.cache.get(userId!)!;
|
||||
|
||||
// Fetch list
|
||||
const list = await embedListReminders(
|
||||
|
|
|
@ -19,11 +19,11 @@ export default {
|
|||
},
|
||||
interaction: async (interaction: MessageComponentInteraction, client: Client) => {
|
||||
const loc = getLocale(client, interaction.locale);
|
||||
const embed_desc = interaction.message.embeds.at(0)?.author?.name as string;
|
||||
const embed_desc = interaction.message.embeds.at(0)?.author?.name;
|
||||
|
||||
// Retrieve Pages
|
||||
const pageMax = Number(/(\d+)(?!.*\d)/gm.exec(embed_desc)?.[0]);
|
||||
let page = Number(/(?!• \s+)\d(?=\/)/gm.exec(embed_desc)?.[0]);
|
||||
const pageMax = Number(/(\d+)(?!.*\d)/gm.exec(embed_desc!)?.[0]);
|
||||
let page = Number(/(?!• \s+)\d(?=\/)/gm.exec(embed_desc!)?.[0]);
|
||||
if (page + 1 > pageMax) {
|
||||
page = 1;
|
||||
} else {
|
||||
|
|
|
@ -24,7 +24,7 @@ export default {
|
|||
// Retrieve Pages
|
||||
const pageMax = Number(/(\d+)(?!.*\d)/gm.exec(embed_desc)?.[0]);
|
||||
let page = Number(/(?!• \s+)\d(?=\/)/gm.exec(embed_desc)?.[0]);
|
||||
if (page - 1 == 0) {
|
||||
if (page - 1 === 0) {
|
||||
page = pageMax;
|
||||
} else {
|
||||
page--;
|
||||
|
|
|
@ -8,9 +8,9 @@ import { removeExtension } from "../utils/misc";
|
|||
export default async (client: Client) => {
|
||||
const rest = new REST({ version: "10" }).setToken(client.token!);
|
||||
|
||||
const command_categories = (await readdir(__dirname)).filter(
|
||||
(element) => !element.endsWith(".js") && !element.endsWith(".ts"),
|
||||
);
|
||||
const command_categories = (await readdir(__dirname, { withFileTypes: true }))
|
||||
.filter((element) => element.isDirectory())
|
||||
.map((element) => element.name);
|
||||
|
||||
const commands = (
|
||||
await Promise.all(
|
||||
|
@ -70,7 +70,7 @@ export default async (client: Client) => {
|
|||
);
|
||||
|
||||
// Send global commands to Discord
|
||||
const globalCommands = commands.filter((c) => c.scope().length == 0);
|
||||
const globalCommands = commands.filter((c) => c.scope().length === 0);
|
||||
return await rest.put(Routes.applicationCommands(client.user?.id as string), {
|
||||
body: globalCommands.map((c) => c.data.toJSON()),
|
||||
});
|
||||
|
|
|
@ -74,14 +74,14 @@ export default {
|
|||
allChannel?.then(async (channelGuild) => {
|
||||
// Retrieve category to archive
|
||||
const catToArchive = channelGuild
|
||||
.filter((chan) => chan?.type == ChannelType.GuildCategory)
|
||||
.filter((chan) => chan?.name == desiredCat);
|
||||
.filter((chan) => chan?.type === ChannelType.GuildCategory)
|
||||
.filter((chan) => chan?.name === desiredCat);
|
||||
|
||||
// Create/Retrieve the archive category
|
||||
const catArchivedName = "archive - " + desiredCat;
|
||||
const catArchivedMap = channelGuild
|
||||
.filter((chan) => chan?.type == ChannelType.GuildCategory)
|
||||
.filter((chan) => chan?.name == catArchivedName);
|
||||
.filter((chan) => chan?.type === ChannelType.GuildCategory)
|
||||
.filter((chan) => chan?.name === catArchivedName);
|
||||
|
||||
let catArchived: NonThreadGuildBasedChannel | null | undefined;
|
||||
if (catArchivedMap.size > 0) {
|
||||
|
@ -94,11 +94,11 @@ export default {
|
|||
}
|
||||
|
||||
const allChannelDesired = channelGuild
|
||||
.filter((chan) => chan?.type == 0)
|
||||
.filter((chan) => chan?.parentId == catToArchive.map((cat) => cat?.id)[0]);
|
||||
.filter((chan) => chan?.type === 0)
|
||||
.filter((chan) => chan?.parentId === catToArchive.map((cat) => cat?.id)[0]);
|
||||
|
||||
// If no channels in the source category
|
||||
if (allChannelDesired.size == 0) {
|
||||
if (allChannelDesired.size === 0) {
|
||||
return interaction.reply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { Locale } from "discord-api-types/v9";
|
||||
import { ChatInputCommandInteraction, Client, Colors, EmbedBuilder } from "discord.js";
|
||||
import "../../modules/string";
|
||||
import { getLocale, getLocalizations } from "../../utils/locales";
|
||||
|
@ -93,7 +92,7 @@ export default {
|
|||
.setDescription(
|
||||
// Loads the description
|
||||
// according to the user's locals
|
||||
command.data.description_localizations?.[interaction.locale as Locale] ??
|
||||
command.data.description_localizations?.[interaction.locale] ??
|
||||
command.data.description,
|
||||
),
|
||||
],
|
||||
|
|
|
@ -67,21 +67,21 @@ export default {
|
|||
const allChannel = interaction.guild?.channels.fetch();
|
||||
allChannel?.then((channel_guild) => {
|
||||
const cat_to_prep = channel_guild
|
||||
.filter((chan) => chan?.type == ChannelType.GuildCategory)
|
||||
.filter((chan) => chan?.name == desired_cat);
|
||||
.filter((chan) => chan?.type === ChannelType.GuildCategory)
|
||||
.filter((chan) => chan?.name === desired_cat);
|
||||
const cat_to_prep_id = cat_to_prep.map((cat) => cat?.id);
|
||||
const cat_to_prep_name = cat_to_prep.map((cat) => cat?.name);
|
||||
|
||||
// console.log(cat_to_prep);
|
||||
const all_channel_desired = channel_guild
|
||||
.filter((chan) => chan?.type == 0)
|
||||
.filter((chan) => chan?.parentId == cat_to_prep_id[0]);
|
||||
.filter((chan) => chan?.type === 0)
|
||||
.filter((chan) => chan?.parentId === cat_to_prep_id[0]);
|
||||
const all_channel_desired_name = all_channel_desired.map((c_d) => c_d?.name);
|
||||
|
||||
let desc = "";
|
||||
|
||||
const general = "général";
|
||||
if (all_channel_desired_name.filter((cdn) => cdn == general).length == 0) {
|
||||
if (all_channel_desired_name.filter((cdn) => cdn === general).length === 0) {
|
||||
interaction.guild?.channels.create({
|
||||
name: general,
|
||||
type: 0,
|
||||
|
@ -91,7 +91,7 @@ export default {
|
|||
}
|
||||
|
||||
const info = "informations";
|
||||
if (all_channel_desired_name.filter((cdn) => cdn == info).length == 0) {
|
||||
if (all_channel_desired_name.filter((cdn) => cdn === info).length === 0) {
|
||||
interaction.guild?.channels.create({
|
||||
name: info,
|
||||
type: 0,
|
||||
|
@ -101,7 +101,7 @@ export default {
|
|||
desc += "`" + info + "` " + loc.get("c_prep5") + "\n";
|
||||
}
|
||||
|
||||
if (desc == "") {
|
||||
if (desc === "") {
|
||||
desc = loc.get("c_prep6");
|
||||
}
|
||||
|
||||
|
|
|
@ -158,12 +158,19 @@ export default {
|
|||
channelId: interaction.channelId,
|
||||
userId: interaction.user.id,
|
||||
guildId: interaction.guildId,
|
||||
}).then((msg) =>
|
||||
interaction.reply({
|
||||
content: msg as string,
|
||||
ephemeral: true,
|
||||
}),
|
||||
);
|
||||
})
|
||||
.then((msg) =>
|
||||
interaction.reply({
|
||||
content: msg as string,
|
||||
ephemeral: true,
|
||||
}),
|
||||
)
|
||||
.catch((err) => {
|
||||
interaction.reply({
|
||||
content: err,
|
||||
ephemeral: true,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Show modal to user to get at least the time
|
||||
const modal = new ModalBuilder()
|
||||
|
@ -198,7 +205,7 @@ export default {
|
|||
let user = interaction.options.getUser(
|
||||
loc_default?.get(`c_${filename}_sub2_opt1_name`) as string,
|
||||
);
|
||||
if (user == null) {
|
||||
if (user === null) {
|
||||
user = interaction.user;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { Player, useMainPlayer, useQueue } from "discord-player";
|
||||
import { useMainPlayer, useQueue } from "discord-player";
|
||||
import { ChatInputCommandInteraction, Client, EmbedBuilder } from "discord.js";
|
||||
import { getLocale, getLocalizations } from "../../utils/locales";
|
||||
import { getFilename } from "../../utils/misc";
|
||||
|
@ -81,11 +81,11 @@ export default {
|
|||
let data = null;
|
||||
await interaction.deferReply();
|
||||
|
||||
const player = useMainPlayer() as Player;
|
||||
const player = useMainPlayer();
|
||||
const queue = useQueue(interaction.guildId!);
|
||||
if (request) {
|
||||
if (
|
||||
interaction.options.getSubcommand() ==
|
||||
interaction.options.getSubcommand() ===
|
||||
loc_default?.get(`c_${filename}_sub2_name`)?.toLowerCase()
|
||||
) {
|
||||
// Romanized
|
||||
|
@ -111,7 +111,7 @@ export default {
|
|||
}
|
||||
|
||||
if (
|
||||
interaction.options.getSubcommand() ==
|
||||
interaction.options.getSubcommand() ===
|
||||
loc_default?.get(`c_${filename}_sub3_name`)?.toLowerCase()
|
||||
) {
|
||||
if (queue === null) {
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { Player, SearchResult, useMainPlayer, useQueue } from "discord-player";
|
||||
import { SearchResult, useMainPlayer, useQueue } from "discord-player";
|
||||
import {
|
||||
AutocompleteInteraction,
|
||||
ChatInputCommandInteraction,
|
||||
Client,
|
||||
EmbedBuilder,
|
||||
GuildResolvable,
|
||||
VoiceBasedChannel,
|
||||
} from "discord.js";
|
||||
import { getLocale, getLocalizations } from "../../utils/locales";
|
||||
import { Metadata } from "../../utils/metadata";
|
||||
|
@ -71,7 +69,7 @@ export default {
|
|||
loc_default?.get(`c_${filename}_opt1_name`) as string,
|
||||
);
|
||||
|
||||
const player = useMainPlayer() as Player;
|
||||
const player = useMainPlayer();
|
||||
if (!query) {
|
||||
// Now playing
|
||||
|
||||
|
@ -97,7 +95,7 @@ export default {
|
|||
return await interaction.reply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
const queue = player.nodes.create(interaction.guild as GuildResolvable, {
|
||||
const queue = player.nodes.create(interaction.guild!, {
|
||||
defaultFFmpegFilters: ["silenceremove"],
|
||||
metadata: {
|
||||
channel: interaction.channel,
|
||||
|
@ -106,7 +104,7 @@ export default {
|
|||
|
||||
// Verify vc connection
|
||||
try {
|
||||
if (!queue.connection) await queue.connect(member.voice.channel as VoiceBasedChannel);
|
||||
if (!queue.connection) await queue.connect(member.voice.channel!);
|
||||
} catch {
|
||||
queue.delete();
|
||||
return await interaction.reply({
|
||||
|
@ -155,7 +153,7 @@ export default {
|
|||
const loc_default = interaction.client.locales.get(interaction.client.config.default_lang);
|
||||
const filename = getFilename(__filename);
|
||||
|
||||
const player = useMainPlayer() as Player;
|
||||
const player = useMainPlayer();
|
||||
const query = interaction.options.getString(
|
||||
loc_default?.get(`c_${filename}_opt1_name`) as string,
|
||||
true,
|
||||
|
|
|
@ -153,7 +153,7 @@ export default {
|
|||
case loc_default?.get(`c_${filename}_sub3_name`)?.toLowerCase(): {
|
||||
const id = interaction.options.getNumber(
|
||||
loc_default?.get(`c_${filename}_sub3_opt1_name`) as string,
|
||||
) as number;
|
||||
)!;
|
||||
|
||||
const track = queue.removeTrack(id - 1);
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||
import { Player, useMainPlayer } from "discord-player";
|
||||
import { ChatInputCommandInteraction, Client, GuildResolvable } from "discord.js";
|
||||
import { useMainPlayer } from "discord-player";
|
||||
import { ChatInputCommandInteraction, Client } from "discord.js";
|
||||
import { getLocale, getLocalizations } from "../../utils/locales";
|
||||
import { Metadata } from "../../utils/metadata";
|
||||
import { getFilename } from "../../utils/misc";
|
||||
|
||||
export default {
|
||||
|
@ -25,11 +24,11 @@ export default {
|
|||
interaction: async (interaction: ChatInputCommandInteraction, client: Client) => {
|
||||
const loc = getLocale(client, interaction.locale);
|
||||
|
||||
const player = useMainPlayer() as Player;
|
||||
const queue = player.nodes.create(interaction.guild as GuildResolvable, {
|
||||
const player = useMainPlayer();
|
||||
const queue = player.nodes.create(interaction.guild!, {
|
||||
metadata: {
|
||||
channel: interaction.channel,
|
||||
} as Metadata,
|
||||
},
|
||||
});
|
||||
|
||||
if (!(queue.connection || queue.node.isPlaying())) {
|
||||
|
|
|
@ -1,12 +1,37 @@
|
|||
import { Player, PlayerEvents, useMainPlayer } from "discord-player";
|
||||
import { PlayerEvents, useMainPlayer } from "discord-player";
|
||||
import { Client } from "discord.js";
|
||||
import { readdir } from "fs/promises";
|
||||
import { splitFilenameExtensions } from "../utils/misc";
|
||||
|
||||
/** Load all the events */
|
||||
export default async (client: Client) => {
|
||||
const events_categories = (await readdir(__dirname)).filter(
|
||||
(element) => !element.endsWith(".js") && !element.endsWith(".ts"),
|
||||
);
|
||||
export default async (client: Client, isDev: boolean) => {
|
||||
const events_categories = (await readdir(__dirname, { withFileTypes: true }))
|
||||
.filter((element) => element.isDirectory())
|
||||
.map((element) => element.name);
|
||||
|
||||
const player = useMainPlayer();
|
||||
|
||||
if (isDev) {
|
||||
player.on("debug", async (message) => {
|
||||
console.log(`General player debug event: ${message}`);
|
||||
});
|
||||
|
||||
player.events.on("debug", async (_, message) => {
|
||||
console.log(`Player debug event: ${message}`);
|
||||
});
|
||||
}
|
||||
|
||||
player.events.on("error", (_, error) => {
|
||||
// Emitted when the player queue encounters error
|
||||
console.error(`General player error event: ${error.message}`);
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
player.events.on("playerError", (_, error) => {
|
||||
// Emitted when the audio player errors while streaming audio track
|
||||
console.error(`Player error event: ${error.message}`);
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
events_categories.forEach(async (event_category) => {
|
||||
// Retrieve events
|
||||
|
@ -20,16 +45,12 @@ export default async (client: Client) => {
|
|||
);
|
||||
|
||||
// Remove extension
|
||||
// TODO: use utils functions
|
||||
const event_type_ext = event_file.split(".");
|
||||
const ext = event_type_ext.pop();
|
||||
const { file: event_type, ext } = splitFilenameExtensions(event_file)!;
|
||||
if (!(ext === "js" || ext === "ts")) {
|
||||
throw `Unknown file in ${event_category}: ${event_file}`;
|
||||
}
|
||||
const event_type = event_type_ext.join(".");
|
||||
|
||||
if (event_category == "player") {
|
||||
const player = useMainPlayer() as Player;
|
||||
if (event_category === "player") {
|
||||
if (once) {
|
||||
// eslint-disable-next-line
|
||||
return player.events.once(event_type as keyof PlayerEvents, (...args: any[]) => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, EmbedBuilder, GuildMember, Message, TextBasedChannel } from "discord.js";
|
||||
import { Client, EmbedBuilder, Message, TextBasedChannel } from "discord.js";
|
||||
import { getLocale } from "../../utils/locales";
|
||||
import { isImage, userWithNickname } from "../../utils/misc";
|
||||
import { showDate } from "../../utils/time";
|
||||
|
@ -65,12 +65,24 @@ export default async (message: Message, client: Client) => {
|
|||
[],
|
||||
)
|
||||
.map(async ({ message_id, channel }) => {
|
||||
const quoted_message = await channel.messages.fetch(message_id).catch(() => undefined);
|
||||
let quoted_message = await channel.messages.fetch(message_id).catch(() => undefined);
|
||||
|
||||
// If it's a reference, we only check for reference once
|
||||
const message_reference = quoted_message?.reference;
|
||||
if (message_reference && message_reference.messageId) {
|
||||
const channel_reference = client.channels.cache.get(
|
||||
message_reference.channelId,
|
||||
) as TextBasedChannel;
|
||||
|
||||
quoted_message = await channel_reference.messages
|
||||
.fetch(message_reference.messageId)
|
||||
.catch(() => undefined);
|
||||
}
|
||||
|
||||
// If message doesn't exist or empty
|
||||
if (
|
||||
!quoted_message ||
|
||||
(!quoted_message.content && quoted_message.attachments.size == 0)
|
||||
(!quoted_message.content && quoted_message.attachments.size === 0)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
@ -131,10 +143,10 @@ export default async (message: Message, client: Client) => {
|
|||
}
|
||||
|
||||
let author = "Auteur";
|
||||
if (message.author == quoted_post?.author) {
|
||||
if (message.author === quoted_post?.author) {
|
||||
author += " & Citateur";
|
||||
} else {
|
||||
footer += `\nCité par ${userWithNickname(message.member as GuildMember) ?? "?"} le ${showDate(
|
||||
footer += `\nCité par ${userWithNickname(message.member!) ?? "?"} le ${showDate(
|
||||
client.config.default_lang,
|
||||
loc,
|
||||
message.createdAt,
|
||||
|
|
|
@ -12,7 +12,7 @@ export const run = async (isDev: boolean) => {
|
|||
|
||||
// Client Discord.JS
|
||||
const client_name = "Client";
|
||||
await loadClient()
|
||||
await loadClient(isDev)
|
||||
.then(async (client) => {
|
||||
if (isDev) {
|
||||
// Attach debugging listeners
|
||||
|
@ -21,7 +21,7 @@ export const run = async (isDev: boolean) => {
|
|||
|
||||
// Events Discord.JS and Player
|
||||
const events_name = "Events";
|
||||
await loadEvents(client)
|
||||
await loadEvents(client, isDev)
|
||||
.then(() => console.log(logStart(events_name, true)))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
"c_reminder15": "Message sent in DM because you have left",
|
||||
"c_reminder16": "Message sent in DM because the Discord guild is no longer available.",
|
||||
"c_reminder17": "Message from",
|
||||
"c_reminder18": "Invalid time, try again.",
|
||||
|
||||
"c_play_name": "play",
|
||||
"c_play_desc": "Plays a song/playlist, no query displays the now playing song",
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
"c_reminder15": "Message envoyé en DM car vous avez quitté",
|
||||
"c_reminder16": "Message envoyé en DM car le serveur Discord n'est plus disponible.",
|
||||
"c_reminder17": "Message d'il y a",
|
||||
"c_reminder18": "Temps invalide, réessayez.",
|
||||
|
||||
"c_play_name": "play",
|
||||
"c_play_desc": "Joue une chanson/playlist, pas de requête affiche la chanson en cours actuellement",
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import { Player } from "discord-player";
|
||||
import { Client, Collection, GatewayIntentBits } from "discord.js";
|
||||
import { ActivityType, Client, Collection, GatewayIntentBits } from "discord.js";
|
||||
import { readFileSync } from "fs";
|
||||
import { Database } from "sqlite3";
|
||||
import "../modules/client";
|
||||
import { loadLocales } from "./locales";
|
||||
import { YoutubeiExtractor } from "discord-player-youtubei";
|
||||
|
||||
/** Creation of the client and definition of its properties */
|
||||
export default async () => {
|
||||
export default async (isDev: boolean) => {
|
||||
const activities = isDev ? [] : [{ name: "/help", type: ActivityType.Watching }];
|
||||
|
||||
const client: Client = new Client({
|
||||
shards: "auto",
|
||||
intents: [
|
||||
|
@ -16,6 +17,9 @@ export default async () => {
|
|||
GatewayIntentBits.MessageContent,
|
||||
GatewayIntentBits.GuildVoiceStates,
|
||||
],
|
||||
presence: {
|
||||
activities,
|
||||
},
|
||||
});
|
||||
|
||||
client.config = {
|
||||
|
@ -46,8 +50,7 @@ export default async () => {
|
|||
quality: "highestaudio",
|
||||
},
|
||||
});
|
||||
await player.extractors.loadDefault((ext) => ext !== "YouTubeExtractor");
|
||||
await player.extractors.register(YoutubeiExtractor, {});
|
||||
await player.extractors.loadDefault();
|
||||
|
||||
console.log("Translations progression :");
|
||||
client.locales = await loadLocales(client.config.default_lang);
|
||||
|
|
|
@ -28,27 +28,41 @@ export const getFilename = (path: string) => {
|
|||
return removeExtension(filename_with_ext);
|
||||
};
|
||||
|
||||
/**
|
||||
* Split a filename and his extension
|
||||
* @param filename string of the filename
|
||||
* @returns Object with filename and extension splitted
|
||||
*/
|
||||
export const splitFilenameExtensions = (filename: string) => {
|
||||
if (filename.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Check if the filename starts with a dot and has no other dots
|
||||
if (filename.startsWith(".") && filename.indexOf(".", 1) === -1) {
|
||||
return { file: filename, ext: undefined };
|
||||
}
|
||||
|
||||
const lastDotIndex = filename.lastIndexOf(".");
|
||||
|
||||
// If there's no dot or the dot is at the start, treat the whole string as the filename
|
||||
if (lastDotIndex <= 0) {
|
||||
return { file: filename, ext: undefined };
|
||||
}
|
||||
|
||||
const file = filename.slice(0, lastDotIndex);
|
||||
const ext = filename.slice(lastDotIndex + 1);
|
||||
|
||||
return { file, ext };
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove extension from a filename
|
||||
* @param filename string of the filename with an extension
|
||||
* @returns string of the filename without an extension
|
||||
*/
|
||||
export const removeExtension = (filename: string) => {
|
||||
const array = filename.split(".");
|
||||
array.pop();
|
||||
|
||||
return array.join(".");
|
||||
};
|
||||
|
||||
/**
|
||||
* Get extension from a filename
|
||||
* @param filename string of the filename
|
||||
* @returns string of the extension if it exists
|
||||
*/
|
||||
export const getExtension = (filename: string) => {
|
||||
const array = filename.split(".");
|
||||
|
||||
return array.pop();
|
||||
return splitFilenameExtensions(filename)!.file;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -57,7 +71,11 @@ export const getExtension = (filename: string) => {
|
|||
* @returns true is file is a media
|
||||
*/
|
||||
export const isImage = (filename: string) => {
|
||||
return Boolean(getExtension(filename)?.match(/jpg|jpeg|png|webp|gif/));
|
||||
return Boolean(
|
||||
splitFilenameExtensions(filename)
|
||||
?.ext?.toLowerCase()
|
||||
.match(/jpg|jpeg|png|webp|gif/),
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -98,7 +116,7 @@ export const cleanCodeBlock = (text: string) => {
|
|||
);
|
||||
|
||||
// Fix issues
|
||||
text = text.replace("``", "");
|
||||
text = text.replaceAll("``", "");
|
||||
|
||||
return text;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { EmbedBuilder } from "@discordjs/builders";
|
||||
import { GuildQueue, QueueRepeatMode, Track } from "discord-player";
|
||||
import { GuildQueue, QueueRepeatMode } from "discord-player";
|
||||
import { Client } from "discord.js";
|
||||
import { getLocale } from "./locales";
|
||||
|
||||
|
@ -14,7 +14,7 @@ export const embedListQueue = (
|
|||
const tracks = queue.tracks.toArray();
|
||||
|
||||
// Add the current song at the top of the list
|
||||
tracks.unshift(queue.history.currentTrack as Track);
|
||||
tracks.unshift(queue.history.currentTrack!);
|
||||
|
||||
// Limit of discord is 25
|
||||
const limit_fields = 25;
|
||||
|
@ -25,10 +25,10 @@ export const embedListQueue = (
|
|||
embed.setFooter({ text: `${printRepeatMode(queue.repeatMode, loc)}` });
|
||||
|
||||
tracks.slice((page - 1) * limit_fields, page * limit_fields).forEach((t, idx) => {
|
||||
const now_playing = idx == 0 && page == 1;
|
||||
const now_playing = idx === 0 && page === 1;
|
||||
const name = now_playing
|
||||
? loc.get("c_queue10")
|
||||
: (idx == 1 && page == 1) || (idx == 0 && page > 1)
|
||||
: (idx === 1 && page === 1) || (idx === 0 && page > 1)
|
||||
? loc.get("c_queue11")
|
||||
: "\u200b";
|
||||
const idx_track = now_playing ? "" : `${idx + limit_fields * (page - 1)}. `;
|
||||
|
|
|
@ -64,8 +64,15 @@ const splitTime = (time: string) => {
|
|||
*/
|
||||
export const newReminder = async (client: Client, time: string, info: infoReminder) =>
|
||||
new Promise((ok, ko) => {
|
||||
const loc = getLocale(client, info.locale);
|
||||
|
||||
const data = splitTime(time);
|
||||
const timeout = strToSeconds(data.time);
|
||||
if (timeout < 0) {
|
||||
ko(loc.get("c_reminder18"));
|
||||
return;
|
||||
}
|
||||
|
||||
const timeoutId = setTimeoutReminder(client, info, data.option, timeout);
|
||||
|
||||
// Add the remind to the db
|
||||
|
@ -90,7 +97,6 @@ export const newReminder = async (client: Client, time: string, info: infoRemind
|
|||
}
|
||||
|
||||
// Send confirmation to user
|
||||
const loc = getLocale(client, info.locale);
|
||||
ok(`${loc.get("c_reminder1")} ${data.time}.`);
|
||||
},
|
||||
);
|
||||
|
@ -160,7 +166,7 @@ export const sendReminder = (client: Client, info: infoReminder, option: OptionR
|
|||
}
|
||||
}
|
||||
|
||||
if (option == OptionReminder.DirectMessage || !channelOk || !guildOk) {
|
||||
if (option === OptionReminder.DirectMessage || !channelOk || !guildOk) {
|
||||
// Direct message
|
||||
const user = client.users.cache.get(info.userId);
|
||||
if (user !== undefined) {
|
||||
|
@ -176,7 +182,7 @@ export const sendReminder = (client: Client, info: infoReminder, option: OptionR
|
|||
});
|
||||
|
||||
// Mention everybody if needed
|
||||
if (option == OptionReminder.Mention) {
|
||||
if (option === OptionReminder.Mention) {
|
||||
(info.message?.match(/<@\d+>/g) ?? []).forEach((mention) => {
|
||||
content += " " + mention;
|
||||
});
|
||||
|
@ -202,8 +208,19 @@ export const setTimeoutReminder = (
|
|||
option: OptionReminder,
|
||||
timeout: number,
|
||||
) => {
|
||||
return Number(
|
||||
setTimeout(() => {
|
||||
const setChunkedTimeout = (remainingTime: number) => {
|
||||
// Maximum for setTimeout is Int32
|
||||
if (remainingTime > 2147483647) {
|
||||
// Schedule a 24-hour delay (24 * 60 * 60 * 1000), then check again
|
||||
const dayChunk = 86400000;
|
||||
|
||||
return setTimeout(() => {
|
||||
setChunkedTimeout(remainingTime - dayChunk);
|
||||
}, dayChunk);
|
||||
}
|
||||
|
||||
// Final timeout when remaining time is within limit
|
||||
return setTimeout(() => {
|
||||
deleteReminder(client, String(info.createdAt), info.userId).then((val) => {
|
||||
if (val != true) {
|
||||
throw val;
|
||||
|
@ -211,8 +228,11 @@ export const setTimeoutReminder = (
|
|||
|
||||
sendReminder(client, info, option);
|
||||
});
|
||||
}, timeout * 1000),
|
||||
);
|
||||
}, remainingTime);
|
||||
};
|
||||
|
||||
// Convert to milliseconds
|
||||
return Number(setChunkedTimeout(timeout * 1000));
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,6 +24,11 @@ enum TimeSecond {
|
|||
* @returns time in seconds
|
||||
*/
|
||||
export const strToSeconds = (time: string) => {
|
||||
if (time.length > 15) {
|
||||
// 15 is a magic value, weird to be this long
|
||||
return -1;
|
||||
}
|
||||
|
||||
const regex = new RegExp(
|
||||
`(?<${TimeSecond[TimeSecond.Year]}>[0-9]+(?=[y|a]))|(?<${
|
||||
TimeSecond[TimeSecond.Week]
|
||||
|
@ -34,7 +39,12 @@ export const strToSeconds = (time: string) => {
|
|||
}>[0-9]+(?=[s]?))`,
|
||||
);
|
||||
|
||||
const data = Object.assign({}, regex.exec(time)?.groups);
|
||||
const data = Object.assign({}, regex.exec(time.toLowerCase())?.groups);
|
||||
|
||||
if (Object.keys(data).length === 0) {
|
||||
// Regex returned an invalid time
|
||||
return -1;
|
||||
}
|
||||
|
||||
let res = 0;
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
|
|
Loading…
Reference in a new issue