From 8bff6d0485ef834c33730c9a31aaed26a874dbea Mon Sep 17 00:00:00 2001 From: Cesium Date: Wed, 12 Nov 2025 05:52:25 -0500 Subject: [PATCH] command for top armory donators --- commands/{api => utility}/calcpayout.js | 0 commands/utility/donorboard.js | 64 +++++++++++++++++++++++++ torn.js | 39 ++++++++++++++- 3 files changed, 102 insertions(+), 1 deletion(-) rename commands/{api => utility}/calcpayout.js (100%) create mode 100644 commands/utility/donorboard.js diff --git a/commands/api/calcpayout.js b/commands/utility/calcpayout.js similarity index 100% rename from commands/api/calcpayout.js rename to commands/utility/calcpayout.js diff --git a/commands/utility/donorboard.js b/commands/utility/donorboard.js new file mode 100644 index 0000000..f45d57f --- /dev/null +++ b/commands/utility/donorboard.js @@ -0,0 +1,64 @@ +const { SlashCommandBuilder } = require('discord.js'); +const torn = require('../../torn.js'); + +module.exports = { + data: new SlashCommandBuilder() + .setName('donorboard') + .setDescription("See who's donated the most this week") + .addIntegerOption(option => + option.setName('days') + .setDescription('Get results for a different amount of time')), + async execute(interaction) { + let days + if (!interaction.options.getInteger('days')) days = 7; + else days = interaction.options.getInteger('days'); + const seconds = days * 24 * 60 * 60; + const time = new Date(new Date().getTime() - seconds * 1000); + let board = {}; + await torn.faction.news("armoryDeposit", time.toISOString()).then(data => { + data.forEach(async news => { + const regex = /([^<]+)<\/a> deposited (\d+) x (.+)/; + const match = news.text.match(regex); + if (match) { + const id = match[1]; + const name = match[2]; + const count = parseInt(match[3]); + const itemName = match[4]; + const item = (await torn.item.lookup(itemName)); + if (!board[id]) { + board[id] = { + name: name, + totalValue: 0, + items: {} + } + } + if (!board[id].items[item.id]) { + board[id].items[item.id] = { + name: itemName, + count: 0, + value: item.value.market_price + } + } + board[id].items[item.id].count += count; + board[id].totalValue += item.value.market_price * count; + } else { + console.log("Unexpected news event: ", news.text); + } + }); + });; + let message = `# Donor Board\n`; + + const sortedBoard = Object.values(board).sort((a, b) => b.totalValue - a.totalValue); + + for (const user of sortedBoard) { + console.log(user) + message += `## ${user.name}: $${user.totalValue.toLocaleString()}\n`; + for (const item in user.items) { + message += `- ${user.items[item].name}: ${user.items[item].count}\n`; + const totalItemValue = user.items[item].count * user.items[item].value; + message += ` - $${totalItemValue.toLocaleString()} (${user.items[item].value.toLocaleString()})\n`; + } + } + interaction.reply(message); + }, +}; \ No newline at end of file diff --git a/torn.js b/torn.js index a54f6e3..5bf004b 100644 --- a/torn.js +++ b/torn.js @@ -103,7 +103,7 @@ module.exports.cache = { return(cache.items[item]); } else { console.debug(`Cache: Miss for item ${item}`) - await module.exports.item(item); + await module.exports.item.get(item); console.debug(`Cache: Resolved item ${cache.items[item].name}`) return(cache.items[item]); } @@ -195,6 +195,11 @@ module.exports.faction = { const response = await fetch(`https://api.torn.com/v2/faction/upgrades?key=${config.torn}`); const data = await response.json(); return(data.upgrades); + }, + async news(category, from) { + const response = await fetch(`https://api.torn.com/v2/faction/news?striptags=false&limit=100&sort=DESC&from=${from}&cat=${category}&key=${config.torn}`) + const data = await response.json(); + return(data.news); } } @@ -228,6 +233,38 @@ module.exports.item = async (item) => { fs.writeFileSync('./cache.json', JSON.stringify(cache)); return(data.items[0]); } +module.exports.item.lookup = async (itemName) => { + console.debug(`Torn: Looking up item ${itemName}`) + const thirtyDays = 30 * 24 * 60 * 60 * 1000; + const now = new Date().getTime(); + + for (const itemId in cache.items) { + if (cache.items[itemId].name === itemName) { + let last = new Date(cache.items[itemId].updated).getTime(); + if (now - last < thirtyDays) { + console.debug(`Cache: Hit for item ${cache.items[itemId].name}`); + return cache.items[itemId]; + } + } + } + + console.debug(`Cache: Miss for item ${itemName}`); + const response = await fetch(`https://api.torn.com/v2/torn/items?cat=All&sort=ASC&key=${config.torn}`); + const data = await response.json(); + let target; + data.items.forEach(item => { + if (item.name === itemName) { + console.debug(`Torn: Found item ${item.name} as ${item.id}`) + target = item; + } + }); + if (target) { + cache.items[target.id] = target; + cache.items[target.id].updated = new Date().toISOString(); + fs.writeFileSync('./cache.json', JSON.stringify(cache)); + } + return(target); +}; module.exports.self = {