Skip to content
This repository has been archived by the owner on Jun 3, 2023. It is now read-only.

Commit

Permalink
Merge pull request #25 from Mirasaki/rank-command
Browse files Browse the repository at this point in the history
Stats command
  • Loading branch information
Mirasaki authored Jun 8, 2022
2 parents 43211f2 + 6ab2262 commit 5ce4583
Show file tree
Hide file tree
Showing 6 changed files with 274 additions and 104 deletions.
1 change: 1 addition & 0 deletions config/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ DEBUG_SLASH_COMMAND_API_DATA=true
DEBUG_INTERACTIONS=false
DEBUG_AUTOCOMPLETE_RESPONSE_TIME=true
DEBUG_LEADERBOARD_API_DATA=false
DEBUG_STAT_COMMAND_DATA=false

# Interaction command API data
REFRESH_SLASH_COMMAND_API_DATA=true
Expand Down
8 changes: 7 additions & 1 deletion src/commands/dayz/leaderboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,12 @@ const buildLeaderboardEmbed = (guild, res, isDefaultQuery, statToGet, mappedStat
author: {
name: description,
iconURL: guild.iconURL({ dynamic: true })
}
},
footer: (
// 1 in5
Math.random() < 0.7
? ({ text: 'Did you know, you can use /stats <cftools-id> to display detailed information on a player?\nYou can find someone\'s CFTools id on their CFTools Cloud account page' })
: null
)
};
};
121 changes: 121 additions & 0 deletions src/commands/dayz/stats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
const logger = require('@mirasaki/logger');
const { stripIndents } = require('common-tags/lib');
const { fetchPlayerDetails } = require('../../modules/cftClient');
const { colorResolver, titleCase } = require('../../util');

const { DEBUG_STAT_COMMAND_DATA } = process.env;

module.exports = {
data: {
description: 'Display information for a specific player',
options: [
{
type: 3, // STRING,
name: 'cftoolsid',
description: 'The player\'s CFTools Cloud ID',
required: true
}
]
},

config: {
cooldown: {
usages: 10,
duration: 60
}
},

// eslint-disable-next-line sonarjs/cognitive-complexity
run: async ({ client, interaction }) => {
// Destructuring and assignments
const { options, member } = interaction;
const { emojis } = client.container;
const cftoolsId = options.getString('cftoolsid');

// Deferring our reply and fetching from API
await interaction.deferReply();
let data;
try {
data = await fetchPlayerDetails(cftoolsId);
} catch (err) {
interaction.editReply({
content: `${emojis.error} ${member}, encountered an error while fetching data, please try again later.`
});
return;
}

// Invalid ID or no access granted
if (data.status === false) {
interaction.editReply({
content: `${emojis.error} ${member}, either the ID you provided is invalid or that player isn't currently known to the client. This command has been cancelled.`
});
return;
}

// Data is delivered as on object with ID key parameters
const stats = data[cftoolsId];

// Detailed, conditional debug logging
if (DEBUG_STAT_COMMAND_DATA === 'true') {
logger.startLog('STAT COMMAND DATA');
console.dir(stats, { depth: Infinity });
logger.endLog('STAT COMMAND DATA');
}

// Assigning our stat variables
const { omega, game } = stats;
const { general } = game;
const hoursPlayed = Math.round(omega.playtime / 60 / 60);
const remainingMinutesPlayed = Math.round(omega.playtime % 60);
const playSessions = omega.sessions;
const averagePlaytimePerSession = Math.round(
((hoursPlayed * 60)
+ remainingMinutesPlayed)
/ playSessions
);
const [
day, month, date, year, time, timezone
] = `${new Date(stats.updated_at)}`.split(' ');
let favoriteWeaponName;
const highestKills = Object.entries(general.weapons).reduce((acc, [weaponName, weaponStats]) => {
const weaponKillsIsLower = acc > weaponStats.kills;
if (!weaponKillsIsLower) favoriteWeaponName = weaponName;
return weaponKillsIsLower ? acc : weaponStats.kills;
}, 0);
// const favoriteWeapon = Object.entries(general.weapons).find(([name]) => name === favoriteWeaponName);
const cleanedWeaponName = titleCase(favoriteWeaponName.replace(/_/g, ' '));

// Reversing the name history array so the latest used name is the first item
omega.name_history.reverse();

// Returning our detailed player information
interaction.editReply({
embeds: [
{
color: colorResolver(),
title: `Stats for ${omega.name_history[0] || 'Survivor'}`,
description: stripIndents`
Survivor has played for ${hoursPlayed} hours and ${remainingMinutesPlayed} minutes over ${playSessions} total sessions.
Bringing them to an average of ${averagePlaytimePerSession} minutes per session.
**Name History:** **\`${omega.name_history.slice(0, 10).join('`**, **`')}\`**
**Deaths:** ${general.deaths || 0}
**Hits:** ${general.hits || 0}
**KDRatio:** ${general.kdratio || 0}
**Kills:** ${general.kills || 0}
**Longest Kill:** ${general.longest_kill || 0} m
**Longest Shot:** ${general.longest_shot || 0} m
**Suicides:** ${general.suicides || 0}
**Favorite Weapon:** ${cleanedWeaponName || 'Knife'} with ${highestKills || 0} kills
`,
footer: {
text: `Last action: ${time} | ${day} ${month} ${date} ${year} ${time} (${timezone})`
}
}
]
});
}
};


