diff --git a/.gitignore b/.gitignore index f958104..c392902 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ npm-debug.log #env .env +.DS_Store diff --git a/structures/DayzRBot.js b/structures/DayzRBot.js index 2df9c96..e7bdf13 100644 --- a/structures/DayzRBot.js +++ b/structures/DayzRBot.js @@ -104,11 +104,11 @@ class DayzRBot extends Client { error(Text) { this.logger.error(Text); } async getDateEST(time) { - let t = new Date(); // Get current date (PST) - let e = new Date(t.getTime() + 180*60*1000); // Convert to EST to ensure the date is correct for the applied EST time - let n = new Date(`${e.getFullYear()}-${e.getMonth()<10?'0':''}${e.getMonth()+1}-${e.getDate()<10?'0':''}${e.getDate()}T${time.split(' ')[0]}`) // Apply given time to EST date - let f = new Date(n.getTime() - 180*60*1000) // Convert back to PST - return f; + let timeArray = time.split(' ')[0].split(':') + let t = new Date(); // Get current date & time (UTC) + let f = new Date(t.getTime() - 4 * 3600000) // Convert UTC into EST time to roll back the day as necessary + f.setUTCHours(timeArray[0], timeArray[1], timeArray[2]); // Apply the supplied EST time to the converted date (EST is the timezone produced from the Nitrado logs). + return new Date(f.getTime() + 4 * 3600000); // Add EST time offset to return timestamp in UTC } async readLogs(guildId) { @@ -246,12 +246,12 @@ class DayzRBot extends Client { this.databaseConnected = true; } catch (err) { databaselogs.attempts++; - this.error(`Failed to connect to mongodb: attempt ${databaselogs.attempts}`); + this.error(`Failed to connect to mongodb (mongodb://${mongoURI.split('@')[1]}/${dbo}): attempt ${databaselogs.attempts} - Error: ${err}`); failed = true; } // write JSON string to a file - await fs.writeFileSync(dbLogDir, JSON.stringify(databaselogs)); + fs.writeFileSync(dbLogDir, JSON.stringify(databaselogs)); if (failed) process.exit(-1); } diff --git a/util/NitradoAPI.js b/util/NitradoAPI.js index d3e95e9..2689713 100644 --- a/util/NitradoAPI.js +++ b/util/NitradoAPI.js @@ -3,64 +3,83 @@ const concat = require('concat-stream'); const { Readable } = require('stream'); const FormData = require('form-data'); const fs = require('fs'); +const maxRetries = 5; +const retryDelay = 5000; // 5 second module.exports = { - DownloadNitradoFile: async (client, filename, outputDir) => { - const res = await fetch(`https://api.nitrado.net/services/${client.config.Nitrado.ServerID}/gameservers/file_server/download?file=${filename}`, { - headers: { - "Authorization": client.config.Nitrado.Auth + for (let retries = 0; retries <= maxRetries; retries++) { + try { + const res = await fetch(`https://api.nitrado.net/services/${client.config.Nitrado.ServerID}/gameservers/file_server/download?file=${filename}`, { + headers: { + "Authorization": client.config.Nitrado.Auth + } + }).then(response => + response.json().then(data => data) + ).then(res => res); + + const stream = fs.createWriteStream(outputDir); + if (!res.data || !res.data.token) { + client.error(`Error downloading File "${filename}":`); + client.error(res); + return -1; + } + const { body } = await fetch(res.data.token.url); + await finished(Readable.fromWeb(body).pipe(stream)); + return 0; + } catch (error) { + if (retries === maxRetries) { + throw new Error(`Failed to fetch data after ${maxRetries} retries`); + } } - }).then(response => - response.json().then(data => data) - ).then(res => res); - - const stream = fs.createWriteStream(outputDir); - if (!res.data || !res.data.token) { - client.error(`Error downloading File "${filename}":`); - client.error(res); - return -1; + await new Promise(resolve => setTimeout(resolve, retryDelay)); // Delay before retrying } - const { body } = await fetch(res.data.token.url); - await finished(Readable.fromWeb(body).pipe(stream)); - return 0; }, HandlePlayerBan: async (client, gamertag, ban) => { // get current bans - const res = await fetch(`https://api.nitrado.net/services/${client.config.Nitrado.ServerID}/gameservers`, { - headers: { - "Authorization": client.config.Nitrado.Auth - } - }).then(response => - response.json().then(data => data) - ).then(res => res); - - let bans = res.data.gameserver.settings.general.bans; - if (ban) bans += `\r\n${gamertag}`; - else if (!ban) bans = bans.replace(gamertag, ''); - else client.error("Incorrect Ban Option: HandlePlayerBan"); - - const formData = new FormData(); - formData.append("category", "general"); - formData.append("key", "bans"); - formData.append("value", bans); - formData.pipe(concat(data => { - async function sendList() { - await fetch(`https://api.nitrado.net/services/${client.config.Nitrado.ServerID}/gameservers/settings`, { - method: "POST", - credentials: 'include', + for (let retries = 0; retries <= maxRetries; retries++) { + try { + const res = await fetch(`https://api.nitrado.net/services/${client.config.Nitrado.ServerID}/gameservers`, { headers: { - ...formData.getHeaders(), "Authorization": client.config.Nitrado.Auth - }, - body: data, - }); - } - sendList(); - })); - }, + } + }).then(response => + response.json().then(data => data) + ).then(res => res); + + let bans = res.data.gameserver.settings.general.bans; + if (ban) bans += `\r\n${gamertag}`; + else if (!ban) bans = bans.replace(gamertag, ''); + else client.error("Incorrect Ban Option: HandlePlayerBan"); + const formData = new FormData(); + formData.append("category", "general"); + formData.append("key", "bans"); + formData.append("value", bans); + 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(); + })); + } catch (error) { + if (retries === maxRetries) { + throw new Error(`Failed to fetch data after ${maxRetries} retries`); + } + } + await new Promise(resolve => setTimeout(resolve, retryDelay)); // Delay before retrying + } + }, + /* Allows more explicit function names outside this file; i.e BanPlayer() & UnbanPlayer() that both call to the @@ -68,7 +87,7 @@ module.exports = { two whole different functions for each. */ - BanPlayer: async (client, gamertag) => module.exports.HandlePlayerBan(client, gamertag, true), - UnbanPlayer: async (client, gamertag) => module.exports.HandlePlayerBan(client, gamertag, false), - -} \ No newline at end of file + BanPlayer: async (client, gamertag) => module.exports.HandlePlayerBan(client, gamertag, true), + UnbanPlayer: async (client, gamertag) => module.exports.HandlePlayerBan(client, gamertag, false), + + } \ No newline at end of file