From 2db118cd2e0f37a4efd5dd523a87e67c6f58f89e Mon Sep 17 00:00:00 2001 From: Braeden Sowinski Date: Sun, 10 Sep 2023 19:00:17 -0700 Subject: [PATCH] update/toggle base damage --- commands/admin.js | 21 ++++++++++- package.json | 2 +- util/NitradoAPI.js | 90 +++++++++++++++++++++++++++++++--------------- 3 files changed, 82 insertions(+), 31 deletions(-) diff --git a/commands/admin.js b/commands/admin.js index fd88dae..dc67b21 100644 --- a/commands/admin.js +++ b/commands/admin.js @@ -1,7 +1,7 @@ const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, StringSelectMenuBuilder } = require('discord.js'); const CommandOptions = require('../util/CommandOptionTypes').CommandOptionTypes; const bitfieldCalculator = require('discord-bitfield-calculator'); -const { BanPlayer, UnbanPlayer, RestartServer, CheckServerStatus } = require('../util/NitradoAPI'); +const { BanPlayer, UnbanPlayer, RestartServer, CheckServerStatus, ToggleBaseDamage } = require('../util/NitradoAPI'); const { Armbands } = require('../config/armbandsdb.js'); module.exports = { @@ -148,6 +148,18 @@ module.exports = { description: "Enable/Disable periodic server checks and restart if stopped.", value: "auto-restart", type: CommandOptions.SubCommand, + }, { + name: "disable-base-damage", + description: "Disable/Enable base damage", + value: "disable-base-damage", + type: CommandOptions.SubCommand, + options: [{ + name: "preference", + description: "DisableBaseDamage Preference", + value: true, + type: CommandOptions.Boolean, + required: true, + }] }], SlashCommand: { /** @@ -462,6 +474,13 @@ module.exports = { }); return interaction.send({ embeds: [new EmbedBuilder().setColor(client.config.Colors.Yellow).setDescription(msg)], flags: (1 << 6) }); + } else if (args[0].name == 'disable-base-damage') { + const preference = args[0].options[0].value; + + const toggle = ToggleBaseDamage(client, preference); + if (toggle == 1) return interaction.send({ embeds: [new EmbedBuilder().setColor(client.config.Colors.Red).setDescription('Failed to update ` disableBaseDamage `, try again later.')] }); + + return interaciton.send({ embeds: [new EmbedBuilder().setColor(client.config.Colors.Green).setDescription(`Successfully updated \` disableBaseDamage \` to ${preference}.\nRestart the DayZ server to apply these changes.`)] }); } } }, diff --git a/package.json b/package.json index 03556a0..338be6d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dayzr-bot", - "version": "9.9.8", + "version": "10.0.0", "description": "A General Purpose Discord Bot for DayZ Nitrado Servers.", "main": "index.js", "nodemonConfig": { diff --git a/util/NitradoAPI.js b/util/NitradoAPI.js index ab5ac41..5392f37 100644 --- a/util/NitradoAPI.js +++ b/util/NitradoAPI.js @@ -8,6 +8,47 @@ const retryDelay = 5000; // 5 seconds // Private functions (only called locally) +const UploadNitradoFile = async (client, remoteDir, remoteFilename, localFileDir) => { + for (let retries = 0; retries <= maxRetries; retries++) { + try { + const res = await fetch(`https://api.nitrado.net/services/${client.config.Nitrado.ServerID}/gameservers/file_server/upload?` + new URLSearchParams({ + path: remoteDir, + file: remoteFilename + }), { + method: "POST", + headers: { + "Authorization": client.config.Nitrado.Auth + }, + }).then(response => + response.json().then(data => data) + ).then(res => res); + + let contents = fs.readFileSync(localFileDir, 'utf8'); + + const uploadRes = await fetch(res.data.token.url, { + method: "POST", + headers: { + 'Content-Type': 'application/binary', + token: res.data.token.token + }, + body: contents, + }); + if (!uploadRes.ok) { + const errorText = await uploadRes.text(); + client.error(`Failed to upload file to Nitrado (${client.config.Nitrado.ServerID}): status: ${uploadRes.status}, message: ${errorText}: UploadNitradoFile`); + if (retries === 2) return 1; // Return error status on the second failed status code. + } else { + const data = await uploadRes.json(); + return data; + } + } catch (error) { + client.error(`UploadNitradoFile: Error connecting to server (${client.config.Nitrado.ServerID}): ${error.message}`); + if (retries === maxRetries) throw new Error(`UploadNitradoFile: Error connecting to server (${client.config.Nitrado.ServerID}) after ${maxRetries} retries`); + } + await new Promise(resolve => setTimeout(resolve, retryDelay)); // Delay before retrying + } +} + const PostServerSettings = async (client, category, key, value) => { for (let retries = 0; retries <= maxRetries; retries++) { try { @@ -176,35 +217,26 @@ module.exports = { ToggleBaseDamage: async (client, preference) => { const settings = await module.exports.FetchServerSettings(client, 'ToggleBaseDamage'); // Fetch server settings + if (!settings || settings == 1) return 1; + + const posted = await PostServerSettings(client, "config", "disableBaseDamage", preference); + if (!posted || posted == 1) return 1; - if (settings && settings != 1) { - for (let retries = 0; retries <= maxRetries; retries++) { - try { - const formData = new FormData(); - formData.append("category", "config"); - formData.append("key", "disableBaseDamage"); - formData.append("value", preference); - formData.pipe(concat(data => { - async function sendList() { - await fetch(`https://api.nitrado.net/services/${client.config.Nitrado.ServerID}/gameservers/settings`, { - method: "POST", - credentials: 'include', - headers: { - ...formData.getHeaders(), - "Authorization": client.config.Nitrado.Auth - }, - body: data, - }); - } - sendList(); - })); - return 0; - } catch (error) { - client.error(`HandlePlayerBan: Error connecting to server (${client.config.Nitrado.ServerID}): ${error.message}`); - if (retries === maxRetries) throw new Error(`HandlePlayerBan: Error connecting to server (${client.config.Nitrado.ServerID}) after ${maxRetries} retries`); - } - await new Promise(resolve => setTimeout(resolve, retryDelay)); // Delay before retrying - } - } + const remoteDir = '/games/ni8434545_1/ftproot/dayzxb_missions/dayzOffline.chernarusplus'; + const remoteFilename = 'cfggameplay.json'; + + const jsonDir = path.join(__dirname, '.', 'logs', remoteFilename); + await module.exports.DownloadNitradoFile(client, `${remoteDir}/${remoteFilename}`, jsonDir); + + let gameplay = JSON.parse(fs.readFileSync(jsonDir)); + gameplay.GeneralData.disableBaseDamage = preference; + + // write JSON to file + fs.writeFileSync(jsonDir, JSON.stringify(gameplay), null, 2); + + const uploaded = await UploadNitradoFile(client, remoteDir, remoteFileName, jsonDir); + if (!uploaded || uploaded == 1) return 1; + + return 0; } }