98 changes: 93 additions & 5 deletions src/commands/system/ping.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,98 @@
const statsCommand = require('./stats');
const { stripIndents } = require('common-tags');
const { version } = require('discord.js');
const { colorResolver } = require('../../util');

const discordVersion = version.indexOf('dev') < 0 ? version : version.slice(0, version.indexOf('dev') + 3);
const discordVersionDocLink = `https://discord.js.org/#/docs/discord.js/v${discordVersion.split('.')[0]}/general/welcome`;
const nodeVersionDocLink = `https://nodejs.org/docs/latest-${process.version.split('.')[0]}.x/api/#`;

// Spread all the data from our /stats command but overwrite the name
module.exports = {
...statsCommand,
data: {
...statsCommand.data,
name: 'ping'
name: 'ping',
description: 'Display latency & bot stats'
},

config: {
globalCmd: true
},

run: async ({ client, interaction }) => {
// Calculating our API latency
const latency = Math.round(client.ws.ping);
const sent = await interaction.reply({
content: 'Pinging...',
fetchReply: true
});
const fcLatency = sent.createdTimestamp - interaction.createdTimestamp;

// Utility function for getting appropriate status emojis
const getMsEmoji = (ms) => {
let emoji = undefined;
for (const [key, value] of Object.entries({
250: '🟢',
500: '🟡',
1000: '🟠'
})) if (ms <= key) {
emoji = value;
break;
}
return (emoji ??= '🔴');
};

// Replying to the interaction with our embed data
interaction.editReply({
content: '\u200b',
embeds: [
{
color: colorResolver(),
author: {
name: `${client.user.tag}`,
iconURL: client.user.displayAvatarURL()
},
fields: [
{
name: 'Latency',
value: stripIndents`
${getMsEmoji(latency)} **API Latency:** ${latency} ms
${getMsEmoji(fcLatency)} **Full Circle Latency:** ${fcLatency} ms
`,
inline: true
},
{
name: 'Memory',
value: stripIndents`
💾 **Memory Usage:** ${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)} MB
♻️ **Cache Size:** ${(process.memoryUsage().external / 1024 / 1024).toFixed(2)} MB
`,
inline: true
},
{
name: 'Uptime',
value: stripIndents`**📊 I've been online for ${parseInt((client.uptime / (1000 * 60 * 60 * 24)) % 60, 10)} days, ${parseInt((client.uptime / (1000 * 60 * 60)) % 24, 10)} hours, ${parseInt((client.uptime / (1000 * 60)) % 60, 10)} minutes and ${parseInt((client.uptime / 1000) % 60, 10)}.${parseInt((client.uptime % 1000) / 100, 10)} seconds!**`,
inline: false
},
{
name: 'System',
value: stripIndents`
⚙️ **Discord.js Version:** [v${discordVersion}](${discordVersionDocLink})
⚙️ **Node Version:** [${process.version}](${nodeVersionDocLink})
`,
inline: true
},
{
name: 'Stats',
value: stripIndents`
👪 **Servers:** ${client.guilds.cache.size.toLocaleString('en-US')}
🙋 **Users:** ${client.guilds.cache.reduce((previousValue, currentValue) => previousValue += currentValue.memberCount, 0).toLocaleString('en-US')}
`,
inline: true
}
],
footer: {
text: 'Made with ❤️ by Mirasaki#0001 • Open to collaborate • me@mirasaki.dev'
}
}
]
});
}
};
98 changes: 0 additions & 98 deletions src/commands/system/stats.js

This file was deleted.

Loading

0 comments on commit 5ce4583

Please sign in to comment.