Merge pull request #19 from IrPgFKS0/co-work

Partial refactoring/bug fix w/ session time correction
This commit is contained in:
SowinskiBraeden authored and GitHub committed 2023-09-09 23:14:31 -07:00
commit 3651e7ab68
7 files changed
+97 -99

No files matched your search

+1 -1
View File
@@ -460,7 +460,7 @@ module.exports = {
if (err) return client.sendInternalError(interaction, err); if (err) return client.sendInternalError(interaction, err);
}); });
return interaction.send({ embeds: [new EmbedBuilder().setColor(client.config.Colors.Yellow).setDescription(msg)] }); return interaction.send({ embeds: [new EmbedBuilder().setColor(client.config.Colors.Yellow).setDescription(msg)], flags: (1 << 6) });
} }
} }
}, },
+6 -4
View File
@@ -4,15 +4,14 @@ const { GatewayIntentBits } = require('discord.js');
const path = require("path"); const path = require("path");
const fs = require('fs'); const fs = require('fs');
const { HandleActivePlayersList } = require('./util/LogsHandler');
let client = new DayzR({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMembers] }, config);
client.build()
// Log all uncaught exceptions before killing process. // Log all uncaught exceptions before killing process.
process.on('uncaughtException', async (error) => { process.on('uncaughtException', async (error) => {
let d = new Date(); let d = new Date();
// Asynchronously write the error message to a log file using Promises // Asynchronously write the error message to a log file using Promises
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
if (HandleActivePlayersList.lastSendMessage) HandleActivePlayersList.lastSendMessage.delete().catch(error => client.sendError(channel, `HandleActivePlayersList Error: \n${error}`)); // Remove previous embed message before closing
fs.appendFile(path.join(__dirname, "./logs/Logs.log"), fs.appendFile(path.join(__dirname, "./logs/Logs.log"),
`{"level":"error","message":"${d.getHours()}:${d.getMinutes()} - ${d.getMonth()+1}:${d.getDate()}:${d.getFullYear()} | uncaughtException: ${error.stack}"}`, (logErr) => { `{"level":"error","message":"${d.getHours()}:${d.getMinutes()} - ${d.getMonth()+1}:${d.getDate()}:${d.getFullYear()} | uncaughtException: ${error.stack}"}`, (logErr) => {
if (logErr) { if (logErr) {
@@ -25,6 +24,9 @@ process.on('uncaughtException', async (error) => {
}); });
}); });
// Now, you can re-throw the error // Now gracefully close the program
process.exit() process.exit()
}); });
let client = new DayzR({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMembers] }, config);
client.build()
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "dayzr-bot", "name": "dayzr-bot",
"version": "9.9.4", "version": "9.9.5",
"description": "A General Purpose Discord Bot for DayZ Nitrado Servers.", "description": "A General Purpose Discord Bot for DayZ Nitrado Servers.",
"main": "index.js", "main": "index.js",
"nodemonConfig": { "nodemonConfig": {
+44 -49
View File
@@ -10,19 +10,18 @@ const { DownloadNitradoFile, CheckServerStatus } = require('../util/NitradoAPI')
const { HandlePlayerLogs, HandleActivePlayersList } = require('../util/LogsHandler'); const { HandlePlayerLogs, HandleActivePlayersList } = require('../util/LogsHandler');
const { HandleKillfeed } = require('../util/KillfeedHandler'); const { HandleKillfeed } = require('../util/KillfeedHandler');
const { HandleExpiredUAVs, HandleEvents } = require('../util/AlarmsHandler'); const { HandleExpiredUAVs, HandleEvents } = require('../util/AlarmsHandler');
const { SendConnectionLogs } = require('../util/AdminLogsHandler');
const path = require("path"); const path = require("path");
const fs = require('fs'); const fs = require('fs');
const readline = require('readline'); const readline = require('readline');
const minute = 60000; // 1 minute in milliseconds const minute = 60000; // 1 minute in milliseconds
const arInterval = 600000; // Set auto-restart interval 10mins (600,000ms) const arInterval = 600000; // Set auto-restart interval 10 minutes (600,000ms)
class DayzRBot extends Client { class DayzRBot extends Client {
constructor(options, config) { constructor(options, config) {
super(options) super(options);
this.config = config; this.config = config;
this.commands = new Collection(); this.commands = new Collection();
@@ -30,15 +29,16 @@ class DayzRBot extends Client {
this.logger = new Logger(path.join(__dirname, "..", "logs/Logs.log")); this.logger = new Logger(path.join(__dirname, "..", "logs/Logs.log"));
this.timer = this.config.Dev == 'PROD.' ? minute * 5 : minute / 4; this.timer = this.config.Dev == 'PROD.' ? minute * 5 : minute / 4;
if (this.config.Token === "" || this.config.GuildID === "") if (this.config.Token === "" || this.config.GuildID === "") {
throw new TypeError( throw new TypeError(
"The config.js is not filled out. Please make sure nothing is blank, otherwise the bot will not work properly." "The config.js is not filled out. Please make sure nothing is blank, otherwise the bot will not work properly."
); );
}
this.db; this.db;
this.dbo; this.dbo;
this.databaseConnected = false; this.databaseConnected = false;
this.arInterval = arInterval this.arInterval = arInterval;
this.arIntervalId; // Interval for auto-restart functions this.arIntervalId; // Interval for auto-restart functions
this.autoRestartInit(); this.autoRestartInit();
this.LoadCommandsAndInteractionHandlers(); this.LoadCommandsAndInteractionHandlers();
@@ -49,7 +49,7 @@ class DayzRBot extends Client {
this.ws.on("INTERACTION_CREATE", async (interaction) => { this.ws.on("INTERACTION_CREATE", async (interaction) => {
const start = new Date().getTime(); const start = new Date().getTime();
if (interaction.type!=3) { if (interaction.type != 3) {
let GuildDB = await this.GetGuild(interaction.guild_id); let GuildDB = await this.GetGuild(interaction.guild_id);
for (const [factionID, data] of Object.entries(GuildDB.factionArmbands)) { for (const [factionID, data] of Object.entries(GuildDB.factionArmbands)) {
@@ -60,7 +60,7 @@ class DayzRBot extends Client {
$pull: { 'server.usedArmbands': data.armband }, $pull: { 'server.usedArmbands': data.armband },
$unset: { [`server.factionArmbands.${factionID}`]: "" }, $unset: { [`server.factionArmbands.${factionID}`]: "" },
}; };
await this.dbo.collection("guilds").updateOne({'server.serverID': GuildDB.serverID}, query, (err, res) => { await this.dbo.collection("guilds").updateOne({ 'server.serverID': GuildDB.serverID }, query, (err, res) => {
if (err) return this.sendInternalError(interaction, err); if (err) return this.sendInternalError(interaction, err);
}); });
} }
@@ -69,12 +69,12 @@ class DayzRBot extends Client {
const command = interaction.data.name.toLowerCase(); const command = interaction.data.name.toLowerCase();
const args = interaction.data.options; const args = interaction.data.options;
client.log(`Interaction - ${command}`); this.log(`Interaction - ${command}`);
//Easy to send respnose so ;) // Easy to send response so ;)
interaction.guild = await this.guilds.fetch(interaction.guild_id); interaction.guild = await this.guilds.fetch(interaction.guild_id);
interaction.send = async (message) => { interaction.send = async (message) => {
const rest = new REST({ version: '10' }).setToken(client.config.Token); const rest = new REST({ version: '10' }).setToken(this.config.Token);
return await rest.post(Routes.interactionCallback(interaction.id, interaction.token), { return await rest.post(Routes.interactionCallback(interaction.id, interaction.token), {
body: { body: {
@@ -92,7 +92,7 @@ class DayzRBot extends Client {
return interaction.send({ embeds: [dbFailedEmbed] }); return interaction.send({ embeds: [dbFailedEmbed] });
} }
let cmd = client.commands.get(command); let cmd = this.commands.get(command);
try { try {
cmd.SlashCommand.run(this, interaction, args, { GuildDB }, 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) { } catch (err) {
@@ -100,17 +100,15 @@ class DayzRBot extends Client {
} }
} }
}); });
const client = this;
} }
log(Text) { this.logger.log(Text); } log(Text) { this.logger.log(Text); }
error(Text) { this.logger.error(Text); } error(Text) { this.logger.error(Text); }
async getDateEST(time) { async getDateEST(time) {
let timeArray = time.split(' ')[0].split(':') let timeArray = time.split(' ')[0].split(':');
let t = new Date(); // Get current date & time (UTC) 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 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). 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 return new Date(f.getTime() + 4 * 3600000); // Add EST time offset to return timestamp in UTC
} }
@@ -141,13 +139,13 @@ class DayzRBot extends Client {
if (!this.exists(guild.playerstats)) guild.playerstats = []; if (!this.exists(guild.playerstats)) guild.playerstats = [];
let s = guild.playerstats; let s = guild.playerstats;
s.map(p => p.connected = false) // assume all players not connected s.map(p => p.connected = false); // assume all players not connected
for (let i = logIndex + 1; i < lines.length; i++) { for (let i = logIndex + 1; i < lines.length; i++) {
if (lines[i].includes('| ####')) continue; if (lines[i].includes('| ####')) continue;
if (lines[i].includes("(id=Unknown") || lines[i].includes("Player \"Unknown Entity\"")) continue; if (lines[i].includes("(id=Unknown") || lines[i].includes("Player \"Unknown Entity\"")) continue;
if ((i - 1) >= 0 && lines[i] == lines[i-1]) continue; // continue if this line is a duplicate of the last line if ((i - 1) >= 0 && lines[i] == lines[i - 1]) continue; // continue if this line is a duplicate of the last line
if (lines[i].includes('connected') || lines[i].includes('pos=<') || lines[1].includes('hit by Player')) s = await HandlePlayerLogs(this, guildId, s, lines[i]); if (lines[i].includes('connected') || lines[i].includes('pos=<') || lines[i].includes('hit by Player')) s = await HandlePlayerLogs(this, guildId, s, lines[i]);
if (lines[i].includes('killed by with') || lines[i].includes('killed by LandMineTrap')) s = await HandleKillfeed(this, guildId, s, lines[i]); // Handles explosive deaths if (lines[i].includes('killed by with') || lines[i].includes('killed by LandMineTrap')) s = await HandleKillfeed(this, guildId, s, lines[i]); // Handles explosive deaths
if (!(i + 1 >= lines.length) && lines[i + 1].includes('killed by') && lines[i].includes('TransportHit')) s = await HandleKillfeed(this, guildId, s, lines[i]) // Handles vehicle deaths if (!(i + 1 >= lines.length) && lines[i + 1].includes('killed by') && lines[i].includes('TransportHit')) s = await HandleKillfeed(this, guildId, s, lines[i]) // Handles vehicle deaths
if (!(i + 1 >= lines.length) && lines[i + 1].includes('killed by Player') && lines[i].includes('hit by Player')) s = await HandleKillfeed(this, guildId, s, lines[i]); // Handles regular deaths if (!(i + 1 >= lines.length) && lines[i + 1].includes('killed by Player') && lines[i].includes('hit by Player')) s = await HandleKillfeed(this, guildId, s, lines[i]); // Handles regular deaths
@@ -155,13 +153,14 @@ class DayzRBot extends Client {
} }
const playerTemplate = /(.*) \| Player \"(.*)\" \(id=(.*) pos=<(.*)>\)/g; const playerTemplate = /(.*) \| Player \"(.*)\" \(id=(.*) pos=<(.*)>\)/g;
const playerSessions = new Map();
let previouslyConnected = s.filter(p => p.connected); // All players with connection log captured above and no disconnect log let previouslyConnected = s.filter(p => p.connected); // All players with connection log captured above and no disconnect log
let detectedAsConnected = []; let detectedAsConnected = [];
let lastDetectedTime; let lastDetectedTime;
for (let i = lines.length - 1; i > 0; i--) { for (let i = lines.length - 1; i > 0; i--) {
if (lines[i].includes('PlayerList log:')) { if (lines[i].includes('PlayerList log:')) {
for (let j = i + 1; i < lines.length; j++) { for (let j = i + 1; j < lines.length; j++) {
let line = lines[j]; let line = lines[j];
if (line.includes('| ####')) break; if (line.includes('| ####')) break;
@@ -178,15 +177,29 @@ class DayzRBot extends Client {
if (!this.exists(info.player) || !this.exists(info.playerID)) continue; if (!this.exists(info.player) || !this.exists(info.playerID)) continue;
// Check if the player session exists in the map.
if (playerSessions.has(info.playerID)) {
// Player is already in a session, update the session's end time.
const session = playerSessions.get(info.playerID);
session.endTime = await this.getDateEST(info.time); // Update end time.
} else {
// Player is not in a session, create a new session.
const newSession = {
startTime: await this.getDateEST(info.time),
endTime: null, // Initialize end time as null.
};
playerSessions.set(info.playerID, newSession);
}
let playerStat = s.find(stat => stat.playerID == info.playerID); let playerStat = s.find(stat => stat.playerID == info.playerID);
let playerStatIndex = s.indexOf(playerStat); let playerStatIndex = s.indexOf(playerStat);
if (playerStat == undefined) playerStat = this.getDefaultPlayerStats(info.player, info.playerID); if (playerStat == undefined) playerStat = this.getDefaultPlayerStats(info.player, info.playerID);
if (!previouslyConnected.includes(playerStat)) {
// This player was not connected before, i.e missing connection log? if (!previouslyConnected.includes(playerStat)) {
// Check if the player has been marked as connected before.
playerStat.connected = true; playerStat.connected = true;
playerStat.lastConnectionDate = await this.getDateEST(info.time); // Assume connected now playerStat.lastConnectionDate = await this.getDateEST(info.time); // Update last connection date.
detectedAsConnected.push() detectedAsConnected.push(playerStat);
} }
if (playerStatIndex == -1) s.push(playerStat); if (playerStatIndex == -1) s.push(playerStat);
@@ -197,24 +210,6 @@ class DayzRBot extends Client {
} }
} }
for (let i = 0; i < previouslyConnected.length; i++) {
if (!detectedAsConnected.includes(previouslyConnected[i])) {
let playerStat = previouslyConnected[i];
let playerStatIndex = s.indexOf(playerStat);
playerStat.connected = false;
s[playerStatIndex] = playerStat;
SendConnectionLogs(this, guildId, {
time: lastDetectedTime,
player: playerStat.gamertag,
connected: false,
lastConnectionDate: playerStat.lastConnectionDate,
});
}
}
await this.dbo.collection("guilds").updateOne({ "server.serverID": guildId }, { await this.dbo.collection("guilds").updateOne({ "server.serverID": guildId }, {
$set: { $set: {
"server.playerstats": s "server.playerstats": s
@@ -223,7 +218,7 @@ class DayzRBot extends Client {
if (err) this.sendError(this.GetChannel(guild.adminLogsChannel), err); if (err) this.sendError(this.GetChannel(guild.adminLogsChannel), err);
}); });
history.lastLog = lines[lines.length-1]; history.lastLog = lines[lines.length - 1];
// write JSON string to a file // write JSON string to a file
fs.writeFileSync(logHistoryDir, JSON.stringify(history)); fs.writeFileSync(logHistoryDir, JSON.stringify(history));
@@ -267,14 +262,14 @@ class DayzRBot extends Client {
try { try {
// Connect to Mongo database. // Connect to Mongo database.
this.db = await MongoClient.connect(mongoURI, {connectTimeoutMS: 1000}); this.db = await MongoClient.connect(mongoURI, { connectTimeoutMS: 1000 });
this.dbo = this.db.db(dbo); this.dbo = this.db.db(dbo);
mongoose.connect(`mongodb://${mongoURI.split('@')[1]}/${dbo}`, { mongoose.connect(`mongodb://${mongoURI.split('@')[1]}/${dbo}`, {
authSource: "admin", authSource: "admin",
user: mongoURI.split('//')[1].split(':')[0], user: mongoURI.split('//')[1].split(':')[0],
pass: mongoURI.split('//')[1].split(':')[1].split('@')[0], pass: mongoURI.split('//')[1].split(':')[1].split('@')[0],
useNewUrlParser: true, useNewUrlParser: true,
}).catch(e=>this.error(e)); }).catch(e => this.error(e));
this.log('Successfully connected to mongoDB'); this.log('Successfully connected to mongoDB');
databaselogs.connected = true; databaselogs.connected = true;
databaselogs.attempts = 0; // reset attempts databaselogs.attempts = 0; // reset attempts
@@ -296,7 +291,7 @@ class DayzRBot extends Client {
await this.connectMongo(this.config.mongoURI, this.config.dbo); await this.connectMongo(this.config.mongoURI, this.config.dbo);
let is_enabled = undefined; let is_enabled = undefined;
if (this.databaseConnected) is_enabled = await this.dbo.collection("guilds").findOne({"server.autoRestart":1}).then(is_enabled => is_enabled); if (this.databaseConnected) is_enabled = await this.dbo.collection("guilds").findOne({ "server.autoRestart": 1 }).then(is_enabled => is_enabled);
if (is_enabled) { if (is_enabled) {
this.log('Starting periodic Nitrado server status check.'); this.log('Starting periodic Nitrado server status check.');
@@ -304,12 +299,12 @@ class DayzRBot extends Client {
} }
} }
exists(n) {return null != n && undefined != n && "" != n} exists(n) { return null != n && undefined != n && "" != n }
secondsToDhms(seconds) { secondsToDhms(seconds) {
seconds = Number(seconds); seconds = Number(seconds);
const d = Math.floor(seconds / (3600*24)); const d = Math.floor(seconds / (3600 * 24));
const h = Math.floor(seconds % (3600*24) / 3600); const h = Math.floor(seconds % (3600 * 24) / 3600);
const m = Math.floor(seconds % 3600 / 60); const m = Math.floor(seconds % 3600 / 60);
const s = Math.floor(seconds % 60); const s = Math.floor(seconds % 60);
@@ -351,7 +346,7 @@ class DayzRBot extends Client {
else else
files.forEach((file) => { files.forEach((file) => {
const event = require(EventsDir + "/" + file); const event = require(EventsDir + "/" + file);
if (['interactionCreate','guildMemberAdd'].includes(file.split(".")[0])) this.on(file.split(".")[0], i => event(this, i)); if (['interactionCreate', 'guildMemberAdd'].includes(file.split(".")[0])) this.on(file.split(".")[0], i => event(this, i));
else this.on(file.split(".")[0], event.bind(null, this)); else this.on(file.split(".")[0], event.bind(null, this));
this.log("Event Loaded: " + file.split(".")[0]); this.log("Event Loaded: " + file.split(".")[0]);
}); });
+5 -6
View File
@@ -3,13 +3,12 @@ const { EmbedBuilder } = require('discord.js');
module.exports = { module.exports = {
SendConnectionLogs: async (client, guildId, data) => { SendConnectionLogs: async (client, guildId, data) => {
let guild = await client.GetGuild(guildId); let guild = await client.GetGuild(guildId);
if (!client.exists(guild.connectionLogsChannel)) return; if (!client.exists(guild.connectionLogsChannel)) return;
const channel = client.GetChannel(guild.connectionLogsChannel); const channel = client.GetChannel(guild.connectionLogsChannel);
let newDt = await client.getDateEST(data.time); let newDt = await client.getDateEST(data.time);
let unixTime = Math.floor(newDt.getTime()/1000); let unixTime = Math.floor(newDt.getTime() / 1000);
let connectionLog = new EmbedBuilder() let connectionLog = new EmbedBuilder()
.setColor(data.connected ? client.config.Colors.Green : client.config.Colors.Red) .setColor(data.connected ? client.config.Colors.Green : client.config.Colors.Red)
@@ -17,7 +16,7 @@ module.exports = {
if (!data.connected) { if (!data.connected) {
if (!(data.lastConnectionDate == null)) { if (!(data.lastConnectionDate == null)) {
let oldUnixTime = Math.floor(data.lastConnectionDate.getTime()/1000); let oldUnixTime = Math.floor(data.lastConnectionDate.getTime() / 1000);
let sessionTime = client.secondsToDhms(unixTime - oldUnixTime); let sessionTime = client.secondsToDhms(unixTime - oldUnixTime);
connectionLog.addFields({ name: '**Session Time**', value: `**${sessionTime}**`, inline: false }); connectionLog.addFields({ name: '**Session Time**', value: `**${sessionTime}**`, inline: false });
} else connectionLog.addFields({ name: '**Session Time**', value: `**Unknown**`, inline: false }); } else connectionLog.addFields({ name: '**Session Time**', value: `**Unknown**`, inline: false });
@@ -36,14 +35,14 @@ module.exports = {
// If diff is greater than 5 minutes, not a combat log // If diff is greater than 5 minutes, not a combat log
// or if death after last combat // or if death after last combat
if (data.lastDamageDate <= data.lastDeathDate) return; if (data.lastDamageDate <= data.lastDeathDate) return;
if (diffSeconds > (5 * 60)) return; if (diffSeconds > 5 * 60) return;
let guild = await client.GetGuild(guildId); let guild = await client.GetGuild(guildId);
if (!client.exists(guild.connectionLogsChannel)) return; if (!client.exists(guild.connectionLogsChannel)) return;
const channel = client.GetChannel(guild.connectionLogsChannel); const channel = client.GetChannel(guild.connectionLogsChannel);
if (!channel) return; if (!channel) return;
let unixTime = Math.floor(newDt.getTime()/1000); let unixTime = Math.floor(newDt.getTime() / 1000);
let combatLog = new EmbedBuilder() let combatLog = new EmbedBuilder()
.setColor(client.config.Colors.Red) .setColor(client.config.Colors.Red)
@@ -53,4 +52,4 @@ module.exports = {
return channel.send({ embeds: [combatLog] }); return channel.send({ embeds: [combatLog] });
} }
} };
+38 -36
View File
@@ -18,10 +18,10 @@ module.exports = {
const deadTemplate = /(.*) \| Player \"(.*)\" \(DEAD\) \(id=(.*) pos=<(.*)>\)\[HP\: (.*)\] hit by Player \"(.*)\" \(id=(.*) pos=<(.*)>\) into (.*) for (.*) damage \((.*)\) with (.*) from (.*) meters /g; const deadTemplate = /(.*) \| Player \"(.*)\" \(DEAD\) \(id=(.*) pos=<(.*)>\)\[HP\: (.*)\] hit by Player \"(.*)\" \(id=(.*) pos=<(.*)>\) into (.*) for (.*) damage \((.*)\) with (.*) from (.*) meters /g;
if (line.includes(' connected')) { if (line.includes(' connected')) {
let data = [...line.matchAll(connectTemplate)][0]; const data = [...line.matchAll(connectTemplate)][0];
if (!data) return stats; if (!data) return stats;
let info = { const info = {
time: data[1], time: data[1],
player: data[2], player: data[2],
playerID: data[3], playerID: data[3],
@@ -29,17 +29,19 @@ module.exports = {
if (!client.exists(info.player) || !client.exists(info.playerID)) return stats; if (!client.exists(info.player) || !client.exists(info.playerID)) return stats;
let playerStat = stats.find(stat => stat.playerID == info.playerID) let playerStat = stats.find(stat => stat.playerID == info.playerID);
let playerStatIndex = stats.indexOf(playerStat); let playerStatIndex = stats.indexOf(playerStat);
if (playerStat == undefined) playerStat = client.getDefaultPlayerStats(info.player, info.playerID); if (playerStat === undefined) playerStat = client.getDefaultPlayerStats(info.player, info.playerID);
playerStat.lastConnectionDate = await client.getDateEST(info.time);; const newDt = await client.getDateEST(info.time);
playerStat.lastConnectionDate = newDt;
playerStat.connected = true; playerStat.connected = true;
if (playerStatIndex == -1) stats.push(playerStat); if (playerStatIndex === -1) stats.push(playerStat);
else stats[playerStatIndex] = playerStat; else stats[playerStatIndex] = playerStat;
SendConnectionLogs(client, guildId, { await SendConnectionLogs(client, guildId, {
time: info.time, time: info.time,
player: info.player, player: info.player,
connected: true, connected: true,
@@ -48,25 +50,25 @@ module.exports = {
} }
if (line.includes(' disconnected')) { if (line.includes(' disconnected')) {
let data = [...line.matchAll(disconnectTemplate)][0]; const data = [...line.matchAll(disconnectTemplate)][0];
if (!data) return stats; if (!data) return stats;
let info = { const info = {
time: data[1], time: data[1],
player: data[2], player: data[2],
playerID: data[3], playerID: data[3],
} };
if (!client.exists(info.player) || !client.exists(info.playerID)) return stats; if (!client.exists(info.player) || !client.exists(info.playerID)) return stats;
let playerStat = stats.find(stat => stat.playerID == info.playerID) let playerStat = stats.find(stat => stat.playerID == info.playerID);
let playerStatIndex = stats.indexOf(playerStat); let playerStatIndex = stats.indexOf(playerStat);
if (playerStat == undefined) playerStat = client.getDefaultPlayerStats(info.player, info.playerID); if (playerStat === undefined) playerStat = client.getDefaultPlayerStats(info.player, info.playerID);
let newDt = await client.getDateEST(info.time); const newDt = await client.getDateEST(info.time);
let unixTime = Math.round(newDt.getTime()/1000); // Seconds const unixTime = Math.round(newDt.getTime() / 1000); // Seconds
let oldUnixTime = Math.round(playerStat.lastConnectionDate.getTime()/1000); // Seconds const oldUnixTime = Math.round(playerStat.lastConnectionDate.getTime() / 1000); // Seconds
let sessionTimeSeconds = unixTime - oldUnixTime; const sessionTimeSeconds = unixTime - oldUnixTime;
if (!client.exists(playerStat.longestSessionTime)) playerStat.longestSessionTime = 0; if (!client.exists(playerStat.longestSessionTime)) playerStat.longestSessionTime = 0;
playerStat.totalSessionTime = playerStat.totalSessionTime + sessionTimeSeconds; playerStat.totalSessionTime = playerStat.totalSessionTime + sessionTimeSeconds;
@@ -74,10 +76,10 @@ module.exports = {
playerStat.longestSessionTime = sessionTimeSeconds > playerStat.longestSessionTime ? sessionTimeSeconds : playerStat.longestSessionTime; playerStat.longestSessionTime = sessionTimeSeconds > playerStat.longestSessionTime ? sessionTimeSeconds : playerStat.longestSessionTime;
playerStat.connected = false; playerStat.connected = false;
if (playerStatIndex == -1) stats.push(playerStat); if (playerStatIndex === -1) stats.push(playerStat);
else stats[playerStatIndex] = playerStat; else stats[playerStatIndex] = playerStat;
SendConnectionLogs(client, guildId, { await SendConnectionLogs(client, guildId, {
time: info.time, time: info.time,
player: info.player, player: info.player,
connected: false, connected: false,
@@ -95,10 +97,10 @@ module.exports = {
} }
if (line.includes('pos=<') && !line.includes('hit by')) { if (line.includes('pos=<') && !line.includes('hit by')) {
let data = [...line.matchAll(positionTemplate)][0]; const data = [...line.matchAll(positionTemplate)][0];
if (!data) return stats; if (!data) return stats;
let info = { const info = {
time: data[1], time: data[1],
player: data[2], player: data[2],
playerID: data[3], playerID: data[3],
@@ -107,9 +109,9 @@ module.exports = {
if (!client.exists(info.player) || !client.exists(info.playerID)) return stats; if (!client.exists(info.player) || !client.exists(info.playerID)) return stats;
let playerStat = stats.find(stat => stat.playerID == info.playerID) let playerStat = stats.find(stat => stat.playerID == info.playerID);
let playerStatIndex = stats.indexOf(playerStat); let playerStatIndex = stats.indexOf(playerStat);
if (playerStat == undefined) playerStat = client.getDefaultPlayerStats(info.player, info.playerID); if (playerStat === undefined) playerStat = client.getDefaultPlayerStats(info.player, info.playerID);
if (!client.exists(playerStat.lastConnectionDate)) playerStat.lastConnectionDate = await client.getDateEST(info.time); if (!client.exists(playerStat.lastConnectionDate)) playerStat.lastConnectionDate = await client.getDateEST(info.time);
playerStat.lastPos = playerStat.pos; playerStat.lastPos = playerStat.pos;
@@ -119,7 +121,7 @@ module.exports = {
playerStat.time = `${info.time} EST`; playerStat.time = `${info.time} EST`;
playerStat.date = await client.getDateEST(info.time); playerStat.date = await client.getDateEST(info.time);
if (playerStatIndex == -1) stats.push(playerStat); if (playerStatIndex === -1) stats.push(playerStat);
else stats[playerStatIndex] = playerStat; else stats[playerStatIndex] = playerStat;
if (line.includes('hit by') || line.includes('killed by')) return stats; // prevent additional information from being fed to Alarms & UAVs if (line.includes('hit by') || line.includes('killed by')) return stats; // prevent additional information from being fed to Alarms & UAVs
@@ -130,33 +132,32 @@ module.exports = {
playerID: info.playerID, playerID: info.playerID,
pos: info.pos, pos: info.pos,
}); });
} }
if (line.includes('hit by Player')) { if (line.includes('hit by Player')) {
let data = line.includes('(DEAD)') ? [...line.matchAll(deadTemplate)][0] : [...line.matchAll(damageTemplate)][0]; const data = line.includes('(DEAD)') ? [...line.matchAll(deadTemplate)][0] : [...line.matchAll(damageTemplate)][0];
if (!data) return stats; if (!data) return stats;
let info = { const info = {
time: data[1], time: data[1],
player: data[2], player: data[2],
playerID: data[3], playerID: data[3],
attacker: data[6], attacker: data[6],
attackerID: data[7] attackerID: data[7]
} };
if (!client.exists(info.player) || !client.exists(info.playerID)) return stats; if (!client.exists(info.player) || !client.exists(info.playerID)) return stats;
let playerStat = stats.find(stat => stat.playerID == info.playerID) let playerStat = stats.find(stat => stat.playerID == info.playerID);
let playerStatIndex = stats.indexOf(playerStat); let playerStatIndex = stats.indexOf(playerStat);
if (playerStat == undefined) playerStat = client.getDefaultPlayerStats(info.player, info.playerID); if (playerStat === undefined) playerStat = client.getDefaultPlayerStats(info.player, info.playerID);
let newDt = await client.getDateEST(info.time); const newDt = await client.getDateEST(info.time);
playerStat.lastDamageDate = newDt; playerStat.lastDamageDate = newDt;
playerStat.lastHitBy = info.attacker; playerStat.lastHitBy = info.attacker;
if (playerStatIndex == -1) stats.push(playerStat); if (playerStatIndex === -1) stats.push(playerStat);
else stats[playerStatIndex] = playerStat; else stats[playerStatIndex] = playerStat;
} }
@@ -168,11 +169,12 @@ module.exports = {
const data = await FetchServerSettings(client, 'HandleActivePlayersList'); // Fetch server status const data = await FetchServerSettings(client, 'HandleActivePlayersList'); // Fetch server status
if (data && data != 1) { if (data && data !== 1) {
let hostname = data.data.gameserver.settings.config.hostname; let hostname = data.data.gameserver.settings.config.hostname;
let map = data.data.gameserver.settings.config.mission.slice(12); let map = data.data.gameserver.settings.config.mission.slice(12);
let status = data.data.gameserver.status; let status = data.data.gameserver.status;
let slots = data.data.gameserver.slots; let slots = data.data.gameserver.slots;
let playersOnline = data.data.gameserver.query.player_current;
let statusEmoji; let statusEmoji;
let statusText; let statusText;
@@ -195,7 +197,7 @@ module.exports = {
if (!client.exists(guild.activePlayersChannel)) return; if (!client.exists(guild.activePlayersChannel)) return;
const channel = client.GetChannel(guild.activePlayersChannel); const channel = client.GetChannel(guild.activePlayersChannel);
let activePlayers = guild.playerstats.filter(p => p.connected == true); let activePlayers = guild.playerstats.filter(p => p.connected === true);
let des = ``; let des = ``;
for (let i = 0; i < activePlayers.length; i++) { for (let i = 0; i < activePlayers.length; i++) {
@@ -204,7 +206,7 @@ module.exports = {
const nodes = activePlayers.length === 0; const nodes = activePlayers.length === 0;
const PlayersEmbed = new EmbedBuilder() const PlayersEmbed = new EmbedBuilder()
.setColor(client.config.Colors.Default) .setColor(client.config.Colors.Default)
.setTitle(`Online List \` ${activePlayers.length} \` Player${activePlayers.length>1?'s':''} Online`) .setTitle(`Online List \` ${playersOnline} \` Player${playersOnline > 1 ? 's' : ''} Online`)
.addFields( .addFields(
{ name: 'Server:', value: `\` ${hostname} \``, inline: false }, { name: 'Server:', value: `\` ${hostname} \``, inline: false },
{ name: 'Map:', value: `\` ${map} \``, inline: true }, { name: 'Map:', value: `\` ${map} \``, inline: true },
@@ -216,7 +218,7 @@ module.exports = {
.setColor(client.config.Colors.Default) .setColor(client.config.Colors.Default)
.setTimestamp() .setTimestamp()
.setTitle(`Players Online:`) .setTitle(`Players Online:`)
.setDescription(des || (nodes ? "No Players Online :(" : "")) .setDescription(des || (nodes ? "No Players Online :(" : ""));
if (lastSendMessage) lastSendMessage.delete().catch(error => client.sendError(channel, `HandleActivePlayersList Error: \n${error}`)); // Remove previous message before reprinting if (lastSendMessage) lastSendMessage.delete().catch(error => client.sendError(channel, `HandleActivePlayersList Error: \n${error}`)); // Remove previous message before reprinting
@@ -225,4 +227,4 @@ module.exports = {
); );
} }
} }
} };
+2 -2
View File
@@ -78,8 +78,8 @@ module.exports = {
const stream = fs.createWriteStream(outputDir); const stream = fs.createWriteStream(outputDir);
if (!res.data || !res.data.token) { if (!res.data || !res.data.token) {
client.error(`Error downloading File "${filename}":`); const errorText = await res.text();
client.error(res); client.error(`Error downloading File "${filename}": message: ${errorText}: DownloadNitradoFile`);
return 1; return 1;
} }
const { body } = await fetch(res.data.token.url); const { body } = await fetch(res.data.token.url);