diff --git a/package.json b/package.json index c3dc7ea..3392f04 100644 --- a/package.json +++ b/package.json @@ -21,31 +21,31 @@ }, "dependencies": { "@fabricio-191/valve-server-query": "^4.1.9", - "@sentry/cli": "^2.31.2", - "@sentry/node": "^8.0.0", + "@sentry/cli": "^2.32.2", + "@sentry/node": "^8.19.0", "cors": "^2.8.5", "discord-canvas": "^1.5.2", - "discord.js": "^14.15.2", + "discord.js": "^14.15.3", "dotenv": "^16.4.5", "express-session": "^1.18.0", - "express-validator": "^7.0.1", + "express-validator": "^7.1.0", "fs": "^0.0.2", "fs-extra": "^11.2.0", - "glob": "^10.3.15", + "glob": "^10.4.5", "helmet": "^7.1.0", "https": "^1.0.0", - "mongodb": "^6.6.1", + "mongodb": "^6.8.0", "node-fetch": "^2.7.0", - "openai": "^4.46.1", - "pino": "^9.1.0", + "openai": "^4.52.7", + "pino": "^9.3.1", "youtubei.js": "^9.4.0" }, "devDependencies": { - "@babel/core": "^7.24.5", + "@babel/core": "^7.24.9", "@types/express": "^4.17.21", "@types/glob": "^8.1.0", "@types/jquery": "^3.5.30", - "@types/node": "^20.12.11", + "@types/node": "^20.14.11", "express": "^4.19.2", "gulp": "^5.0.0", "gulp-babel": "^8.0.0", @@ -53,7 +53,7 @@ "gulp-uglify": "^3.0.2", "ts-node": "^10.9.2", "ts-node-dev": "^2.0.0", - "typescript": "^5.4.5", - "uglify-js": "^3.17.4" + "typescript": "^5.5.3", + "uglify-js": "^3.19.0" } } diff --git a/plugins/CS2/events/messageCreateCs2Chat.ts b/plugins/CS2/events/messageCreateCs2Chat.ts index 7a4a9c6..1011b74 100644 --- a/plugins/CS2/events/messageCreateCs2Chat.ts +++ b/plugins/CS2/events/messageCreateCs2Chat.ts @@ -9,7 +9,7 @@ export default new Event("messageCreate", async (message) => { try { const configs = getGuildConfigsById(message.guildId)?.cs2?.chatChannels; - if (!configs || !configs[message.channelId]) { + if (!configs?.length || !configs[message.channelId]) { return; } diff --git a/plugins/CS2/events/messageCreateCs2RCON.ts b/plugins/CS2/events/messageCreateCs2RCON.ts index 9da18f2..a8fbfaf 100644 --- a/plugins/CS2/events/messageCreateCs2RCON.ts +++ b/plugins/CS2/events/messageCreateCs2RCON.ts @@ -11,7 +11,7 @@ export default new Event("messageCreate", async (message) => { try { const configs = getGuildConfigsById(message.guildId)?.cs2?.rconChannels; - if (!configs || !configs[message.channelId]) { + if (!configs?.length || !configs[message.channelId]) { return; } diff --git a/plugins/MemberUpdate/PremiumMemberListener.ts b/plugins/MemberUpdate/PremiumMemberListener.ts new file mode 100644 index 0000000..e709ba1 --- /dev/null +++ b/plugins/MemberUpdate/PremiumMemberListener.ts @@ -0,0 +1,29 @@ +import { MemberUpdateData } from "../../src/events/guildMemberUpdate"; + +export default class PremiumMemberListener { + static async run(eventData: MemberUpdateData): Promise { + const { + guild, + member, + oldMember, + guildConfigs + } = eventData; + + const newPremiumSince = member.premiumSince; + const oldPremiumSince = oldMember.premiumSince; + const isBoostStop = oldPremiumSince && !newPremiumSince; + + // No boost change or end of boost + if (oldPremiumSince === newPremiumSince || isBoostStop) { + return; + } + + // Else isNewBoost on extra-boost + const data = guildConfigs.boost; + + + return true; + } + + +} \ No newline at end of file diff --git a/src/commands/banner.ts b/src/commands/banner.ts index d89864d..91a0018 100644 --- a/src/commands/banner.ts +++ b/src/commands/banner.ts @@ -7,11 +7,11 @@ import { getGuildConfigsById } from "../configs/guildsConfigs"; export default new Command({ name: "banner", public: true, - description: "Will send a banner.", + description: "Will send a banner. (welcome by default)", options: [ { - name: "type", description: "(default) 0: welcome, 1: goodbye", - type: ApplicationCommandOptionType.Integer, + name: "type", description: "welcome|goodbye|boost", + type: ApplicationCommandOptionType.String }, { name: "member", description: "a member", @@ -31,7 +31,7 @@ export default new Command({ const member = args.getMember("member") as GuildMember ?? interaction.member; - const type = args.getInteger("type", false) ? "goodbye" : "welcome"; + const type = args.getString("type", false) ?? "welcome"; const channel = args.getChannel('channel', false, [ChannelType.GuildText]) ?? guild.systemChannel; @@ -39,6 +39,7 @@ export default new Command({ await sendBanner(member, type, channel, interaction); interaction.reply({ content: "Done!", ephemeral: true }); } catch (error) { + console.error(error); interaction?.reply({ content: "Error!", ephemeral: true }); } } @@ -46,25 +47,36 @@ export default new Command({ export async function sendBanner( member: GuildMember | PartialGuildMember, - type: any, + type: string = "welcome", channelOverride?: any, interaction?: any, args?: any) { if (!member || member.user.bot) return; - const defConfigs = getGuildConfigsById("default"); - const guildConfigs = getGuildConfigsById(member.guild.id) ?? defConfigs; + let data = null; + const guildConfigs = getGuildConfigsById(member.guild.id); - const data = type === "goodbye" - ? (guildConfigs?.goodbye ?? defConfigs?.goodbye) - : (guildConfigs?.welcome ?? defConfigs?.welcome); + switch (type) { + case "goodbye": + data = guildConfigs.goodbye + break; + + case "boost": + data = guildConfigs.boost + break; + + default: + case "welcome": + data = guildConfigs.welcome + break; + } if (!guildConfigs || !data) { throw "No configs found..."; } - const cardData = data.card ?? defConfigs[type].card; - const getContent = data.getContent ?? defConfigs[type].getContent; + const cardData = data.card + const getContent = data.getContent; let channel = data.channelId ? member.guild.channels.cache.get((data.channelId)) diff --git a/src/configs/guildsConfigs.ts b/src/configs/guildsConfigs.ts index 8925e0b..cbafd9b 100644 --- a/src/configs/guildsConfigs.ts +++ b/src/configs/guildsConfigs.ts @@ -11,17 +11,27 @@ export const guildsConfigs = [ getTitle: () => "Welcome !!!", getMsg: (params: any) => "We are glad to have you here!" }, - getContent: (params: any) => `🤖 Greetings <@${params.member.id}> ! ⚡👾` + getContent: (params: any) => `🤖 Greetings <@${params.member.id}>! ⚡👾` }, goodbye: { channelId: null, card: { getTitle: () => "Bye bye", - getMsg: () => "We'll miss him / her!" + getMsg: (params: any) => "We'll miss him / her!" }, - getContent: (params: any) => `🤖 Say goodbye to <@${params.member.id}> ! 😢👾` + getContent: (params: any) => `🤖 Say goodbye to <@${params.member.id}>! 😢👾` + }, + boost: { + channelId: null, + card: { + getTitle: () => "New Boost !!!", + getMsg: (params: any) => "Thank you for the support!" + }, + getContent: (params: any) => `🤖 Big thanks to <@${params.member.id}> for boosting the server! ⚡👾` }, cs2: { + rconChannels: [], + chatChannels: [], dockerAccess: [] }, ollama: { @@ -221,11 +231,12 @@ export function getDefaultConfigs() { } export function getGuildConfigsById(guildId: string) { + const def = guildId !== "default" ? getDefaultConfigs() : {}; const found = guildsConfigs.find((config) => { return config.guildId === guildId; }); - return found; + return Object.assign(def, found ?? {}); } export function hasCs2DockerAccess(member: GuildMember) { diff --git a/src/events/guildMemberUpdate.ts b/src/events/guildMemberUpdate.ts new file mode 100644 index 0000000..e6636c2 --- /dev/null +++ b/src/events/guildMemberUpdate.ts @@ -0,0 +1,23 @@ +import { Guild, GuildMember, PartialGuildMember } from "discord.js"; + +import { Event } from "../class/event"; +import { getGuildConfigsById } from "../configs/guildsConfigs"; +import PremiumMemberListener from "../../plugins/MemberUpdate/PremiumMemberListener"; + +export type MemberUpdateData = { + guild: Guild, + member: GuildMember | PartialGuildMember + oldMember: GuildMember | PartialGuildMember + guildConfigs?: any +} + +export default new Event("guildMemberUpdate", (oldMember, member) => { + const eventData: MemberUpdateData = { + member, + oldMember, + guild: member.guild, + guildConfigs: getGuildConfigsById(member.guild.id), + } + + PremiumMemberListener.run(eventData); +}); \ No newline at end of file