diff --git a/commands/application.js b/commands/application.js deleted file mode 100644 index 54e297a..0000000 --- a/commands/application.js +++ /dev/null @@ -1,71 +0,0 @@ -const { ModalBuilder } = require('discord.js'); - -module.exports = { - name: "application", - debug: false, - global: false, - description: "manage or create applications", - usage: "[cmd] [opts]", - permissions: { - channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], - member: [], - }, - options: [ - { - name: "create", - description: "Create a new application form", - type: 1, - value: "create", - options: [ - { - name: "title", - description: "Application Title", - value: "title", - type: 3, - max: 50, - required: true, - }, - { - name: "description", - description: "Application Description", - value: "description", - type: 3, - max: 250, - required: true, - } - ] - } - ], - SlashCommand: { - /** - * - * @param {require("../structures/QuarksBot")} client - * @param {import("discord.js").Message} message - * @param {string[]} args - * @param {*} param3 - */ - run: async (client, interaction, args, start) => { - if (args[0].name == 'create') { - // Create the modal - const modal = new ModalBuilder() - .setCustomId('model-test') - .setTitle(args[0].options[0].value); - - // Add components to modal - - // Create the text input components - const favoriteColorInput = new TextInputBuilder() - .setCustomId('favoriteColorInput') - // The label is the prompt the user sees for this input - .setLabel(args[0].options[1].value) - // Short means only a single line of text - .setStyle(TextInputStyle.Paragraph); - - // An action row only holds one text input, - // so you need one action row per text input. - const firstActionRow = new ActionRowBuilder().addComponents(favoriteColorInput); - const secondActionRow = new ActionRowBuilder().addComponents(hobbiesInput); - } - }, - }, -} \ No newline at end of file diff --git a/commands/claim.js b/commands/claim.js new file mode 100644 index 0000000..675d6d8 --- /dev/null +++ b/commands/claim.js @@ -0,0 +1,30 @@ +const { TextInputBuilder, ModalBuilder, ActionRowBuilder, TextInputStyle } = require('discord.js'); +const bitfieldCalculator = require('discord-bitfield-calculator'); + +module.exports = { + name: "", + debug: false, + global: false, + description: "", + usage: "[cmd] [opts]", + permissions: { + channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], + member: [], + }, + options: [ + + ], + SlashCommand: { + /** + * + * @param {require("../structures/QuarksBot")} client + * @param {import("discord.js").Message} message + * @param {string[]} args + * @param {*} param3 + */ + run: async (client, interaction, args) => { + + }, + }, + Interactions: {} +} diff --git a/commands/help.js b/commands/help.js index d5ddafe..7fcc1d1 100644 --- a/commands/help.js +++ b/commands/help.js @@ -33,7 +33,7 @@ module.exports = { }, { name: "credits", - description: "Applicantz Credits", + description: "DayzArmbands Credits", value: "credits", type: 1, }, @@ -56,7 +56,7 @@ module.exports = { run: async (client, interaction, args) => { if (args[0].name == 'version') { const versionEmbed = new EmbedBuilder() - .setTitle(`Current Applicantz Version`) + .setTitle(`Current DayzArmbands Version`) .setDescription(client.config.Version); return interaction.send({ embeds: [versionEmbed] }); @@ -72,7 +72,7 @@ module.exports = { .setColor(client.config.Colors.Default) .setDescription(`${Commands.join("\n")} - Applicantz Version: v${client.config.Version}`); + DayzArmbands Version: v${client.config.Version}`); if (!args[0].options[0]) return interaction.send({ embeds: [Embed] }); else { let cmd = @@ -114,9 +114,9 @@ module.exports = { } else if (args[0].name == 'support') { const supportEmbed = new EmbedBuilder() .setColor(client.config.Colors.Default) - .setDescription(`**__Applicantz Support__** + .setDescription(`**__DayzArmbands Support__** - Are you experiencing troubles with Applicantz? + Are you experiencing troubles with DayzArmbands? Do you have questions or concerns? Do you require help to use the bot? Do you have a feature you'd like to see? diff --git a/index.js b/index.js index c08dd95..c51804b 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ -const Applicantz = require('./structures/Applicantz'); +const DayzArmbands = require('./structures/DayzArmbands'); const config = require('./config/config'); const { GatewayIntentBits } = require('discord.js'); -let client = new Applicantz({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages] }, config); +let client = new DayzArmbands({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages] }, config); client.build() diff --git a/package.json b/package.json index 6447c83..02563c6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "applicantz", + "name": "dayz-armbands", "version": "0.0.1", - "description": "Application Handler for Discord", + "description": "A Discord Bot to handle DayZ server flags and armbands for in game factions.", "main": "index.js", "nodemonConfig": { "ignore": ["logs/*.log", "logs/*.json"] diff --git a/structures/Applicantz.js b/structures/DayzArmbands.js similarity index 59% rename from structures/Applicantz.js rename to structures/DayzArmbands.js index f42e9ca..1fc60be 100644 --- a/structures/Applicantz.js +++ b/structures/DayzArmbands.js @@ -7,7 +7,7 @@ const Logger = require("../util/Logger"); const path = require("path"); const fs = require('fs'); -class Applicantz extends Client { +class DayzArmbands extends Client { constructor(options, config) { super(options) @@ -22,6 +22,10 @@ class Applicantz extends Client { "The config.js is not filled out. Please make sure nothing is blank, otherwise the bot will not work properly." ); + this.db; + this.dbo; + this.connectMongo(this.config.mongoURI, this.config.dbo); + this.databaseConnected = false; this.LoadCommandsAndInteractionHandlers(); this.LoadEvents(); @@ -30,12 +34,14 @@ class Applicantz extends Client { this.ws.on("INTERACTION_CREATE", async (interaction) => { const start = new Date().getTime(); if (interaction.type!=3) { + let GuildDB = await this.GetGuild(interaction.guild_id); const command = interaction.data.name.toLowerCase(); const args = interaction.data.options; client.log(`Interaction - ${command}`); + //Easy to send respnose so ;) interaction.guild = await this.guilds.fetch(interaction.guild_id); interaction.send = async (message) => { const rest = new REST({ version: '10' }).setToken(client.config.Token); @@ -48,9 +54,17 @@ class Applicantz extends Client { }); }; + if (!this.databaseConnected) { + let dbFailedEmbed = new EmbedBuilder() + .setDescription(`**Internal Error:**\nUh Oh D: Its not you, its me.\nThe bot has failed to connect to the database 5 times!\nContact the Developers\nhttps://discord.gg/YCXhvy9uZw`) + .setColor(this.config.Colors.Red) + + return interaction.send({ embeds: [dbFailedEmbed] }); + } + let cmd = client.commands.get(command); try { - cmd.SlashCommand.run(this, interaction, args, start); // start is only used in ping / stats command + cmd.SlashCommand.run(this, interaction, args, { GuildDB }, start); // start is only used in ping / stats command } catch (err) { this.sendInternalError(err); } @@ -60,6 +74,46 @@ class Applicantz extends Client { const client = this; } + async connectMongo(mongoURI, dbo) { + let failed = false; + + let dbLogDir = path.join(__dirname, '..', 'logs', 'database-logs.json'); + let databaselogs; + try { + databaselogs = JSON.parse(fs.readFileSync(dbLogDir)); + } catch (err) { + databaselogs = { + attempts: 0, + connected: false, + }; + } + + if (databaselogs.attempts >= 5) { + this.error('Failed to connect to mongodb after multiple attempts'); + return; // prevent further attempts + } + + try { + // Connect to Mongo database. + this.db = await MongoClient.connect(mongoURI, {connectTimeoutMS: 1000}); + this.dbo = this.db.db(dbo); + mongoose.connect(`${mongoURI}/${dbo}`); + this.log('Successfully connected to mongoDB'); + databaselogs.connected = true; + databaselogs.attempts = 0; // reset attempts + this.databaseConnected = true; + } catch (err) { + databaselogs.attempts++; + this.error(`Failed to connect to mongodb: attempt ${databaselogs.attempts}`); + failed = true; + } + + // write JSON string to a file + await fs.writeFileSync(dbLogDir, JSON.stringify(databaselogs)); + + if (failed) process.exit(-1); + } + exists(n) {return null != n && undefined != n && "" != n} secondsToDhms(seconds) { @@ -125,7 +179,7 @@ class Applicantz extends Client { sendInternalError(Interaction, Error) { this.error(Error); const embed = new EmbedBuilder() - .setDescription(`**Internal Error:**\nUh Oh D: Its not you, its me.\nThis command has crashed\nContact the Developers\n${this.config.SupportServer}`) + .setDescription(`**Internal Error:**\nUh Oh D: Its not you, its me.\nThis command has crashed\nContact the Developers\nhttps://discord.gg/YCXhvy9uZw`) .setColor(this.config.Colors.Red) Interaction.send({ embeds: [embed] }); @@ -137,6 +191,39 @@ class Applicantz extends Client { this.guilds.cache.forEach((guild) => RegisterGuildCommands(this, guild.id)); } + getDefaultSettings(GuildId) { + return { + serverID: GuildId, + allowedChannels: [], // list of channels the bot is allowed to be used in + factionArmbands: [], // list of armbands in use + botAdmin: null, // + } + } + + async GetGuild(GuildId) { + let guild = undefined; + if (this.databaseConnected) guild = await this.dbo.collection("guilds").findOne({"server.serverID":GuildId}).then(guild => guild); + + // If guild not found, generate guild default + if (!guild) { + guild = {} + guild.server = this.getDefaultSettings(GuildId); + if (this.databaseConnected) { + this.dbo.collection("guilds").insertOne(guild, function(err, res) { + if (err) throw err; + }); + } + } + + return { + serverID: GuildId, + customChannelStatus: guild.server.allowedChannels.length > 0 ? true : false, // not stored but calculated after + allowedChannels: guild.server.allowedChannels, + factionArmbands: [], + botAdmin: guild.server.botAdmin, + }; + } + log(Text) { this.logger.log(Text); } error(Text) { this.logger.error(Text); } @@ -145,4 +232,4 @@ class Applicantz extends Client { } } -module.exports = Applicantz; \ No newline at end of file +module.exports = QuarksBot; \ No newline at end of file