diff --git a/.gitignore b/.gitignore index 54ab0b0..f958104 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ node_modules/* # Testing/dev related *_test.js dev-*.js +commands/debug.js # Logs logs/* diff --git a/commands/admin-gamertag-link.js b/commands/admin-gamertag-link.js index 09d43c5..5a40787 100644 --- a/commands/admin-gamertag-link.js +++ b/commands/admin-gamertag-link.js @@ -67,9 +67,16 @@ module.exports = { } }) - const role = interaction.guild.roles.cache.get(GuildDB.linkedGamertagRole); - const member = interaction.guild.members.cache.get(interaction.member.user.id); - member.roles.add(role); + let member = interaction.guild.members.cache.get(args[0].value); + if (client.exists(GuildDB.linkedGamertagRole)) { + let role = interaction.guild.roles.cache.get(GuildDB.linkedGamertagRole); + member.roles.add(role); + } + + if (client.exists(GuildDB.memberRole)) { + let role = interaction.guild.roles.cache.get(GuildDB.memberRole); + member.roles.add(role); + } let connectedEmbed = new EmbedBuilder() .setColor(client.config.Colors.Default) diff --git a/commands/config.js b/commands/config.js index 3b89802..793783d 100644 --- a/commands/config.js +++ b/commands/config.js @@ -219,6 +219,20 @@ module.exports = { required: true, }] }, + { + name: "uav-price", + description: "Configure the price of a UAV", + value: "uav-price", + type: 1, + options: [{ + name: "amount", + description: "The amount to set the UAV price", + value: "amount", + type: 10, + min_value: 0.01, + required: true, + }] + }, { name: "income_role", description: "Add/update a role to earn income on /collect-income command", @@ -613,6 +627,16 @@ module.exports = { return interaction.send({ embeds: [prompt], components: [opt], flags: (1 << 6) }); } } + } else if (args[0].name == 'uav-price') { + client.dbo.collection("guilds").updateOne({"server.serverID": GuildDB.serverID}, {$set: {"server.uavPrice":args[0].options[0].value}}, function(err, res) { + if (err) return client.sendInternalError(interaction, err); + }); + + let successEmbed = new EmbedBuilder() + .setColor(client.config.Colors.Green) + .setDescription(`Successfully set $${args[0].options[0].value.toFixed(2)} as UAV price`); + + return interaction.send({ embeds: [successEmbed] }); } }, }, diff --git a/commands/debug.js b/commands/debug.js deleted file mode 100644 index 6d5c094..0000000 --- a/commands/debug.js +++ /dev/null @@ -1,33 +0,0 @@ -const { EmbedBuilder } = require('discord.js'); - -module.exports = { - name: "debug", - debug: true, - global: true, - description: "debug", - usage: "", - 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, { GuildDB }, start) => { - - if (client.config.Dev != 'DEV.') return interaction.send({ content: 'This command is not available to Production Version.' }); - - let embed = new EmbedBuilder() - .setColor(client.config.Colors.Default) - .setDescription(`**Welcome** <@${interaction.member.user.id}> to **DayZ Reforger**\nTo gain access please use the command `); - - interaction.send({ embeds: [embed] }); - }, - }, -} \ No newline at end of file diff --git a/commands/gamertag-link.js b/commands/gamertag-link.js index eccd33c..57413c8 100644 --- a/commands/gamertag-link.js +++ b/commands/gamertag-link.js @@ -52,15 +52,14 @@ module.exports = { } }); + let member = interaction.guild.members.cache.get(interaction.member.user.id); if (client.exists(GuildDB.linkedGamertagRole)) { let role = interaction.guild.roles.cache.get(GuildDB.linkedGamertagRole); - let member = interaction.guild.members.cache.get(interaction.member.user.id); member.roles.add(role); } if (client.exists(GuildDB.memberRole)) { let role = interaction.guild.roles.cache.get(GuildDB.memberRole); - let member = interaction.guild.members.cache.get(interaction.member.user.id); member.roles.add(role); } diff --git a/commands/purchase-uav.js b/commands/purchase-uav.js new file mode 100644 index 0000000..39d36bf --- /dev/null +++ b/commands/purchase-uav.js @@ -0,0 +1,108 @@ +const { EmbedBuilder } = require('discord.js'); +const { User, addUser } = require('../structures/user') + +module.exports = { + name: "purchase-uav", + debug: false, + global: false, + description: "Send a UAV to scout for 30 minutes. (500m range)", + usage: "[cmd] [opt]", + permissions: { + channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], + member: ["MANAGE_GUILD"], + }, + 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, + }, + ], + SlashCommand: { + /** + * + * @param {require("../structures/QuarksBot")} client + * @param {import("discord.js").Message} message + * @param {string[]} args + * @param {*} param3 + */ + run: async (client, interaction, args, { GuildDB }) => { + + let banking = await client.dbo.collection("users").findOne({"user.userID": interaction.member.user.id}).then(banking => banking); + + if (!banking) { + banking = { + userID: interaction.member.user.id, + guilds: { + [GuildDB.serverID]: { + bankAccount: { + balance: GuildDB.startingBalance, + cash: 0.00, + } + } + } + } + + // Register inventory for user + let newBank = new User(); + newBank.createUser(interaction.member.user.id, GuildDB.serverID, GuildDB.startingBalance, 0); + newBank.save().catch(err => { + if (err) return client.sendInternalError(interaction, err); + }); + + } else banking = banking.user; + + if (!client.exists(banking.guilds[GuildDB.serverID])) { + const success = addUser(banking.guilds, GuildDB.serverID, interaction.member.user.id, client, GuildDB.startingBalance); + if (!success) return client.sendInternalError(interaction, 'Failed to add bank'); + } + + if (banking.guilds[GuildDB.serverID].bankAccount.balance.toFixed(2) - GuildDB.uavPrice < 0) { + let embed = new EmbedBuilder() + .setTitle('**Bank Notice:** NSF. Non sufficient funds') + .setColor(client.config.Colors.Red); + + return interaction.send({ embeds: [embed] }); + } + + const newBalance = banking.guilds[GuildDB.serverID].bankAccount.balance - GuildDB.uavPrice; + + client.dbo.collection("users").updateOne({"user.userID":interaction.member.user.id},{$set:{[`user.guilds.${GuildDB.serverID}.bankAccount.balance`]:newBalance}}, function(err, res) { + if (err) return client.sendInternalError(interaction, err); + }); + + let uav = { + origin: [args[0].value, args[1].value], + radius: 250, + owner: interaction.member.user.id, + creationDate: new Date(), + }; + + client.dbo.collection('guilds').updateOne({ 'server.serverID': GuildDB.serverID }, { + $push: { + 'server.uavs': uav, + } + }, function (err, res) { + if (err) return client.sendInternalError(interaction, err); + }); + + let successEmbed = new EmbedBuilder() + .setColor(client.config.Colors.Green) + .setDescription(`**Success:** Successfully deployed a UAV to **[${uav.origin[0]}, ${uav.origin[1]}](https://www.izurvive.com/chernarusplussatmap/#location=${uav.origin[0]};${uav.origin[1]})**\nRange: 500m`); + + return interaction.send({ embeds: [successEmbed], flags: (1 << 6) }); + + }, + } +} diff --git a/package.json b/package.json index 7320bea..1ec9a4e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dayz-armbands", - "version": "6.3.16", + "version": "6.4.1", "description": "A General Purpose Discord Bot for DayZ Servers.", "main": "index.js", "nodemonConfig": { diff --git a/structures/DayzArmbands.js b/structures/DayzArmbands.js index 64dafb2..865253e 100644 --- a/structures/DayzArmbands.js +++ b/structures/DayzArmbands.js @@ -9,11 +9,11 @@ const mongoose = require('mongoose'); const { DownloadNitradoFile } = require('../util/NitradoAPI'); const { HandlePlayerLogs, HandleActivePlayersList } = require('../util/LogsHandler'); const { HandleKillfeed } = require('../util/KillfeedHandler'); +const { HandleExpiredUAVs } = require('../util/AlarmsHandler'); const path = require("path"); const fs = require('fs'); const readline = require('readline'); -const { HandleAlarms } = require("../util/AlarmsHandler"); const minute = 60000; // 1 minute in milliseconds @@ -173,6 +173,7 @@ class DayzArmbands extends Client { c.log('...Downloaded logs...'); await c.readLogs(c.config.GuildID).then(async () => { c.log('...Analyzed logs...'); + HandleExpiredUAVs(c, c.config.GuildID); if (c.activePlayersTick == 12) await HandleActivePlayersList(c, c.config.GuildID); }) }); @@ -318,9 +319,11 @@ class DayzArmbands extends Client { botAdminRoles: [], playerstats: [], alarms: [], + uavs: [], incomeRoles: [], linkedGamertagRole: "", startingBalance: 500, + uavPrice: 50000, memberRole: "", adminRole: "", } @@ -378,6 +381,7 @@ class DayzArmbands extends Client { botAdminRoles: guild.server.botAdminRoles, playerstats: guild.server.playerstats, alarms: guild.server.alarms, + uavs: guild.server.uavs, killfeedChannel: guild.server.killfeedChannel, connectionLogsChannel: guild.server.connectionLogsChannel, welcomeChannel: guild.server.welcomeChannel, @@ -385,6 +389,7 @@ class DayzArmbands extends Client { linkedGamertagRole: guild.server.linkedGamertagRole, incomeRoles: guild.server.incomeRoles, startingBalance: guild.server.startingBalance, + uavPrice: guild.server.uavPrice, memberRole: guild.server.memberRole, adminRole: guild.server.adminRole, }; diff --git a/util/AlarmsHandler.js b/util/AlarmsHandler.js index 0f3a0d2..831cd28 100644 --- a/util/AlarmsHandler.js +++ b/util/AlarmsHandler.js @@ -3,7 +3,7 @@ const { EmbedBuilder } = require('discord.js'); module.exports = { - HandleAlarms: async (client, guildId, data) => { + HandleAlarmsAndUAVs: async (client, guildId, data) => { let guild = await client.GetGuild(guildId); @@ -41,6 +41,50 @@ module.exports = { return await channel.send({ content: `<@&${alarm.role}>`, embeds: [alarmEmbed] }); } } + + for (let i = 0; i < guild.uavs.length; i++) { + let uav = guild.uavs[i]; + + let diff = [Math.round(uav.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 < uav.radius) { + let newDt = await client.getDateEST(data.time); + let unixTime = Math.floor(newDt.getTIme()/1000); + + let uavEmbed = new EmbedBuilder() + .setColor(client.config.Colors.Default) + .setDescription(`**UAV Detection - **\n**${data.player}** was spotted in the UAV zone at **[${data.pos[0]}, ${data.pos[1]}](https://www.izurvive.com/chernarusplussatmap/#location=${data.pos[0]};${data.pos[1]})**`) + + client.users.fetch(uav.owner, false).then((user) => { + user.send({ embeds: [uavEmbed] }); + }); + } + } + }, + + HandleExpiredUAVs: async (client, guildId) => { + let guild = await client.GetGuild(guildId); + let uavs = guild.uavs; + let update = false; + + for (let i = 0; i < uavs.length; i++) { + let uav = uavs[i]; + + let now = new Date(); + let diff = Math.round((now.getTime() - uav.createDate.getTime()) / 1000 / 60); // diff minutes + + if (diff <= 30) continue; + + uavs.splice(i, 1); + update = true; + } + + if (update) { + client.dbo.collection("guilds").updateOne({ "server.serverID": guildId }, {$set: { "server.uavs": uavs }}, function (err, res) { + if (err) return client.sendInternalError(interaction, err); + }); + } }, KillInAlarm: async (client, guildId, data) => { diff --git a/util/LogsHandler.js b/util/LogsHandler.js index da1b983..57adf3f 100644 --- a/util/LogsHandler.js +++ b/util/LogsHandler.js @@ -1,5 +1,5 @@ const { EmbedBuilder } = require('discord.js'); -const { HandleAlarms } = require('./AlarmsHandler'); +const { HandleAlarmsAndUAVs } = require('./AlarmsHandler'); const { SendConnectionLogs, DetectCombatLog } = require('./AdminLogsHandler'); module.exports = { @@ -105,7 +105,7 @@ module.exports = { playerStat.lastTime = playerStat.time; playerStat.time = `${info.time} EST`; - HandleAlarms(client, guildId, { + HandleAlarmsAndUAVs(client, guildId, { time: info.time, player: info.player, playerID: info.playerID,