diff --git a/commands/alarm.js b/commands/alarm.js new file mode 100644 index 0000000..dcf4f02 --- /dev/null +++ b/commands/alarm.js @@ -0,0 +1,273 @@ +const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js'); +const bitfieldCalculator = require('discord-bitfield-calculator'); + +module.exports = { + name: "alarm", + debug: false, + global: false, + description: "Create a Zone Ping Alarm", + usage: "[cmd] [opt]", + permissions: { + channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], + member: ["MANAGE_GUILD"], + }, + options: [ + { + name: "create", + description: "Create a new Zone Ping Alarm", + value: "create", + type: 1, + options: [ + { + name: "x-coord", + description: "X Coordinate of the origin", + value: "x-coord", + type: 10, + min_value: 0.01, + required: true, + }, + { + name: "y-coord", + description: "Y Coordinate of the origin", + value: "y-coord", + type: 10, + min_value: 0.01, + required: true, + }, + { + name: "radius", + description: "Radius of Zone Alarm", + value: "radius", + type: 10, + min_value: 25.00, + required: true, + }, + { + name: "name", + description: "Zone Alarm Name", + value: "name", + type: 3, + required: true, + }, + { + name: "channel", + description: "Channel for Zone Alarm Pings", + value: "channel", + type: 7, + required: true, + }, + { + name: "role", + description: "Role to Ping on Zone Alarm", + value: "role", + type: 8, + required: true, + } + ] + }, + { + name: "delete", + description: "Delete a Zone Alarm", + value: "delete", + type: 1, + options: [{ + name: "name", + description: "Name of the Zone Alarm to Delete", + value: "name", + type: 3, + required: true, + }] + }, + { + name: "add-player", + description: "Add Player to be Ignored in a Zone Alarm Pings", + value: "add-player", + type: 1, + options: [{ + name: "alarm-name", + description: "Name of the Zone Alarm to add player to", + value: "alarm-name", + type: 3, + required: true, + }, { + name: "gamertag", + description: "Gamertag of Player to Ignore", + value: "gamertag", + type: 3, + required: true, + }] + }, + { + name: "remove-player", + description: "Remove a Player from being Ignored in a Zone Alarm Pings", + value: "remove-player", + type: 1, + options: [{ + name: "alarm-name", + description: "Name of the Zone Alarm to add player to", + value: "alarm-name", + type: 3, + required: true, + }, { + name: "gamertag", + description: "Gamertag of Player to Ignore", + value: "gamertag", + type: 3, + required: true, + }] + } + ], + SlashCommand: { + /** + * + * @param {require("../structures/QuarksBot")} client + * @param {import("discord.js").Message} message + * @param {string[]} args + * @param {*} param3 + */ + run: async (client, interaction, args, { GuildDB }) => { + const permissions = bitfieldCalculator.permissions(interaction.member.permissions); + let canUseCommand = false; + + if (permissions.includes("MANAGE_GUILD")) canUseCommand = true; + if (GuildDB.hasBotAdmin && interaction.member.roles.filter(e => GuildDB.botAdminRoles.indexOf(e) !== -1).length > 0) canUseCommand = true; + if (!canUseCommand) return interaction.send({ content: 'You don\'t have the permissions to use this command.' }); + + if (args[0].name == 'create') { + if (args[0].options[3].value.includes('-') || args[0].options[3].value.includes(' ')) return interaction.send({ embeds: [new EmbedBuilder().setColor(client.config.Colors.Red).setDescription('**Invalid Name:** Alarm Names cannot include hyphens or spaces.')] }) + + let alarm = { + origin: [args[0].options[0].value, args[0].options[1].value], + radius: args[0].options[2].value, + name: args[0].options[3].value, + channel: args[0].options[4].value, + role: args[0].options[5].value, + ignoredPlayers: [], + }; + + client.dbo.collection('guilds').updateOne({ 'server.serverID': GuildDB.serverID }, { + $push: { + 'server.alarms': alarm, + } + }, function (err, res) { + if (err) return client.sendInternalError(interacion, err); + }); + + let successEmbed = new EmbedBuilder() + .setColor(client.config.Colors.Green) + .setDescription(`**Success:** Successfully set **${alarm.name}** in <#${alarm.channel}>`); + + return interaction.send({ embeds: [successEmbed] }); + + } else if (args[0].name == 'delete') { + + let alarm = GuildDB.alarms.find(alarm => alarm.name == args[0].options[0].value); + if (!alarm) return interaction.send({ embeds: [new EmbedBuilder().setColor(client.config.Colors.Red).setDescription(`**Not Found!** Alarm ${args[0].options[0].value} is not an existing alarm name.`)] }); + + const prompt = new EmbedBuilder() + .setTitle(`Are you sure you want to delete this Zone Alarm?`) + .setColor(client.config.Colors.Default) + + const opt = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId(`DeleteAlarm-yes-${args[0].options[0].value}-${interaction.member.user.id}`) + .setLabel("Yes") + .setStyle(ButtonStyle.Danger), + new ButtonBuilder() + .setCustomId(`DeleteAlarm-no-${args[0].options[0].value}-${interaction.member.user.id}`) + .setLabel("No") + .setStyle(ButtonStyle.Success) + ) + + return interaction.send({ embeds: [prompt], components: [opt], flags: (1 << 6) }); + + } else if (args[0].name == 'add-player') { + let alarm = GuildDB.alarms.find(alarm => alarm.name == args[0].options[0].value); + if (!alarm) return interaction.send({ embeds: [new EmbedBuilder().setColor(client.config.Colors.Red).setDescription(`**Not Found!** Alarm ${args[0].options[0].value} is not an existing alarm name.`)] }); + let alarmIndex = GuildDB.alarms.indexOf(alarm); + + let playerStat = GuildDB.playerstats.find(stat => stat.player == args[0].options[1].value) + if (playerStat == undefined) return interaction.send({ embeds: [new EmbedBuilder().setColor(client.config.Colors.Yellow).setDescription('**Not Found** This player cannot be found, the gamertag may be incorrect or this player has not logged onto the server before.')] }) + + alarm.ignoredPlayers.push(playerStat.playerID); + + GuildDB.alarms[alarmIndex] = alarm; + + client.dbo.collection('guilds').updateOne({ 'server.serverID': GuildDB.serverID }, { + $set: { + 'server.alarms': GuildDB.alarms, + } + }, function (err, res) { + if (err) return client.sendInternalError(interacion, err); + }); + + let successEmbed = new EmbedBuilder() + .setColor(client.config.Colors.Green) + .setDescription(`**Success:** Successfully added **${args[0].options[1].value}** to **${alarm.name}**`); + + return interaction.send({ embeds: [successEmbed] }); + } else if (args[0].name == 'remove-player') { + + let alarm = GuildDB.alarms.find(alarm => alarm.name == args[0].options[0].value); + if (!alarm) return interaction.send({ embeds: [new EmbedBuilder().setColor(client.config.Colors.Red).setDescription(`**Not Found!** Alarm ${args[0].options[0].value} is not an existing alarm name.`)] }); + let alarmIndex = GuildDB.alarms.indexOf(alarm); + + let playerStat = GuildDB.playerstats.find(stat => stat.player == args[0].options[1].value) + if (playerStat == undefined) return interaction.send({ embeds: [new EmbedBuilder().setColor(client.config.Colors.Yellow).setDescription('**Not Found** This player cannot be found, the gamertag may be incorrect or this player has not logged onto the server before.')] }) + if (!alarm.includes(playerStat.playerID)) return interaction.send({ embeds: [new EmbedBuilder().setColor(client.config.Colors.Yellow).setDescription(`**Not Found** This Player is not added to the Ignored Player list for the Zone Alarm **${alarm.name}**`)] }) + + alarm.ignoredPlayers = alarm.ignoredPlayers.filter(function(value, index, arr){ + return value != args[0].options[1].value; + }); + + GuildDB.alarms[alarmIndex] = alarm; + + client.dbo.collection('guilds').updateOne({ 'server.serverID': GuildDB.serverID }, { + $set: { + 'server.alarms': GuildDB.alarms, + } + }, function (err, res) { + if (err) return client.sendInternalError(interacion, err); + }); + + let successEmbed = new EmbedBuilder() + .setColor(client.config.Colors.Green) + .setDescription(`**Success:** Successfully added **${args[0].options[1].value}** to **${alarm.name}**`); + + return interaction.send({ embeds: [successEmbed] }); + } + }, + }, + + Interactions: { + DeleteAlarm: { + run: async(client, interaction, GuildDB) => { + + if (interaction.customId.split('-')[1] == 'yes') { + let alarm = GuildDB.alarms.find(alarm => alarm.name == interaction.customId.split('-')[2]); + + client.dbo.collection('guilds').updateOne({ 'server.serverID': GuildDB.serverID }, { + $pull: { + 'server.alarms': alarm, + } + }, function (err, res) { + if (err) return client.sendInternalError(interacion, err); + }); + + let successEmbed = new EmbedBuilder() + .setColor(client.config.Colors.Green) + .setDescription(`**Success:** Successfully Deleted **${interaction.customId.split('-')[2]}**`); + + return interaction.send({ embeds: [successEmbed] }); + } else { + let successEmbed = new EmbedBuilder() + .setColor(client.config.Colors.Green) + .setDescription(`The Zone Alarm **${interaction.customId.split('-')[2]}** will not be deleted.`); + + return interaction.send({ embeds: [successEmbed] }); + } + } + } + } +} diff --git a/package.json b/package.json index 04b6711..fe180d1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dayz-armbands", - "version": "5.2.2.4", + "version": "5.3.0.5", "description": "A General Purpose Discord Bot for DayZ Servers.", "main": "index.js", "nodemonConfig": { diff --git a/structures/DayzArmbands.js b/structures/DayzArmbands.js index 8f8e916..ab23b3f 100644 --- a/structures/DayzArmbands.js +++ b/structures/DayzArmbands.js @@ -50,7 +50,7 @@ class DayzArmbands extends Client { $unset: { [`server.factionArmbands.${factionID}`]: "" }, }; await this.dbo.collection("guilds").updateOne({'server.serverID': GuildDB.serverID}, query, function (err, res) { - if (err) return client.sendInternalError(interaction, err); + if (err) return this.sendInternalError(interaction, err); }); } } @@ -158,7 +158,9 @@ class DayzArmbands extends Client { $set: { "server.playerstats": guild.playerstats } - }) + }, function (err, res) { + if (err && this.exists(channel)) return this.sendInternalError(channel, err); + }); let today = new Date(); let newDt = new Date(`${today.toLocaleDateString('default', { month: 'long' })} ${today.getDate()}, ${today.getFullYear()} ${info.time} EST`) @@ -174,12 +176,25 @@ class DayzArmbands extends Client { async handleAlarms(guildId, data) { let guild = await this.GetGuild(guildId); + if (!this.exists(guild.alarms)) { + guild.alarms = []; + this.dbo.collection("guilds").updateOne({ 'server.serverID': guildId }, { + $set: { + 'server.alarms': [], + } + }, function (err, res) { + if (err) this.error(err); + }); + } + for (let i = 0; i < guild.alarms.length; i++) { let alarm = guild.alarms[i]; + if (alarm.ignoredPlayers.includes(data.playerID)) continue; + let diff = [Math.round(alarm.origin[0] - data.pos[0]), Math.round(alarm.origin[1] - data.pos[1])]; let distance = Math.sqrt(Math.pow(diff[0], 2) + Math.pow(diff[1], 2)).toFixed(2) - + if (distance < alarm.radius) { const channel = this.channels.cache.get(alarm.channel); @@ -193,6 +208,7 @@ class DayzArmbands extends Client { .addFields({ name: '**Location**', value: `**[${data.pos[0]}, ${data.pos[1]}](https://www.izurvive.com/chernarusplussatmap/#location=${data.pos[0]};${data.pos[1]})**`, inline: false }) channel.send({ content: `<@&${alarm.role}>`, embeds: [alarmEmbed] }); + break; // we break because no need to check if they are in two alarms at once, can't be in two places at once. } } } @@ -258,12 +274,14 @@ class DayzArmbands extends Client { $set: { "server.playerstats": guild.playerstats } + }, function (err, res) { + if (err) this.error(err); }); this.sendConnectionLogs(guildId, { time: info.time, player: info.player, - conected: info.connected, + connected: info.connected, lastConnectionDate: null, }); } @@ -291,6 +309,8 @@ class DayzArmbands extends Client { $set: { "server.playerstats": guild.playerstats } + }, function (err, res) { + if (err) this.error(err); }); this.sendConnectionLogs(guildId, { @@ -331,6 +351,8 @@ class DayzArmbands extends Client { $set: { "server.playerstats": guild.playerstats } + }, function (err, res) { + if (err) this.error(err); }); } } @@ -557,6 +579,7 @@ class DayzArmbands extends Client { hasBotAdmin: guild.server.botAdminRoles.length > 0 ? true : false, botAdminRoles: guild.server.botAdminRoles, playerstats: guild.server.playerstats, + alarms: guild.server.alarms, }; }