From ea2a8c97ae081d3fe9151a5fe28aa6c4cf8b8ffa Mon Sep 17 00:00:00 2001 From: 1tzEmerald Date: Sun, 26 Jul 2026 21:23:16 +0100 Subject: [PATCH] Removed optional addons by default --- Addons/Configs/applicationsystem.yml | 111 --- Addons/Configs/discord-stats.yml | 11 - Addons/Configs/minecraft.yml | 16 - Addons/Configs/tempvc.yml | 38 - Addons/Configs/vouchley.yml | 28 - Addons/Data/applicationsystem.json | 3 - Addons/MinecraftStatus.js | 78 --- .../Configs/sactionaddon.yml | 5 - Addons/SupportBot Sanctions/sanction.js | 157 ----- Addons/SupportBot Tags v1.3/Data/tags.json | 2 - Addons/SupportBot Tags v1.3/tags.js | 85 --- Addons/SupportBot Tags v1.3/tagscreate.js | 76 -- Addons/SupportBot Tags v1.3/tagsdelete.js | 68 -- .../SupportBot-Invoices v1/Configs/paypal.yml | 14 - Addons/SupportBot-Invoices v1/paypal.js | 146 ---- Addons/TempVC.js | 227 ------ Addons/applicationsystem.js | 652 ------------------ Addons/calculator.js | 83 --- Addons/discord-stats.js | 139 ---- Addons/vouchley.js | 292 -------- Data/ai-memory.db | Bin 0 -> 4096 bytes Data/ai-memory.db-shm | Bin 0 -> 32768 bytes Data/ai-memory.db-wal | Bin 0 -> 45352 bytes Data/supportbot.db | Bin 0 -> 49152 bytes 24 files changed, 2231 deletions(-) delete mode 100644 Addons/Configs/applicationsystem.yml delete mode 100644 Addons/Configs/discord-stats.yml delete mode 100644 Addons/Configs/minecraft.yml delete mode 100644 Addons/Configs/tempvc.yml delete mode 100644 Addons/Configs/vouchley.yml delete mode 100644 Addons/Data/applicationsystem.json delete mode 100644 Addons/MinecraftStatus.js delete mode 100644 Addons/SupportBot Sanctions/Configs/sactionaddon.yml delete mode 100644 Addons/SupportBot Sanctions/sanction.js delete mode 100644 Addons/SupportBot Tags v1.3/Data/tags.json delete mode 100644 Addons/SupportBot Tags v1.3/tags.js delete mode 100644 Addons/SupportBot Tags v1.3/tagscreate.js delete mode 100644 Addons/SupportBot Tags v1.3/tagsdelete.js delete mode 100644 Addons/SupportBot-Invoices v1/Configs/paypal.yml delete mode 100644 Addons/SupportBot-Invoices v1/paypal.js delete mode 100644 Addons/TempVC.js delete mode 100644 Addons/applicationsystem.js delete mode 100644 Addons/calculator.js delete mode 100644 Addons/discord-stats.js delete mode 100644 Addons/vouchley.js create mode 100644 Data/ai-memory.db create mode 100644 Data/ai-memory.db-shm create mode 100644 Data/ai-memory.db-wal create mode 100644 Data/supportbot.db diff --git a/Addons/Configs/applicationsystem.yml b/Addons/Configs/applicationsystem.yml deleted file mode 100644 index db1c3e5..0000000 --- a/Addons/Configs/applicationsystem.yml +++ /dev/null @@ -1,111 +0,0 @@ -Command: - Name: "applicationsetup" - Description: "Posts the application panel" - Permission: - - "ManageGuild" - -Application: - ReviewChannelId: "1481380207305691287" - CooldownHours: 24 - OneOpenApplicationPerUserPerType: true - -Panel: - Title: "Applications" - Description: "Choose an application type from the dropdown below." - Placeholder: "Select an application type" - -Review: - Title: "New Application" - AcceptLabel: "Accept" - RejectLabel: "Reject" - -Applications: - staff: - Name: "Staff Team" - Description: "Apply for the staff team" - AcceptedRoleId: "" # Leave "" blank to disable - Questions: - Username: - Label: "What is your Discord username?" - Placeholder: "ExampleUser" - Required: true - Style: "Short" - MinLength: 2 - MaxLength: 50 - - Age: - Label: "How old are you?" - Placeholder: "18" - Required: true - Style: "Short" - MinLength: 1 - MaxLength: 3 - - Timezone: - Label: "What is your timezone?" - Placeholder: "GMT / BST / EST" - Required: true - Style: "Short" - MinLength: 2 - MaxLength: 30 - - Experience: - Label: "What experience do you have?" - Placeholder: "Tell us about your experience" - Required: true - Style: "Paragraph" - MinLength: 10 - MaxLength: 1000 - - Reason: - Label: "Why should we accept you?" - Placeholder: "Tell us why" - Required: true - Style: "Paragraph" - MinLength: 10 - MaxLength: 1000 - - developer: - Name: "Developer" - Description: "Apply for the development team" - AcceptedRoleId: "" - Questions: - Username: - Label: "What is your Discord username?" - Placeholder: "ExampleUser" - Required: true - Style: "Short" - MinLength: 2 - MaxLength: 50 - - Languages: - Label: "What languages do you know?" - Placeholder: "JavaScript, Python, Lua" - Required: true - Style: "Paragraph" - MinLength: 3 - MaxLength: 500 - - Projects: - Label: "What projects have you worked on?" - Placeholder: "Describe your work" - Required: true - Style: "Paragraph" - MinLength: 10 - MaxLength: 1000 - - Availability: - Label: "How active can you be?" - Placeholder: "How much time can you commit?" - Required: true - Style: "Paragraph" - MinLength: 5 - MaxLength: 500 - - Reason: - Label: "Why do you want this role?" - Placeholder: "Tell us why" - Required: true - Style: "Paragraph" - MinLength: 10 - MaxLength: 1000 \ No newline at end of file diff --git a/Addons/Configs/discord-stats.yml b/Addons/Configs/discord-stats.yml deleted file mode 100644 index f295c0e..0000000 --- a/Addons/Configs/discord-stats.yml +++ /dev/null @@ -1,11 +0,0 @@ - -# SupportBot | Emerald Services -# Discord Stats addon | Created by Xiled Emerald - -Guild_ID: "GUILD_ID_HERE" - -StatsCategory: "Server Statistics" - -UserCount_Name: "Total Members:" -ChannelCount_Name: "Total Channels:" -RoleCount_Name: "Total Roles:" \ No newline at end of file diff --git a/Addons/Configs/minecraft.yml b/Addons/Configs/minecraft.yml deleted file mode 100644 index 552deec..0000000 --- a/Addons/Configs/minecraft.yml +++ /dev/null @@ -1,16 +0,0 @@ -# Minecraft Server Configuration - -Java: - IP: "play.sapling.gg" - Port: 25565 - DisplayName: "Java Edition" -Bedrock: - IP: "play.sapling.gg" - Port: 19132 - DisplayName: "Bedrock Edition" - -Embed: - Color: "#57F287" - OfflineColor: "#ED4245" - - diff --git a/Addons/Configs/tempvc.yml b/Addons/Configs/tempvc.yml deleted file mode 100644 index f7227bc..0000000 --- a/Addons/Configs/tempvc.yml +++ /dev/null @@ -1,38 +0,0 @@ -# SupportBot Temporary Voice Channels Configuration -# Addon Version 1.0 - -Enabled: true - -# The ID of the voice channel that users join to create a new one -JoinToCreateChannelID: "CHANNEL_ID" - -# The category ID where new channels should be created (Optional) -# If left blank, it will create it in the same category as the JoinToCreate channel -CategoryID: "CATEGORY_ID" - -# The name pattern for new channels - -# Placeholders: -# {user}: Username -ChannelNamePattern: "🔊 {user}'s Channel" - -# Should the channel be deleted when the last person leaves? -AutoDelete: true - -# Voice Channel Hub (Control Panel) -Hub: - Enabled: true - SendOnCreate: true - LayoutStyle: "classic" # classic | modern - - # Classic Layout Settings (Standard Embed + Buttons) - Classic: - Title: "Voice Channel Hub" - Description: "Manage your voice channel using the buttons below." - Color: "#57F287" - - # Modern Layout Settings (V2 Containers) - Modern: - Title: "Voice Channel Controller" - Body: "Control temporary voice channel using this control panel." - Color: "#57F287" diff --git a/Addons/Configs/vouchley.yml b/Addons/Configs/vouchley.yml deleted file mode 100644 index ed67607..0000000 --- a/Addons/Configs/vouchley.yml +++ /dev/null @@ -1,28 +0,0 @@ -# +==================================================================================+ -# | | -# | __ __ _ _ _ _ _ | -# | \ \ / /__ _ _ ___| |__ | | ___ _ _ / \ __| | __| | ___ _ __ | -# | \ \ / / _ \| | | |/ __| '_ \| |/ _ \ | | | / _ \ / _` |/ _` |/ _ \| '_ \ | -# | \ V / (_) | |_| | (__| | | | | __/ |_| | / ___ \ (_| | (_| | (_) | | | | | -# | \_/ \___/ \__,_|\___|_| |_|_|\___|\__, | /_/ \_\__,_|\__,_|\___/|_| |_| | -# | |___/ | -# | | -# | Vouchley Addon for SupportBot | -# | Created by Emerald Services | -# | | -# +==================================================================================+ - -Vouchley: - API_Key: "REQUEST_API_KEY_BELOW" - -# Vouchley API Documentation: https://www.vouchley.com/docs/api/getting-started -# To use the API you will need an API key. To get this create a ticket in https://discord.gg/buzz - -Embed: - Colour: 0x6063fc # 0x without the # - Ephermal: true # Make the profile searches hidden so only the interacting user can see them. - -Command: - Name: "vouchley" # The name of the command (/vouchley) - Description: "Search a Vouchley Profile." # The description of the command (/vouchley) - Permissions: ["SendMessages"] \ No newline at end of file diff --git a/Addons/Data/applicationsystem.json b/Addons/Data/applicationsystem.json deleted file mode 100644 index caf3f18..0000000 --- a/Addons/Data/applicationsystem.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "applications": [] -} \ No newline at end of file diff --git a/Addons/MinecraftStatus.js b/Addons/MinecraftStatus.js deleted file mode 100644 index 3ff782b..0000000 --- a/Addons/MinecraftStatus.js +++ /dev/null @@ -1,78 +0,0 @@ -const Discord = require("discord.js"); -const { Command } = require("../Structures/Addon.js"); -const fs = require("fs"); -const yaml = require("js-yaml"); -const axios = require("axios"); - -// Load configs -const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8")); -const minecraftConfig = yaml.load(fs.readFileSync("./Addons/Configs/minecraft.yml", "utf8")); - -module.exports = new Command({ - name: "serverip", - description: "Display the Minecraft server IP and status", - options: [ - { - name: "type", - description: "The edition of Minecraft (Java or Bedrock)", - type: Discord.ApplicationCommandOptionType.String, - required: true, - choices: [ - { name: "Java", value: "java" }, - { name: "Bedrock", value: "bedrock" }, - ], - }, - ], - permissions: ["SendMessages"], - - async run(interaction) { - const type = interaction.options.getString("type"); - const config = type === "java" ? minecraftConfig.Java : minecraftConfig.Bedrock; - - await interaction.deferReply(); - - try { - const response = await axios.get(`https://api.mcstatus.io/v2/status/${type}/${config.IP}:${config.Port}`); - const data = response.data; - - if (!data.online) { - throw new Error("Server is offline"); - } - - const embed = new Discord.EmbedBuilder() - .setTitle(`${config.DisplayName} Status`) - .setTimestamp(); - - embed.setColor(minecraftConfig.Embed.Color || supportbot.Embed.Colours.General) - .setDescription(`The server is currently **Online**!`) - .addFields( - { name: "IP Address", value: `\`${config.IP}\``, inline: true }, - { name: "Port", value: `\`${config.Port}\``, inline: true }, - { name: "Players", value: `\`${data.players.online}/${data.players.max}\``, inline: true }, - { name: "Version", value: `\`${type === "java" ? data.version.name_clean : data.version.name || "Unknown"}\``, inline: true } - ); - - if (data.motd && data.motd.clean) { - embed.addFields({ name: "MOTD", value: `\`\`\`${data.motd.clean}\`\`\`` }); - } - - await interaction.editReply({ embeds: [embed] }); - } catch (error) { - console.error("Error fetching Minecraft status:", error); - - const config = interaction.options.getString("type") === "java" ? minecraftConfig.Java : minecraftConfig.Bedrock; - - const embed = new Discord.EmbedBuilder() - .setTitle(`${config.DisplayName} Status`) - .setTimestamp() - .setColor(minecraftConfig.Embed.OfflineColor || "#FF0000") - .setDescription(`The server is currently **Offline**.`) - .addFields( - { name: "IP Address", value: `\`${config.IP}\``, inline: true }, - { name: "Port", value: `\`${config.Port}\``, inline: true } - ); - - await interaction.editReply({ embeds: [embed] }); - } - }, -}); diff --git a/Addons/SupportBot Sanctions/Configs/sactionaddon.yml b/Addons/SupportBot Sanctions/Configs/sactionaddon.yml deleted file mode 100644 index f352e10..0000000 --- a/Addons/SupportBot Sanctions/Configs/sactionaddon.yml +++ /dev/null @@ -1,5 +0,0 @@ -# SupportBot Sanction Addon -# Created by ItsNyoty - -LogChannel: "1275426007980965908" -# The ID of the channel where the logs will be sent. \ No newline at end of file diff --git a/Addons/SupportBot Sanctions/sanction.js b/Addons/SupportBot Sanctions/sanction.js deleted file mode 100644 index 153a166..0000000 --- a/Addons/SupportBot Sanctions/sanction.js +++ /dev/null @@ -1,157 +0,0 @@ -const Discord = require('discord.js'); -const fs = require('fs'); -const yaml = require('js-yaml'); -const { Command } = require('../Structures/Addon.js'); -const supportbot = yaml.load(fs.readFileSync('./Configs/supportbot.yml', 'utf8')); -const sactionaddon = yaml.load(fs.readFileSync('./Addons/Configs/sactionaddon.yml', 'utf8')); - -module.exports = new Command({ - name: 'sanction', - description: 'Sanction a user (kick, ban, or timeout).', - options: [ - { - name: 'action', - type: 3, - description: 'The action to perform (kick, ban, timeout)', - required: true, - choices: [ - { name: 'Kick', value: 'kick' }, - { name: 'Ban', value: 'ban' }, - { name: 'Timeout', value: 'timeout' } - ] - }, - { - name: 'user', - type: 6, - description: 'The user to sanction', - required: true - }, - { - name: 'reason', - type: 3, - description: 'Reason for the sanction', - required: false - }, - { - name: 'duration', - type: 3, - description: 'Duration of the timeout (e.g., "10m", "2h", "1d")', - required: false - } - ], - permissions: [], - - async run(interaction) { - const action = interaction.options.getString('action'); - const user = interaction.options.getUser('user'); - const reason = interaction.options.getString('reason') || 'No reason provided'; - const duration = interaction.options.getString('duration'); - const staffRoleId = supportbot.Roles.StaffMember.Staff; - - const member = interaction.guild.members.cache.get(interaction.user.id); - if (!member || !member.roles.cache.has(staffRoleId)) { - return interaction.reply({ content: 'You do not have permission to use this command.', ephemeral: true }); - } - - const targetMember = interaction.guild.members.cache.get(user.id); - if (!targetMember) { - return interaction.reply({ content: 'The user is not a member of this guild.', ephemeral: true }); - } - - try { - let actionMessage = ''; - let logEmbed = new Discord.EmbedBuilder().setColor(supportbot.Embed.Colours.General); - - switch (action) { - case 'kick': - if (!targetMember.kickable) return interaction.reply({ content: 'I cannot kick this user.', ephemeral: true }); - await targetMember.kick(reason); - actionMessage = `Successfully kicked ${user.tag} for: ${reason}`; - logEmbed - .setTitle('User Kicked') - .setDescription(`**User:** ${user.tag}\n**Reason:** ${reason}`) - .addFields( - { name: 'Action By', value: interaction.user.tag, inline: true }, - { name: 'Action', value: 'Kick', inline: true }, - { name: 'Timestamp', value: new Date().toISOString(), inline: true } - ); - break; - - case 'ban': - if (!targetMember.bannable) return interaction.reply({ content: 'I cannot ban this user.', ephemeral: true }); - await targetMember.ban({ reason }); - actionMessage = `Successfully banned ${user.tag} for: ${reason}`; - logEmbed - .setTitle('User Banned') - .setDescription(`**User:** ${user.tag}\n**Reason:** ${reason}`) - .addFields( - { name: 'Action By', value: interaction.user.tag, inline: true }, - { name: 'Action', value: 'Ban', inline: true }, - { name: 'Timestamp', value: new Date().toISOString(), inline: true } - ); - break; - - case 'timeout': - // Ensure a valid duration is provided - if (!duration) return interaction.reply({ content: 'You must specify a duration for the timeout.', ephemeral: true }); - - // Convert duration to milliseconds - const parsedDuration = ms(duration); - if (!parsedDuration) return interaction.reply({ content: 'Invalid duration format. Use "1s", "5m", "2h", or "1d".', ephemeral: true }); - - // Apply the timeout - await targetMember.timeout(parsedDuration, reason); - actionMessage = `Successfully timed out ${user.tag} for ${duration} with reason: ${reason}`; - logEmbed - .setTitle('User Timed Out') - .setDescription(`**User:** ${user.tag}\n**Duration:** ${duration}\n**Reason:** ${reason}`) - .addFields( - { name: 'Action By', value: interaction.user.tag, inline: true }, - { name: 'Action', value: 'Timeout', inline: true }, - { name: 'Timestamp', value: new Date().toISOString(), inline: true } - ); - break; - - default: - return interaction.reply({ content: 'Invalid action specified.', ephemeral: true }); - } - - // Send the action message - interaction.reply({ content: actionMessage, ephemeral: true }); - - // Log the action to the logging channel - const logChannel = interaction.guild.channels.cache.get(sactionaddon.LogChannel); - if (logChannel) { - logChannel.send({ embeds: [logEmbed] }); - } else { - console.error('Logging channel not found.'); - } - } catch (error) { - console.error('Error executing sanction command:', error); - interaction.reply({ content: 'An error occurred while executing the command.', ephemeral: true }); - } - }, -}); - -/** - * Converts a time duration string to milliseconds. - * @param {string} duration - The duration string (e.g., "10m", "2h", "1d"). - * @returns {number} - The duration in milliseconds. - */ -function ms(duration) { - const regex = /^(\d+)([smhd])$/; - const match = regex.exec(duration); - - if (!match) return null; - - const value = parseInt(match[1], 10); - const unit = match[2]; - - switch (unit) { - case 's': return value * 1000; // seconds - case 'm': return value * 60 * 1000; // minutes - case 'h': return value * 60 * 60 * 1000; // hours - case 'd': return value * 24 * 60 * 60 * 1000; // days - default: return null; - } -} \ No newline at end of file diff --git a/Addons/SupportBot Tags v1.3/Data/tags.json b/Addons/SupportBot Tags v1.3/Data/tags.json deleted file mode 100644 index 7a73a41..0000000 --- a/Addons/SupportBot Tags v1.3/Data/tags.json +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file diff --git a/Addons/SupportBot Tags v1.3/tags.js b/Addons/SupportBot Tags v1.3/tags.js deleted file mode 100644 index 22fa01d..0000000 --- a/Addons/SupportBot Tags v1.3/tags.js +++ /dev/null @@ -1,85 +0,0 @@ -const Discord = require("discord.js"); -const fs = require("fs"); -const yaml = require("js-yaml"); -const { Command } = require('../Structures/Addon.js'); // Adjust the path as needed -const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8")); - -module.exports = new Command({ - name: "tags", - description: "Retrieve a saved tag.", - options: [ - { - name: 'name', - type: Discord.ApplicationCommandOptionType.String, - description: 'The name of the tag', - required: true, - autocomplete: true - }, - ], - permissions: ["SendMessages"], - - async autocomplete(interaction) { - const tagsPath = './Addons/Data/tags.json'; - const focusedValue = interaction.options.getFocused().toLowerCase(); - - if (!fs.existsSync(tagsPath)) { - return interaction.respond([]); - } - - const tags = JSON.parse(fs.readFileSync(tagsPath, 'utf8')); - const choices = Object.keys(tags) - .filter(tag => tag.toLowerCase().includes(focusedValue)) - .slice(0, 25) // Discord has a limit of 25 choices - .map(tag => ({ name: tag, value: tag })); - - return interaction.respond(choices); - }, - - async run(interaction) { - const tagsPath = './Addons/Data/tags.json'; - const tagName = interaction.options.getString('name').toLowerCase(); - - if (!fs.existsSync(tagsPath)) { - const embed = new Discord.EmbedBuilder() - .setDescription('No tags have been created yet.') - .setColor(supportbot.Embed.Colours.General); - return interaction.reply({ embeds: [embed], ephemeral: true }); - } - - const tags = JSON.parse(fs.readFileSync(tagsPath, 'utf8')); - - if (tags[tagName]) { - const tag = tags[tagName]; - - if (tag.embed) { - // For embeds, Discord automatically handles line breaks correctly - const embed = new Discord.EmbedBuilder() - .setDescription(tag.content) - .setColor(supportbot.Embed.Colours.General); - - if (tag.image) { - embed.setImage(tag.image); - } - - return interaction.reply({ embeds: [embed], ephemeral: tag.ephemeral || false }); - } else { - // For plain text, we need to keep the line breaks - const response = { - content: tag.content, - ephemeral: tag.ephemeral || false - }; - - if (tag.image) { - response.files = [tag.image]; - } - - return interaction.reply(response); - } - } else { - const embed = new Discord.EmbedBuilder() - .setDescription(`Tag "${tagName}" not found.`) - .setColor(supportbot.Embed.Colours.General); - return interaction.reply({ embeds: [embed], ephemeral: true }); - } - } -}); \ No newline at end of file diff --git a/Addons/SupportBot Tags v1.3/tagscreate.js b/Addons/SupportBot Tags v1.3/tagscreate.js deleted file mode 100644 index 0af78ee..0000000 --- a/Addons/SupportBot Tags v1.3/tagscreate.js +++ /dev/null @@ -1,76 +0,0 @@ -const Discord = require("discord.js"); -const fs = require("fs"); -const yaml = require("js-yaml"); -const { Command } = require('../Structures/Addon.js'); // Adjust the path as needed -const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8")); - -module.exports = new Command({ - name: "tagscreate", - description: "Create a new tag.", - options: [ - { - name: 'name', - type: Discord.ApplicationCommandOptionType.String, - description: 'The name of the tag', - required: true, - }, - { - name: 'content', - type: Discord.ApplicationCommandOptionType.String, - description: 'The content of the tag (use ; or /n for new lines)', - required: true, - }, - { - name: 'image', - type: Discord.ApplicationCommandOptionType.Attachment, - description: 'The image URL of the tag', - required: false, - }, - { - name: 'embed', - type: Discord.ApplicationCommandOptionType.Boolean, - description: 'Do you want this tag to send as an embed', - required: false, - }, - { - name: 'ephemeral', - type: Discord.ApplicationCommandOptionType.Boolean, - description: 'Do you want this tag to send as ephemeral', - required: false, - }, - ], - permissions: ["SendMessages"], - - async run(interaction) { - const tagName = interaction.options.getString('name').toLowerCase(); - let tagContent = interaction.options.getString('content'); - const tagImage = interaction.options.getAttachment('image'); - const isEmbed = interaction.options.getBoolean('embed'); - const isEphemeral = interaction.options.getBoolean('ephemeral'); - const tagsPath = './Addons/Data/tags.json'; - - // Process line breaks in content - support both ; and /n notations - tagContent = tagContent.replace(/;/g, '\n').replace(/\/n/g, '\n'); - - let tags = {}; - - if (fs.existsSync(tagsPath)) { - tags = JSON.parse(fs.readFileSync(tagsPath, 'utf8')); - } - - tags[tagName] = { - content: tagContent, - image: tagImage ? tagImage.url : null, - embed: isEmbed || false, - ephemeral: isEphemeral || false, - }; - - fs.writeFileSync(tagsPath, JSON.stringify(tags, null, 4)); - - const embed = new Discord.EmbedBuilder() - .setDescription(`Tag "${tagName}" created successfully.`) - .setColor(supportbot.Embed.Colours.General); - - return interaction.reply({ embeds: [embed], ephemeral: true }); - }, -}); \ No newline at end of file diff --git a/Addons/SupportBot Tags v1.3/tagsdelete.js b/Addons/SupportBot Tags v1.3/tagsdelete.js deleted file mode 100644 index 250a8eb..0000000 --- a/Addons/SupportBot Tags v1.3/tagsdelete.js +++ /dev/null @@ -1,68 +0,0 @@ -const Discord = require("discord.js"); -const fs = require("fs"); -const yaml = require("js-yaml"); -const { Command } = require('../Structures/Addon.js'); // Adjust the path as needed -const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8")); - -module.exports = new Command({ - name: "tagsdelete", - description: "Delete an existing tag.", - options: [ - { - name: 'name', - type: Discord.ApplicationCommandOptionType.String, - description: 'The name of the tag to delete', - required: true, - autocomplete: true - }, - ], - permissions: ["SendMessages"], - - async autocomplete(interaction) { - const tagsPath = './Addons/Data/tags.json'; - const focusedValue = interaction.options.getFocused().toLowerCase(); - - if (!fs.existsSync(tagsPath)) { - return interaction.respond([]); - } - - const tags = JSON.parse(fs.readFileSync(tagsPath, 'utf8')); - const choices = Object.keys(tags) - .filter(tag => tag.toLowerCase().includes(focusedValue)) - .slice(0, 25) // Discord has a limit of 25 choices - .map(tag => ({ name: tag, value: tag })); - - return interaction.respond(choices); - }, - - async run(interaction) { - const tagsPath = './Addons/Data/tags.json'; - const tagName = interaction.options.getString('name').toLowerCase(); - - if (!fs.existsSync(tagsPath)) { - const embed = new Discord.EmbedBuilder() - .setDescription('No tags have been created yet.') - .setColor(supportbot.Embed.Colours.General); - return interaction.reply({ embeds: [embed], ephemeral: true }); - } - - let tags = JSON.parse(fs.readFileSync(tagsPath, 'utf8')); - - if (!tags[tagName]) { - const embed = new Discord.EmbedBuilder() - .setDescription(`Tag "${tagName}" not found.`) - .setColor(supportbot.Embed.Colours.General); - return interaction.reply({ embeds: [embed], ephemeral: true }); - } - - delete tags[tagName]; - - fs.writeFileSync(tagsPath, JSON.stringify(tags, null, 4)); - - const embed = new Discord.EmbedBuilder() - .setDescription(`Tag "${tagName}" deleted successfully.`) - .setColor(supportbot.Embed.Colours.General); - - return interaction.reply({ embeds: [embed], ephemeral: true }); - } -}); \ No newline at end of file diff --git a/Addons/SupportBot-Invoices v1/Configs/paypal.yml b/Addons/SupportBot-Invoices v1/Configs/paypal.yml deleted file mode 100644 index 0796f6a..0000000 --- a/Addons/SupportBot-Invoices v1/Configs/paypal.yml +++ /dev/null @@ -1,14 +0,0 @@ -PayPal: - ClientID: "clientID_Here" - ClientSecret: "ClientSecret_Here" - Mode: "live" # or "live" - Email: "Email_Here" # Add your PayPal email here -Embed: - Colours: - General: "#0099ff" - Success: "#00ff00" # Add more colors if needed - Error: "#ff0000" # Add more colors if needed - Footer: "PayPal Invoice" # Add footer text here - Logo: "https://your-logo-url.com/logo.png" # Add logo URL if used in invoice - Note: "Thank you for your business!" # Add a note if used in invoice - TOS: "Please review our terms and conditions. https://domain.com/tos" # Add terms of service if used in invoice diff --git a/Addons/SupportBot-Invoices v1/paypal.js b/Addons/SupportBot-Invoices v1/paypal.js deleted file mode 100644 index bd02844..0000000 --- a/Addons/SupportBot-Invoices v1/paypal.js +++ /dev/null @@ -1,146 +0,0 @@ -const { EmbedBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder, ApplicationCommandOptionType } = require('discord.js'); -const fs = require('fs'); -const yaml = require('js-yaml'); -const paypal = require('paypal-rest-sdk'); -const { Command } = require('../Structures/Addon.js'); // Adjust the path as needed - -// Load the PayPal configuration -const config = yaml.load(fs.readFileSync("./Addons/Configs/paypal.yml", "utf8")); -const supportbot = config; - -// Configure PayPal SDK -paypal.configure({ - mode: supportbot.PayPal.Mode, // sandbox or live - client_id: supportbot.PayPal.ClientID, - client_secret: supportbot.PayPal.ClientSecret -}); - -module.exports = new Command({ - name: "invoice", - description: "Generate a PayPal invoice for a user.", - options: [ - { - name: "user", - description: "The user to notify.", - type: ApplicationCommandOptionType.User, - required: true, - }, - { - name: "price", - description: "The amount to invoice.", - type: ApplicationCommandOptionType.String, - required: true, - }, - { - name: "service", - description: "The service provided.", - type: ApplicationCommandOptionType.String, - required: true, - }, - { - name: "email", - description: "The email to invoice.", - type: ApplicationCommandOptionType.String, - required: true, - } - ], - permissions: ["Administrator"], - - async run(interaction) { - const user = interaction.options.getUser("user"); - const price = interaction.options.getString("price"); - const service = interaction.options.getString("service"); - const email = interaction.options.getString("email"); - - // Validate the price format - if (isNaN(price) || parseFloat(price) <= 0) { - const errorEmbed = new EmbedBuilder() - .setDescription(`The price provided is invalid.`) - .setColor(supportbot.Embed.Colours.Error) - .setFooter({ text: supportbot.Embed.Footer }); - return interaction.reply({ embeds: [errorEmbed], ephemeral: true }); - } - - const invoiceData = { - "merchant_info": { - "email": supportbot.PayPal.Email, - "business_name": interaction.guild.name - }, - "billing_info": [{ - "email": email - }], - "items": [{ - "name": service, - "quantity": 1, - "unit_price": { - "currency": "USD", - "value": price - } - }], - "logo_url": supportbot.PayPal.Logo, - "note": supportbot.PayPal.Note, - "terms": supportbot.PayPal.TOS, - "payment_term": { - "term_type": "NET_45" - }, - "tax_inclusive": false, - "total_amount": { - "currency": "USD", - "value": price - } - }; - - paypal.invoice.create(invoiceData, function (error, invoice) { - if (error) { - console.error(error); - const errorEmbed = new EmbedBuilder() - .setTitle(`PayPal Error`) - .setDescription(`There was an error creating the invoice. Please check your configuration and try again.`) - .setColor(supportbot.Embed.Colours.Error) - .setFooter({ text: supportbot.Embed.Footer }); - return interaction.reply({ embeds: [errorEmbed], ephemeral: true }); - } - - const invoiceId = invoice.id; - paypal.invoice.send(invoiceId, function (error) { - if (error) { - console.error(error); - const errorEmbed = new EmbedBuilder() - .setTitle(`PayPal Error`) - .setDescription(`There was an error sending the invoice. Please check your configuration and try again.`) - .setColor(supportbot.Embed.Colours.Error) - .setFooter({ text: supportbot.Embed.Footer }); - return interaction.reply({ embeds: [errorEmbed], ephemeral: true }); - } - - const invoiceEmbed = new EmbedBuilder() - .setTitle(`Payment System | ${interaction.guild.name}`) - .addFields( - { name: 'Service', value: service, inline: true }, - { name: 'Amount Due', value: `$${price}`, inline: true }, - { name: 'Currency', value: 'USD', inline: true }, - { name: 'Invoice ID', value: `\`${invoiceId}\``, inline: false } - ) - .setColor(supportbot.Embed.Colours.General) - .setFooter({ text: supportbot.Embed.Footer }) - .setTimestamp(); - - // Create a button with a link to the invoice - const invoiceButton = new ButtonBuilder() - .setLabel('View Invoice') - .setStyle(ButtonStyle.Link) - .setURL(`https://www.paypal.com/invoice/payerView/details/${invoiceId}`); - - // Create the action row - const actionRow = new ActionRowBuilder() - .addComponents(invoiceButton); - - // Send the embed with the button - interaction.reply({ - embeds: [invoiceEmbed], - components: [actionRow] - }); - }); - }); - }, -}); diff --git a/Addons/TempVC.js b/Addons/TempVC.js deleted file mode 100644 index 1c3b190..0000000 --- a/Addons/TempVC.js +++ /dev/null @@ -1,227 +0,0 @@ -const Discord = require("discord.js"); -const { Event } = require("../Structures/Addon.js"); -const fs = require("fs"); -const yaml = require("js-yaml"); - -const tempVCConfig = yaml.load(fs.readFileSync("./Addons/Configs/tempvc.yml", "utf8")); - -const tempChannels = new Map(); - -const voiceStateUpdate = new Event("voiceStateUpdate", async (client, oldState, newState) => { - if (!tempVCConfig.Enabled) return; - - const member = newState.member; - const guild = newState.guild; - - if (newState.channelId === tempVCConfig.JoinToCreateChannelID) { - console.log(`[TempVC] ${member.user.tag} joined the Join-to-Create channel.`); - } - - if (newState.channelId === tempVCConfig.JoinToCreateChannelID) { - try { - const parentCategory = tempVCConfig.CategoryID || newState.channel.parentId; - const channelName = tempVCConfig.ChannelNamePattern.replace("{user}", member.user.username); - - const newChannel = await guild.channels.create({ - name: channelName, - type: Discord.ChannelType.GuildVoice, - parent: parentCategory, - permissionOverwrites: [ - { - id: member.id, - allow: [Discord.PermissionFlagsBits.ManageChannels, Discord.PermissionFlagsBits.MoveMembers], - }, - ], - }); - - tempChannels.set(newChannel.id, member.id); - await member.voice.setChannel(newChannel); - - console.log(`[TempVC] Created channel "${channelName}" for ${member.user.tag}`); - - if (tempVCConfig.Hub.Enabled && tempVCConfig.Hub.SendOnCreate) { - try { - const { ActionRowBuilder, ButtonBuilder, EmbedBuilder, MessageFlags, ButtonStyle } = Discord; - const layoutStyle = tempVCConfig.Hub.LayoutStyle || "classic"; - - if (layoutStyle === "classic") { - const config = tempVCConfig.Hub.Classic; - const embed = new EmbedBuilder() - .setTitle(config.Title) - .setDescription(config.Description) - .setColor(config.Color); - - const buttons = new ActionRowBuilder().addComponents( - new ButtonBuilder().setCustomId("tempvc_lock").setLabel("Lock").setEmoji("🔒").setStyle(ButtonStyle.Secondary), - new ButtonBuilder().setCustomId("tempvc_unlock").setLabel("Unlock").setEmoji("🔓").setStyle(ButtonStyle.Secondary), - new ButtonBuilder().setCustomId("tempvc_rename").setLabel("Rename").setEmoji("✏️").setStyle(ButtonStyle.Secondary), - new ButtonBuilder().setCustomId("tempvc_limit").setLabel("Limit").setEmoji("👥").setStyle(ButtonStyle.Secondary), - new ButtonBuilder().setCustomId("tempvc_claim").setLabel("Claim Ownership").setEmoji("👑").setStyle(ButtonStyle.Primary) - ); - - await newChannel.send({ embeds: [embed], components: [buttons] }); - } else { - const config = tempVCConfig.Hub.Modern; - const colorInt = parseInt(config.Color.replace("#", ""), 16); - - const container = { - type: 11, - accent_color: colorInt, - children: [ - { - type: 12, - children: [ - { type: 13, content: `## ${config.Title}` }, - { type: 13, content: config.Body } - ] - }, - { - type: 15, - divider: true - }, - { - type: 1, - components: [ - { type: 2, custom_id: "tempvc_lock", label: "Lock", emoji: { name: "🔒" }, style: 2 }, - { type: 2, custom_id: "tempvc_unlock", label: "Unlock", emoji: { name: "🔓" }, style: 2 }, - { type: 2, custom_id: "tempvc_rename", label: "Rename", emoji: { name: "✏️" }, style: 2 }, - { type: 2, custom_id: "tempvc_limit", label: "Limit", emoji: { name: "👥" }, style: 2 } - ] - }, - { - type: 1, - components: [ - { type: 2, custom_id: "tempvc_claim", label: "Claim Ownership", emoji: { name: "👑" }, style: 1 } - ] - } - ] - }; - - await newChannel.send({ - flags: MessageFlags.IsComponentsV2, - components: [container] - }); - } - } catch (hubError) { - console.error("[TempVC] Error sending Hub:", hubError); - } - } - } catch (error) { - console.error("[TempVC] Error creating temporary channel:", error); - } - } - - if (oldState.channelId && tempChannels.has(oldState.channelId)) { - const oldChannel = oldState.channel; - - if (oldChannel && oldChannel.members.size === 0) { - try { - await oldChannel.delete(); - tempChannels.delete(oldState.channelId); - console.log(`[TempVC] Deleted empty temporary channel "${oldChannel.name}"`); - } catch (error) { - if (error.code !== 10003) { - console.error("[TempVC] Error deleting temporary channel:", error); - } - tempChannels.delete(oldState.channelId); - } - } - } -}); - -const interactionEvent = new Event("interactionCreate", async (client, interaction) => { - if (!interaction.isButton() && !interaction.isModalSubmit()) return; - if (!interaction.customId.startsWith("tempvc_")) return; - - const channel = interaction.channel; - if (!tempChannels.has(channel.id)) { - return interaction.reply({ content: "This channel is no longer a temporary voice channel.", flags: Discord.MessageFlags.Ephemeral }); - } - - const ownerId = tempChannels.get(channel.id); - const isOwner = interaction.user.id === ownerId || interaction.member.permissions.has(Discord.PermissionFlagsBits.Administrator); - - if (interaction.customId === "tempvc_claim") { - const currentOwnerInVC = channel.members.has(ownerId); - if (currentOwnerInVC && interaction.user.id !== ownerId) { - return interaction.reply({ content: "The owner is still in the voice channel!", flags: Discord.MessageFlags.Ephemeral }); - } - - tempChannels.set(channel.id, interaction.user.id); - await channel.permissionOverwrites.edit(interaction.user.id, { - ManageChannels: true, - MoveMembers: true, - }); - - return interaction.reply({ content: "You are now the owner of this voice channel!", flags: Discord.MessageFlags.Ephemeral }); - } - - if (!isOwner) { - return interaction.reply({ content: "Only the channel owner can use these controls.", flags: Discord.MessageFlags.Ephemeral }); - } - - try { - switch (interaction.customId) { - case "tempvc_lock": - await channel.permissionOverwrites.edit(interaction.guild.id, { Connect: false }); - await interaction.reply({ content: "Channel locked! 🔒", flags: Discord.MessageFlags.Ephemeral }); - break; - case "tempvc_unlock": - await channel.permissionOverwrites.edit(interaction.guild.id, { Connect: null }); - await interaction.reply({ content: "Channel unlocked! 🔓", flags: Discord.MessageFlags.Ephemeral }); - break; - case "tempvc_rename": - const modal = new Discord.ModalBuilder() - .setCustomId("tempvc_modal_rename") - .setTitle("Rename Channel") - .addComponents( - new Discord.ActionRowBuilder().addComponents( - new Discord.TextInputBuilder() - .setCustomId("name") - .setLabel("New Name") - .setStyle(Discord.TextInputStyle.Short) - .setPlaceholder(channel.name) - .setRequired(true) - ) - ); - await interaction.showModal(modal); - break; - case "tempvc_limit": - const limitModal = new Discord.ModalBuilder() - .setCustomId("tempvc_modal_limit") - .setTitle("Set User Limit") - .addComponents( - new Discord.ActionRowBuilder().addComponents( - new Discord.TextInputBuilder() - .setCustomId("limit") - .setLabel("Limit (0-99)") - .setStyle(Discord.TextInputStyle.Short) - .setPlaceholder("0 for no limit") - .setRequired(true) - ) - ); - await interaction.showModal(limitModal); - break; - } - - if (interaction.isModalSubmit()) { - if (interaction.customId === "tempvc_modal_rename") { - const newName = interaction.fields.getTextInputValue("name"); - await channel.setName(newName); - await interaction.reply({ content: `Channel renamed to **${newName}**!`, flags: Discord.MessageFlags.Ephemeral }); - } else if (interaction.customId === "tempvc_modal_limit") { - const limit = parseInt(interaction.fields.getTextInputValue("limit")); - if (isNaN(limit) || limit < 0 || limit > 99) { - return interaction.reply({ content: "Please enter a valid number between 0 and 99.", flags: Discord.MessageFlags.Ephemeral }); - } - await channel.setUserLimit(limit); - await interaction.reply({ content: `User limit set to **${limit === 0 ? "Unlimited" : limit}**!`, flags: Discord.MessageFlags.Ephemeral }); - } - } - } catch (error) { - console.error("[TempVC] Error handling interaction:", error); - if (!interaction.replied) await interaction.reply({ content: "An error occurred.", flags: Discord.MessageFlags.Ephemeral }); - } -}); - -module.exports = [voiceStateUpdate, interactionEvent]; diff --git a/Addons/applicationsystem.js b/Addons/applicationsystem.js deleted file mode 100644 index cb84e34..0000000 --- a/Addons/applicationsystem.js +++ /dev/null @@ -1,652 +0,0 @@ -const Discord = require("discord.js"); -const fs = require("fs"); -const path = require("path"); -const yaml = require("js-yaml"); - -const { Command } = require("../Structures/Addon.js"); - -// Main bot config -const supportbot = yaml.load( - fs.readFileSync("./Configs/supportbot.yml", "utf8") -); - -// Addon config -const addonConfig = yaml.load( - fs.readFileSync("./Addons/Configs/applicationsystem.yml", "utf8") -); - -// Data file -const dataPath = path.join(__dirname, "Data/applicationsystem.json"); - -function ensureDataFile() { - const dir = path.dirname(dataPath); - - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, { recursive: true }); - } - - if (!fs.existsSync(dataPath)) { - fs.writeFileSync( - dataPath, - JSON.stringify({ applications: [] }, null, 2), - "utf8" - ); - } -} - -function readData() { - ensureDataFile(); - - try { - const raw = fs.readFileSync(dataPath, "utf8"); - const parsed = JSON.parse(raw); - - if (!parsed || !Array.isArray(parsed.applications)) { - return { applications: [] }; - } - - return parsed; - } catch (error) { - console.error("[ApplicationSystem] Failed to read data file:", error); - return { applications: [] }; - } -} - -function writeData(data) { - ensureDataFile(); - fs.writeFileSync(dataPath, JSON.stringify(data, null, 2), "utf8"); -} - -function now() { - return Date.now(); -} - -function createId() { - return `app_${Date.now()}_${Math.floor(Math.random() * 100000)}`; -} - -function parseColor(value, fallback = 0x2b2d31) { - if (typeof value === "number") return value; - - if (typeof value === "string") { - const cleaned = value.trim().replace("#", ""); - if (/^[0-9A-Fa-f]{6}$/.test(cleaned)) { - return parseInt(cleaned, 16); - } - } - - return fallback; -} - -function getGeneralColour() { - return parseColor(supportbot?.Embed?.Colours?.General, 0x2b2d31); -} - -function buildNoticeContainer(title, description, colour = 0x5865f2) { - return new Discord.ContainerBuilder() - .setAccentColor(colour) - .addTextDisplayComponents( - new Discord.TextDisplayBuilder().setContent(`## ${title}`) - ) - .addSeparatorComponents(new Discord.SeparatorBuilder()) - .addTextDisplayComponents( - new Discord.TextDisplayBuilder().setContent(description) - ); -} - -function buildPanelContainer() { - const options = Object.entries(addonConfig.Applications || {}) - .slice(0, 25) - .map(([key, app]) => - new Discord.StringSelectMenuOptionBuilder() - .setLabel(String(app.Name || key).slice(0, 100)) - .setDescription( - String(app.Description || "Apply for this position").slice(0, 100) - ) - .setValue(key) - ); - - return new Discord.ContainerBuilder() - .setAccentColor(getGeneralColour()) - .addTextDisplayComponents( - new Discord.TextDisplayBuilder().setContent( - `## ${addonConfig.Panel?.Title || "Applications"}` - ) - ) - .addSeparatorComponents(new Discord.SeparatorBuilder()) - .addTextDisplayComponents( - new Discord.TextDisplayBuilder().setContent( - addonConfig.Panel?.Description || - "Choose an application from the dropdown below." - ) - ) - .addActionRowComponents( - new Discord.ActionRowBuilder().addComponents( - new Discord.StringSelectMenuBuilder() - .setCustomId("appsystem_select") - .setPlaceholder( - addonConfig.Panel?.Placeholder || "Select an application type" - ) - .addOptions(options) - ) - ); -} - -function textInputStyle(style) { - return style === "Paragraph" - ? Discord.TextInputStyle.Paragraph - : Discord.TextInputStyle.Short; -} - -function sanitizeQuestionKey(key) { - return String(key).toLowerCase().replace(/[^a-z0-9_]/g, "_"); -} - -function formatQuestionTitle(key) { - return String(key) - .replace(/_/g, " ") - .replace(/\b\w/g, (char) => char.toUpperCase()); -} - -function buildApplicationModal(typeKey) { - const applicationType = addonConfig.Applications?.[typeKey]; - if (!applicationType) return null; - - const modal = new Discord.ModalBuilder() - .setCustomId(`appsystem_modal_${typeKey}`) - .setTitle(String(applicationType.Name || typeKey).slice(0, 45)); - - const questionEntries = Object.entries(applicationType.Questions || {}).slice(0, 5); - - for (const [key, question] of questionEntries) { - const input = new Discord.TextInputBuilder() - .setCustomId(sanitizeQuestionKey(key)) - .setLabel(String(question.Label || key).slice(0, 45)) - .setPlaceholder(String(question.Placeholder || "Enter your answer").slice(0, 100)) - .setRequired(Boolean(question.Required)) - .setStyle(textInputStyle(question.Style)) - .setMinLength(Number(question.MinLength || 1)) - .setMaxLength(Number(question.MaxLength || 1000)); - - modal.addComponents( - new Discord.ActionRowBuilder().addComponents(input) - ); - } - - return modal; -} - -function buildReviewContainer(application, reviewerText = null, locked = false) { - const statusText = - application.status === "accepted" - ? "Accepted" - : application.status === "rejected" - ? "Rejected" - : "Pending"; - - const answerLines = Object.entries(application.answers || {}) - .map(([key, value]) => `### ${formatQuestionTitle(key)}\n${value}`) - .join("\n\n"); - - const body = [ - `**Applicant:** <@${application.userId}>`, - `**Tag:** ${application.userTag}`, - `**Application Type:** ${application.typeName}`, - `**Application ID:** \`${application.id}\``, - `**Status:** ${statusText}`, - "", - answerLines || "*No answers provided.*", - ].join("\n"); - - const container = new Discord.ContainerBuilder() - .setAccentColor(getGeneralColour()) - .addTextDisplayComponents( - new Discord.TextDisplayBuilder().setContent( - `## ${addonConfig.Review?.Title || "New Application"}` - ) - ) - .addSeparatorComponents(new Discord.SeparatorBuilder()) - .addTextDisplayComponents( - new Discord.TextDisplayBuilder().setContent(body) - ); - - if (reviewerText) { - container - .addSeparatorComponents(new Discord.SeparatorBuilder()) - .addTextDisplayComponents( - new Discord.TextDisplayBuilder().setContent(reviewerText) - ); - } - - container.addActionRowComponents( - new Discord.ActionRowBuilder().addComponents( - new Discord.ButtonBuilder() - .setCustomId(`appsystem_accept_${application.id}`) - .setLabel(addonConfig.Review?.AcceptLabel || "Accept") - .setStyle(Discord.ButtonStyle.Success) - .setDisabled(locked), - new Discord.ButtonBuilder() - .setCustomId(`appsystem_reject_${application.id}`) - .setLabel(addonConfig.Review?.RejectLabel || "Reject") - .setStyle(Discord.ButtonStyle.Danger) - .setDisabled(locked) - ) - ); - - return container; -} - -function getPendingApplication(data, guildId, userId, type) { - return data.applications.find( - (app) => - app.guildId === guildId && - app.userId === userId && - app.type === type && - app.status === "pending" - ); -} - -function getCooldownApplication(data, guildId, userId, type) { - const cooldownMs = - Number(addonConfig.Application?.CooldownHours || 24) * 60 * 60 * 1000; - - return data.applications.find( - (app) => - app.guildId === guildId && - app.userId === userId && - app.type === type && - now() - Number(app.createdAt || 0) < cooldownMs - ); -} - -function memberCanReview(member) { - if (!member) return false; - - if (member.permissions?.has(Discord.PermissionFlagsBits.ManageGuild)) { - return true; - } - - return false; -} - -function registerAddonInteractions(client) { - if (client.__applicationSystemRegistered) return; - client.__applicationSystemRegistered = true; - - client.on("interactionCreate", async (interaction) => { - try { - if (!interaction.guild) return; - - // Application dropdown select - if ( - interaction.isStringSelectMenu() && - interaction.customId === "appsystem_select" - ) { - const typeKey = interaction.values[0]; - const applicationType = addonConfig.Applications?.[typeKey]; - - if (!applicationType) { - return interaction.reply({ - flags: - Discord.MessageFlags.Ephemeral | - Discord.MessageFlags.IsComponentsV2, - components: [ - buildNoticeContainer( - "Invalid Application", - "That application type does not exist.", - 0xed4245 - ), - ], - }); - } - - const data = readData(); - - if (addonConfig.Application?.OneOpenApplicationPerUserPerType) { - const existing = getPendingApplication( - data, - interaction.guild.id, - interaction.user.id, - typeKey - ); - - if (existing) { - return interaction.reply({ - flags: - Discord.MessageFlags.Ephemeral | - Discord.MessageFlags.IsComponentsV2, - components: [ - buildNoticeContainer( - "Application Already Open", - `You already have a pending ${applicationType.Name} application.`, - 0xed4245 - ), - ], - }); - } - } - - const cooldownHit = getCooldownApplication( - data, - interaction.guild.id, - interaction.user.id, - typeKey - ); - - if (cooldownHit && cooldownHit.status !== "pending") { - return interaction.reply({ - flags: - Discord.MessageFlags.Ephemeral | - Discord.MessageFlags.IsComponentsV2, - components: [ - buildNoticeContainer( - "Please Wait", - `You must wait ${addonConfig.Application?.CooldownHours || 24} hours before applying again for ${applicationType.Name}.`, - 0xfee75c - ), - ], - }); - } - - const modal = buildApplicationModal(typeKey); - - if (!modal) { - return interaction.reply({ - flags: - Discord.MessageFlags.Ephemeral | - Discord.MessageFlags.IsComponentsV2, - components: [ - buildNoticeContainer( - "Modal Error", - "The application form could not be created.", - 0xed4245 - ), - ], - }); - } - - return interaction.showModal(modal); - } - - // Application modal submit - if ( - interaction.isModalSubmit() && - interaction.customId.startsWith("appsystem_modal_") - ) { - const typeKey = interaction.customId.replace("appsystem_modal_", ""); - const applicationType = addonConfig.Applications?.[typeKey]; - - if (!applicationType) { - return interaction.reply({ - flags: - Discord.MessageFlags.Ephemeral | - Discord.MessageFlags.IsComponentsV2, - components: [ - buildNoticeContainer( - "Invalid Application", - "That application type no longer exists.", - 0xed4245 - ), - ], - }); - } - - const reviewChannel = interaction.guild.channels.cache.get( - addonConfig.Application?.ReviewChannelId - ); - - if (!reviewChannel) { - return interaction.reply({ - flags: - Discord.MessageFlags.Ephemeral | - Discord.MessageFlags.IsComponentsV2, - components: [ - buildNoticeContainer( - "Configuration Error", - "The review channel was not found. Please contact staff.", - 0xed4245 - ), - ], - }); - } - - const data = readData(); - - if (addonConfig.Application?.OneOpenApplicationPerUserPerType) { - const existing = getPendingApplication( - data, - interaction.guild.id, - interaction.user.id, - typeKey - ); - - if (existing) { - return interaction.reply({ - flags: - Discord.MessageFlags.Ephemeral | - Discord.MessageFlags.IsComponentsV2, - components: [ - buildNoticeContainer( - "Application Already Open", - `You already have a pending ${applicationType.Name} application.`, - 0xed4245 - ), - ], - }); - } - } - - const answers = {}; - const questionEntries = Object.entries(applicationType.Questions || {}).slice(0, 5); - - for (const [key] of questionEntries) { - const inputKey = sanitizeQuestionKey(key); - answers[inputKey] = interaction.fields.getTextInputValue(inputKey); - } - - const application = { - id: createId(), - type: typeKey, - typeName: applicationType.Name || typeKey, - guildId: interaction.guild.id, - userId: interaction.user.id, - userTag: interaction.user.tag || interaction.user.username, - status: "pending", - createdAt: now(), - reviewerId: null, - reviewedAt: null, - reviewMessageId: null, - answers, - }; - - const reviewMessage = await reviewChannel.send({ - flags: Discord.MessageFlags.IsComponentsV2, - components: [buildReviewContainer(application, null, false)], - }); - - application.reviewMessageId = reviewMessage.id; - data.applications.push(application); - writeData(data); - - return interaction.reply({ - flags: - Discord.MessageFlags.Ephemeral | - Discord.MessageFlags.IsComponentsV2, - components: [ - buildNoticeContainer( - "Application Sent", - `Your ${applicationType.Name} application has been submitted successfully.`, - 0x57f287 - ), - ], - }); - } - - // Review buttons - if ( - interaction.isButton() && - (interaction.customId.startsWith("appsystem_accept_") || - interaction.customId.startsWith("appsystem_reject_")) - ) { - if (!memberCanReview(interaction.member)) { - return interaction.reply({ - flags: - Discord.MessageFlags.Ephemeral | - Discord.MessageFlags.IsComponentsV2, - components: [ - buildNoticeContainer( - "No Permission", - "You do not have permission to review applications.", - 0xed4245 - ), - ], - }); - } - - const isAccept = interaction.customId.startsWith("appsystem_accept_"); - const applicationId = interaction.customId.replace( - isAccept ? "appsystem_accept_" : "appsystem_reject_", - "" - ); - - const data = readData(); - const application = data.applications.find((app) => app.id === applicationId); - - if (!application) { - return interaction.reply({ - flags: - Discord.MessageFlags.Ephemeral | - Discord.MessageFlags.IsComponentsV2, - components: [ - buildNoticeContainer( - "Not Found", - "This application no longer exists in storage.", - 0xed4245 - ), - ], - }); - } - - if (application.status !== "pending") { - return interaction.reply({ - flags: - Discord.MessageFlags.Ephemeral | - Discord.MessageFlags.IsComponentsV2, - components: [ - buildNoticeContainer( - "Already Reviewed", - `This application has already been ${application.status}.`, - 0xfee75c - ), - ], - }); - } - - application.status = isAccept ? "accepted" : "rejected"; - application.reviewerId = interaction.user.id; - application.reviewedAt = now(); - writeData(data); - - const reviewerText = [ - `### Review Result`, - `**Decision:** ${isAccept ? "Accepted" : "Rejected"}`, - `**Reviewer:** <@${interaction.user.id}>`, - `**Reviewed At:** `, - ].join("\n"); - - await interaction.update({ - flags: Discord.MessageFlags.IsComponentsV2, - components: [ - buildReviewContainer(application, reviewerText, true), - ], - }); - - const applicationType = addonConfig.Applications?.[application.type]; - - if (isAccept && applicationType?.AcceptedRoleId) { - const member = await interaction.guild.members - .fetch(application.userId) - .catch(() => null); - - if (member) { - await member.roles.add(applicationType.AcceptedRoleId).catch(() => null); - } - } - - const applicantUser = await interaction.client.users - .fetch(application.userId) - .catch(() => null); - - if (applicantUser) { - await applicantUser - .send({ - flags: Discord.MessageFlags.IsComponentsV2, - components: [ - buildNoticeContainer( - isAccept ? "Application Accepted" : "Application Rejected", - isAccept - ? `Congratulations! Your ${application.typeName} application in **${interaction.guild.name}** has been accepted.` - : `Your ${application.typeName} application in **${interaction.guild.name}** has been rejected.`, - isAccept ? 0x57f287 : 0xed4245 - ), - ], - }) - .catch(() => null); - } - - return; - } - } catch (error) { - console.error("[ApplicationSystem] Interaction error:", error); - - if (interaction.deferred || interaction.replied) { - return; - } - - return interaction - .reply({ - flags: - Discord.MessageFlags.Ephemeral | - Discord.MessageFlags.IsComponentsV2, - components: [ - buildNoticeContainer( - "Error", - "Something went wrong while handling that application interaction.", - 0xed4245 - ), - ], - }) - .catch(() => null); - } - }); -} - -module.exports = new Command({ - name: addonConfig.Command?.Name || "applicationsetup", - description: - addonConfig.Command?.Description || "Posts the application panel", - options: [], - permissions: addonConfig.Command?.Permission || ["ManageGuild"], - - async run(interaction) { - registerAddonInteractions(interaction.client); - - await interaction.channel.send({ - flags: Discord.MessageFlags.IsComponentsV2, - components: [buildPanelContainer()], - }); - - return interaction.reply({ - flags: - Discord.MessageFlags.Ephemeral | - Discord.MessageFlags.IsComponentsV2, - components: [ - buildNoticeContainer( - "Application Panel Posted", - "The application panel has been posted in this channel.", - 0x57f287 - ), - ], - }); - }, -}); \ No newline at end of file diff --git a/Addons/calculator.js b/Addons/calculator.js deleted file mode 100644 index b6c7f95..0000000 --- a/Addons/calculator.js +++ /dev/null @@ -1,83 +0,0 @@ -const Discord = require("discord.js"); -const fs = require("fs"); -const yaml = require("js-yaml"); -const { Command } = require('../Structures/Addon.js'); // Adjust the path as needed -const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8")); - -module.exports = new Command({ - name: "calculator", - description: "Use a calculator to solve your math problems.", - options: [], - permissions: ["SendMessages"], - - async run(interaction) { - let expression = ""; - let history = ""; - - const createButton = (label, customId) => { - return new Discord.ButtonBuilder() - .setLabel(label) - .setCustomId(customId) - .setStyle(Discord.ButtonStyle.Secondary); - }; - - const createRow = (buttons) => { - return new Discord.ActionRowBuilder().addComponents(buttons); - }; - - const rows = [ - createRow([createButton('7', '7'), createButton('8', '8'), createButton('9', '9'), createButton('/', '/')]), - createRow([createButton('4', '4'), createButton('5', '5'), createButton('6', '6'), createButton('*', '*')]), - createRow([createButton('1', '1'), createButton('2', '2'), createButton('3', '3'), createButton('-', '-')]), - createRow([createButton('0', '0'), createButton('.', '.'), createButton('=', '='), createButton('+', '+')]), - createRow([createButton('Clear', 'clear')]) - ]; - - const embed = new Discord.EmbedBuilder() - .setTitle('Calculator') - .setDescription('Calculator') - .setColor(supportbot.Embed.Colours.General); - - const message = await interaction.reply({ - embeds: [embed], - components: rows, - fetchReply: true - }); - - const filter = i => i.user.id === interaction.user.id; - const collector = message.createMessageComponentCollector({ filter, time: 60000 }); - - collector.on('collect', async i => { - if (i.customId === 'clear') { - expression = ""; - history = ""; - } else if (i.customId === '=') { - try { - const result = eval(expression).toString(); - history += `${expression} = ${result}\n`; - expression = result; - } catch { - expression = "Error"; - } - } else { - if (history.endsWith(`${expression} = ${expression}\n`)) { - history += `\n`; - expression = i.customId; - } else { - expression += i.customId; - } - } - - await i.update({ - embeds: [new Discord.EmbedBuilder().setTitle('Calculator').setDescription(`\`\`\`${history}${expression}\`\`\``).setColor(supportbot.Embed.Colours.General)], - components: rows - }); - }); - - collector.on('end', collected => { - message.edit({ - components: [] - }); - }); - }, -}); diff --git a/Addons/discord-stats.js b/Addons/discord-stats.js deleted file mode 100644 index 1299b91..0000000 --- a/Addons/discord-stats.js +++ /dev/null @@ -1,139 +0,0 @@ -// SupportBot | Emerald Services -// Discord Stats addon | Created by Xiled Emerald - -const fs = require("fs"); - -const Discord = require("discord.js"); -const yaml = require("js-yaml"); -const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8")); - -// If you need to read something from the main config! -const cmdconfig = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8")); - -// This is for your Addon Configuration -const config = yaml.load(fs.readFileSync('./Addons/Configs/discord-stats.yml', 'utf8')); - -const { Command, Event } = require("../Structures/Addon"); - -module.exports.commands = [ - - new Command({ - name: "stats", - description: "Create the discord statistic channels", - options: [], - permissions: ["SEND_MESSAGES"], - async run(interaction) { - const guild = interaction.guild; - const statsCategory = guild.channels.cache.find( - (category) => - category.name === config.StatsCategory || - category.id === config.StatsCategory - ); - - if (!statsCategory) { - const errorEmbed = new Discord.MessageEmbed() - .setTitle("Invalid Category") - .setDescription( - `${supportbot.InvalidChannel}\n\n**Category Required:** \`${config.StatsCategory}\`` - ) - .setColor(supportbot.ErrorColour); - - interaction.reply({ - embeds: [errorEmbed], - ephemeral: true, - }); - return; - } - - const guildName = guild.name; - const userCount = guild.memberCount; - const roleCount = guild.roles.cache.size; - const channelCount = guild.channels.cache.size; - - try { - const guildNameChannel = await guild.channels.create(guildName, { - type: "GUILD_VOICE", - }); - - const userCountChannel = await guild.channels.create( - `${config.UserCount_Name} ${userCount}`, - { - type: "GUILD_VOICE", - } - ); - - const channelCountChannel = await guild.channels.create( - `${config.ChannelCount_Name} ${channelCount}`, - { - type: "GUILD_VOICE", - } - ); - - const roleCountChannel = await guild.channels.create( - `${config.RoleCount_Name} ${roleCount}`, - { - type: "GUILD_VOICE", - } - ); - - guildNameChannel.permissionOverwrites.edit(guild.id, { - VIEW_CHANNEL: true, - CONNECT: false, - }); - - userCountChannel.permissionOverwrites.edit(guild.id, { - VIEW_CHANNEL: true, - CONNECT: false, - }); - - channelCountChannel.permissionOverwrites.edit(guild.id, { - VIEW_CHANNEL: true, - CONNECT: false, - }); - - roleCountChannel.permissionOverwrites.edit(guild.id, { - VIEW_CHANNEL: true, - CONNECT: false, - }); - - userCountChannel.setParent(statsCategory.id); - roleCountChannel.setParent(statsCategory.id); - guildNameChannel.setParent(statsCategory.id); - channelCountChannel.setParent(statsCategory.id); - - const successEmbed = new Discord.MessageEmbed() - .setDescription(":white_check_mark: **[DISCORD STATS]** Channels created successfully!") - .setColor(supportbot.EmbedColour); - - interaction.reply({ - embeds: [successEmbed], - ephemeral: true, - }); - - setInterval(() => { - userCountChannel.setName( - `${config.UserCount_Name} ${userCount}` - ); - channelCountChannel.setName( - `${config.ChannelCount_Name} ${channelCount}` - ); - roleCountChannel.setName( - `${config.RoleCount_Name} ${roleCount}` - ); - }, 30000); - } catch (error) { - console.error(error); - const errorEmbed = new Discord.MessageEmbed() - .setTitle("Error") - .setDescription("An error occurred while creating the stats channels.") - .setColor(supportbot.ErrorColour); - - interaction.reply({ - embeds: [errorEmbed], - ephemeral: true, - }); - } - }, - }), - -]; diff --git a/Addons/vouchley.js b/Addons/vouchley.js deleted file mode 100644 index e6a8d26..0000000 --- a/Addons/vouchley.js +++ /dev/null @@ -1,292 +0,0 @@ -const Discord = require("discord.js"); -const fs = require("fs"); -const yaml = require("js-yaml"); -const fetch = require("node-fetch"); -const { Command } = require('../Structures/Addon.js'); - -const supportbot = yaml.load(fs.readFileSync("./Configs/supportbot.yml", "utf8")); -const vouchleyaddon = yaml.load(fs.readFileSync("./Addons/Configs/vouchley.yml", "utf8")); - -function formatURL(url) { - if (!url) return 'https://www.vouchley.com'; - if (!url.startsWith('http://') && !url.startsWith('https://')) { - return `https://${url}`; - } - return url; -} - -function formatDate(timestamp) { - return ``; -} - -function createReviewEmbed(review, username, currentPage, totalReviews) { - const embed = new Discord.EmbedBuilder() - .setTitle(`Review for ${username}`) - .setColor(vouchleyaddon.Embed.Colour); - - const fields = [ - { - name: "Rating", - value: "⭐".repeat(Math.min(Math.max(review.rating, 1), 5)) || "No rating", - inline: false - }, - { - name: "Platform", - value: review.platform?.toString() || "Not specified", - inline: true - }, - { - name: "Date", - value: formatDate(review.time_sent), - inline: true - } - ]; - - if (review.message && review.message.trim()) { - fields.push({ - name: "Review", - value: `\`\`\`${review.message.substring(0, 1024)}\`\`\``, - inline: false - }); - } - - embed.addFields(fields); - embed.setFooter({ text: `Review ${currentPage + 1} of ${totalReviews}` }); - - return embed; -} - -function createReviewNavigation(currentPage, totalReviews) { - return new Discord.ActionRowBuilder() - .addComponents( - new Discord.ButtonBuilder() - .setCustomId('prev_review') - .setLabel('Previous') - .setStyle(Discord.ButtonStyle.Primary) - .setDisabled(currentPage === 0), - new Discord.ButtonBuilder() - .setCustomId('next_review') - .setLabel('Next') - .setStyle(Discord.ButtonStyle.Primary) - .setDisabled(currentPage === totalReviews - 1), - new Discord.ButtonBuilder() - .setCustomId('back_to_profile') - .setLabel('Back to Profile') - .setStyle(Discord.ButtonStyle.Secondary) - ); -} - -const activeReviews = new Map(); - -module.exports = new Command({ - name: vouchleyaddon.Command.Name, - description: vouchleyaddon.Command.Description, - options: [ - { - name: "search_type", - description: "How do you want to search for the user?", - type: 3, - required: true, - choices: [ - { name: "Vouchley ID", value: "id" }, - { name: "Vouchley Username", value: "username" }, - ] - }, - { - name: "query", - description: "Enter the ID, username, or Discord ID to search", - type: 3, - required: true - } - ], - permissions: vouchleyaddon.Command.Permissions, - - async run(interaction) { - const searchType = interaction.options.getString("search_type"); - const query = interaction.options.getString("query"); - - try { - let apiUrl; - switch (searchType) { - case "id": - apiUrl = `https://www.vouchley.com/api/v1/user?id=${query}`; - break; - case "username": - apiUrl = `https://www.vouchley.com/api/v1/user?username=${query}`; - break; - } - - const response = await fetch(apiUrl, { - headers: { - 'Authorization': `Bearer ${vouchleyaddon.Vouchley.API_Key}`, - 'Content-Type': 'application/json', - } - }); - - const data = await response.json(); - - if (!response.ok || (data.error && data.error.code !== 200)) { - return interaction.reply({ - content: `Error: ${data.error?.message || 'Failed to fetch user data'}`, - ephemeral: vouchleyaddon.Embed.Ephemeral - }); - } - - const user = data.user; - - const profileEmbed = new Discord.EmbedBuilder() - .setTitle(`${user.username} - ${String(user.title || "N/A")}`) - .setColor(vouchleyaddon.Embed.Colour) - .setThumbnail(user.avatar_url) - .addFields([ - { - name: "Discord", - value: `<@${String(user.discord_id)}> (\`${String(user.discord_id)}\`)`, - inline: false - }, - { - name: "Average Rating", - value: `${String(user.average_rating)} (\`${String(user.reviews.length)} Reviews\`)`, - inline: false - } - ]); - - const profileButtons = [ - new Discord.ButtonBuilder() - .setLabel(`Review ${user.username}`) - .setURL(`https://www.vouchley.com/review?user=${user.username}`) - .setStyle(Discord.ButtonStyle.Link) - ]; - - if (user.website) { - profileButtons.push( - new Discord.ButtonBuilder() - .setLabel('Visit Website') - .setURL(formatURL(user.website)) - .setStyle(Discord.ButtonStyle.Link) - ); - } - - if (user.reviews && user.reviews.length > 0) { - profileButtons.push( - new Discord.ButtonBuilder() - .setCustomId('seereviews') - .setLabel('See Reviews') - .setEmoji("⭐") - .setStyle(Discord.ButtonStyle.Secondary) - ); - } - - const profileRow = new Discord.ActionRowBuilder() - .addComponents(profileButtons); - - const message = await interaction.reply({ - embeds: [profileEmbed], - components: [profileRow], - fetchReply: true, - ephemeral: vouchleyaddon.Embed.Ephemeral - }); - - if (user.reviews && user.reviews.length > 0) { - activeReviews.set(message.id, { - reviews: user.reviews, - currentPage: 0, - username: user.username, - profileEmbed, - profileRow - }); - - const collector = message.createMessageComponentCollector({ - time: 600000 - }); - - collector.on('collect', async i => { - const reviewData = activeReviews.get(message.id); - if (!reviewData) return; - - switch (i.customId) { - case 'seereviews': { - const review = reviewData.reviews[reviewData.currentPage]; - const reviewEmbed = createReviewEmbed( - review, - reviewData.username, - reviewData.currentPage, - reviewData.reviews.length - ); - const reviewNav = createReviewNavigation( - reviewData.currentPage, - reviewData.reviews.length - ); - await i.update({ - embeds: [reviewEmbed], - components: [reviewNav], - ephemeral: vouchleyaddon.Embed.Ephemeral - }); - break; - } - case 'prev_review': { - if (reviewData.currentPage > 0) { - reviewData.currentPage--; - const review = reviewData.reviews[reviewData.currentPage]; - const reviewEmbed = createReviewEmbed( - review, - reviewData.username, - reviewData.currentPage, - reviewData.reviews.length - ); - const reviewNav = createReviewNavigation( - reviewData.currentPage, - reviewData.reviews.length - ); - await i.update({ - embeds: [reviewEmbed], - components: [reviewNav], - ephemeral: vouchleyaddon.Embed.Ephemeral - }); - } - break; - } - case 'next_review': { - if (reviewData.currentPage < reviewData.reviews.length - 1) { - reviewData.currentPage++; - const review = reviewData.reviews[reviewData.currentPage]; - const reviewEmbed = createReviewEmbed( - review, - reviewData.username, - reviewData.currentPage, - reviewData.reviews.length - ); - const reviewNav = createReviewNavigation( - reviewData.currentPage, - reviewData.reviews.length - ); - await i.update({ embeds: [reviewEmbed], components: [reviewNav] }); - } - break; - } - case 'back_to_profile': { - await i.update({ - embeds: [reviewData.profileEmbed], - components: [reviewData.profileRow] - }); - break; - } - } - }); - - collector.on('end', () => { - activeReviews.delete(message.id); - }); - } - - } catch (error) { - console.error(error); - if (!interaction.replied) { - await interaction.reply({ - content: "There was an error fetching Vouchley user data.", - ephemeral: vouchleyaddon.Embed.Ephemeral - }); - } - } - } -}); diff --git a/Data/ai-memory.db b/Data/ai-memory.db new file mode 100644 index 0000000000000000000000000000000000000000..c9cf4b4e788deb2a37a4a5eef5db1c380729a4e1 GIT binary patch literal 4096 zcmWFz^vNtqRY=P(%1ta$FlG>7U}9o$P*7lCU|@t|AVoG{WYC*>nir&9fNV2HHI9bB nXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDP#6LLLQ)5D literal 0 HcmV?d00001 diff --git a/Data/ai-memory.db-shm b/Data/ai-memory.db-shm new file mode 100644 index 0000000000000000000000000000000000000000..423b95bb8e39ba570528873fa5cb5aaf1bbbe722 GIT binary patch literal 32768 zcmeI)F-`(O6b9e{g;lYjL_)F^C0DSt@&Y#Az%#%JD7lZ9@BnsHRyH*Ho|za*En&Vt zd70hKW_I4U{hPh7N@f%_C}lc{wTn93uW$F8x5xft{<2#v?_NK;+8$G=N_y9}c)qVoE(uJv4HT<`O2LVy4P0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlya4rIam@_dh zSLNnh8qx=WKMUl%6(P{3Ku#JG0&NQ9TrDBcrhqAOZT@#%r@%D^0?i8KBvK(jfB*pk v1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyaGC<&iwz@m literal 0 HcmV?d00001 diff --git a/Data/ai-memory.db-wal b/Data/ai-memory.db-wal new file mode 100644 index 0000000000000000000000000000000000000000..98ccbd80463eb8cf48e8272fd107a241acc0a5f1 GIT binary patch literal 45352 zcmeI*O^g#|9LMoaUlU$7B$!l)WCzJA1XdCuYB0WZO=A{Hf!d91V$uxl!|uSmKxc|_ zLdufWc=4ha^@cZJ4klha7%{|yCod*?@W8?7$%KQ6o_wC!PBR@^+9G?P`<-OB^UPbP zpWW_e`u{!8JbNYEPR!nZG?CbrP}B5ZJM9l2o7pj^-FbTZ)bF-jq(zti^xo>%ZsnzO zubnEHzR=IQP22GGLvrtAGV!vm%WaeLE2Z}7Oltph*pQFG@gnVhv&qC$AN;sgu1QYa zNKE}LzcC?z00IagfB*srAbyVo&naX{|5ubtC!`Po_RS|K>5VbWi?@?KM~$!5 z_iobVWH$8qa<%wsv7(=>%pWgQ7WHGrMZK_4JuzRF2RL3VR}TbRF11XnQIp$Oi>Et_ z>dS`X2&;Et%M;DsB~8~7!Crd#L{%>@luBzylxOb?$M3tUDGXmUYVztnJiTyVc{2MX zxw_8peqQkD$G^OD^XP6(U9)#SN>Fo52q1s}0tg_000IagfB*srATXH%s`j4>a|CC8 zHILl6ed{ov3ryw@n^%PZ0tg_000IagfB*srAb>zjpr;?fBQH#Ue*L#Ewh!q?5bZah z@&?iNSp5i6TfYqY5y%H71Q0*~0R#|0009ILKmdW^0#}=t@bqxs@F;L2mCnfv#KsbgH5qqM4oBEKB;nxS zxX!qP>KZ>2<^{ALKASmq`uZE>1vb>5V_qx*2q1s}0tg_000IagfWXET=*bHhg>U~^ zo_c?ENM0Zt;R^a8MA~DGFOb<>?dApKEE56XFfsp*cp(TNfB*srAbo@b3QMw%ZU^ zWH;50G%dsPYqmUJV@cEuU+)xeJ5MpVOYTTTUGf6Dt`8Ywp1c5gfrV0Or1ul|BUsn_ w5vXhYT$mTwa^=N;OFzH;CwYN~;omXmhyVfzAbf&a7{GCFTl1$nj-mo9?B7f{Pg3YA4~Bnj7DxOzA^3? zrfED8!Z3`x`n9TG#g-f|6$kp$EbU*nd)N5-&%bZ4|7$cGpBd}-*Z*2OTKi}9+1lsL zKblV(@0xX8%!U902q1s}0tg`RzY6r4b!&6eoLaHl8%ibP*bfG(_*^|WvD;l+blXo4 zZBdkp-GCGgrAAxFgxp zU)`HNtfw~TUzBaeZXkzw&*}ck%-PB{pA3d*zwG|dIo6Gj?BiT)B$aXpau%(B<_5aU zxxz@gvGg2$tB?me!Tas!<+`=8Vg9~c8gU*-Rl8!G>dNpf=FDO!RqVzSl}1}Uv%hP< zJnV{{a4dtJEcpF}0p>|D*7-Lx@T^=-daq?aE~SqrRX_5_u^$FSy0*l-(C^EGOr(=1 zoABh=jpC6EvgViL8OT6J?r^6i#*rUJe*9r>z$5ATlaa1>{iD#6c95*J%e7NX>{0TC z`CeVW`(Z4z0qg3#?bED_q(NTNz6eoE=ycTK2!nQ@e$`7XZ=B`KvCg~Mg2|{SqqJ!6 zt6I%!Z+v=LsA5H^`qa9aUOUdsG!e#8_{!Ipkm7S`CKZa(JQvEbUd)7^A7+D0uO+cR zk{`n$A9q^RABOrG;&p-|F)zaLC`r+WOEv3Y^SX%?Lvi+tz2)hbX5HG_GSBa2D|<2+ zWQIyz?%tT0P^qHG?=zi_Ua^E0XQi(&XW`t%Dwgld>3C(rA7oj+lg#Y#jhfZjx^8Br zF**CCgPZy%W+nNVxt+Y-N#58HKmY**5I_I{1Q0*~0R#|0psE6mWMbU^S2euM3jqWW zKmY**5I_I{1Q0*~fmDF!|0Dte2q1s}0tg_000IagfB*v37vTAS^<&Ho5kLR|1Q0*~ z0R#|0009IL;Q2o}fB*srAb0q*~+A7f^S00IagfB*srAb