diff --git a/db/initialize.ts b/db/initialize.ts index 9b28923..9986eeb 100644 --- a/db/initialize.ts +++ b/db/initialize.ts @@ -27,7 +27,7 @@ await dbClient.execute(` CREATE TABLE command_cnt ( command char(20) NOT NULL, count bigint unsigned NOT NULL DEFAULT 0, - dailyRate float unsigned NOT NULL DEFAULT 0, + hourlyRate float unsigned NOT NULL DEFAULT 0, PRIMARY KEY (command), UNIQUE KEY command_cnt_command_UNIQUE (command) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/mod.ts b/mod.ts index d37b75d..b71827b 100644 --- a/mod.ts +++ b/mod.ts @@ -73,10 +73,17 @@ startBot({ intervals.updateListStatistics(botId, cache.guilds.size); }, 86400000); + // Interval to update hourlyRates every hour + setInterval(() => { + log(LT.LOG, 'Updating all command hourlyRates'); + intervals.updateHourlyRates(); + }, 3600000); + // setTimeout added to make sure the startup message does not error out setTimeout(() => { LOCALMODE && editBotNickname(config.devServer, `LOCAL - ${config.name}`); LOCALMODE ? log(LT.INFO, 'updateListStatistics not running') : intervals.updateListStatistics(botId, cache.guilds.size); + intervals.updateHourlyRates(); editBotStatus({ activities: [{ name: 'Booting Complete', diff --git a/src/commandUtils.ts b/src/commandUtils.ts index f6e0ca6..cbc62e6 100644 --- a/src/commandUtils.ts +++ b/src/commandUtils.ts @@ -30,7 +30,7 @@ export const generateReport = (msg: string) => ({ }], }); -export const generateStats = (guildCount: number, channelCount: number, memberCount: number, rollCount: bigint, utilityCount: bigint) => ({ +export const generateStats = (guildCount: number, channelCount: number, memberCount: number, rollCount: bigint, utilityCount: bigint, rollRate: number, utilityRate: number) => ({ embeds: [{ color: infoColor2, title: 'The Artificer\'s Statistics:', @@ -53,12 +53,14 @@ export const generateStats = (guildCount: number, channelCount: number, memberCo }, { name: 'Roll Commands:', - value: `${rollCount}`, + value: `${rollCount} +(${rollRate.toFixed(2)} per hour)`, inline: true, }, { name: 'Utility Commands:', - value: `${utilityCount}`, + value: `${utilityCount} +(${utilityRate.toFixed(2)} per hour)`, inline: true, }, ], diff --git a/src/commands/stats.ts b/src/commands/stats.ts index d6272e0..24c2218 100644 --- a/src/commands/stats.ts +++ b/src/commands/stats.ts @@ -17,15 +17,17 @@ export const stats = async (message: DiscordenoMessage) => { const m = await message.send(compilingStats); // Calculate how many times commands have been run - const rollQuery = await dbClient.query(`SELECT count FROM command_cnt WHERE command = "roll";`).catch((e) => utils.commonLoggers.dbError('stats.ts:23', 'query', e)); - const totalQuery = await dbClient.query(`SELECT SUM(count) as count FROM command_cnt;`).catch((e) => utils.commonLoggers.dbError('stats.ts:24', 'query', e)); + const rollQuery = await dbClient.query(`SELECT count, hourlyRate FROM command_cnt WHERE command = "roll";`).catch((e) => utils.commonLoggers.dbError('stats.ts:23', 'query', e)); + const totalQuery = await dbClient.query(`SELECT SUM(count) as count, SUM(hourlyRate) as hourlyRate FROM command_cnt;`).catch((e) => utils.commonLoggers.dbError('stats.ts:24', 'query', e)); const rolls = BigInt(rollQuery[0].count); + const rollRate = parseFloat(rollQuery[0].hourlyRate); const total = BigInt(totalQuery[0].count); + const totalRate = parseFloat(totalQuery[0].hourlyRate); const cachedGuilds = await cacheHandlers.size('guilds'); const cachedChannels = await cacheHandlers.size('channels'); const cachedMembers = await cacheHandlers.size('members'); - m.edit(generateStats(cachedGuilds + cache.dispatchedGuildIds.size, cachedChannels + cache.dispatchedChannelIds.size, cachedMembers, rolls, total - rolls)).catch((e: Error) => + m.edit(generateStats(cachedGuilds + cache.dispatchedGuildIds.size, cachedChannels + cache.dispatchedChannelIds.size, cachedMembers, rolls, (total - rolls), rollRate, (totalRate - rollRate))).catch((e: Error) => utils.commonLoggers.messageSendError('stats.ts:38', message, e) ); } catch (e) { diff --git a/src/intervals.ts b/src/intervals.ts index 2539877..e0c9b7e 100644 --- a/src/intervals.ts +++ b/src/intervals.ts @@ -12,7 +12,9 @@ import { log, LT, } from '../deps.ts'; - +import { PastCommandCount } from './mod.d.ts'; +import { dbClient } from './db.ts'; +import utils from './utils.ts'; import config from '../config.ts'; // getRandomStatus() returns status as string @@ -59,4 +61,40 @@ const updateListStatistics = (botID: bigint, serverCount: number): void => { }); }; -export default { getRandomStatus, updateListStatistics }; +// Keep one week of data +const hoursToKeep = 7 * 24; +const previousHours: Array> = [] +// updateHourlyRates() returns nothing +// Updates the hourlyRate for command usage +const updateHourlyRates = async () => { + try { + const newestHour = await dbClient.query(`SELECT command, count FROM command_cnt ORDER BY command;`).catch((e) => utils.commonLoggers.dbError('intervals.ts:71', 'query', e)); + previousHours.push(newestHour); + if (previousHours.length > 1) { + const oldestHour = previousHours[0]; + + const computedDiff: Array = [] + for (let i = 0; i < newestHour.length; i++) { + computedDiff.push({ + command: newestHour[i].command, + count: (newestHour[i].count - oldestHour[i].count), + }); + log(LT.LOG, `Updating hourlyRate | Computing diffs: ${JSON.stringify(computedDiff)}`); + } + + // Update DB + computedDiff.forEach(async (cmd) => { + log(LT.LOG, `Updating hourlyRate | Storing to DB: ${JSON.stringify(cmd)}`); + await dbClient.execute(`UPDATE command_cnt SET hourlyRate = ? WHERE command = ?`, [(cmd.count / previousHours.length), cmd.command]).catch((e) => utils.commonLoggers.dbError('intervals.ts:88', 'update', e)); + }); + } + + if (previousHours.length > hoursToKeep) { + previousHours.unshift(); + } + } catch (e) { + log(LT.ERROR, `Something went wrong in previousHours interval | Error: ${e.name} - ${e.message}`) + } +}; + +export default { getRandomStatus, updateListStatistics, updateHourlyRates }; diff --git a/src/mod.d.ts b/src/mod.d.ts index dee5174..fa26758 100644 --- a/src/mod.d.ts +++ b/src/mod.d.ts @@ -41,3 +41,8 @@ export type QueuedRoll = { rollCmd: string; modifiers: RollModifiers; }; + +export type PastCommandCount = { + command: string; + count: number; +};