diff --git a/commands/tpsbar.js b/commands/tpsbar.js new file mode 100644 index 0000000..115ff5e --- /dev/null +++ b/commands/tpsbar.js @@ -0,0 +1,63 @@ +const { EmbedBuilder } = require('discord.js') +module.exports = { + name: 'tpsbar', + alias: ['tps'], + description: 'Shows the server\'s TPS using Minecraft bossbar', + usage: '', + trusted: 0, + execute (bot, username, sender, prefix, args, config, hash, ownerhash, selector) { + switch (args[0]) { + case 'on': + bot.tps.on() + bot.tellraw(selector, [ + { + text: 'TPSBar is now ', + color: 'white' + }, + { + text: 'enabled', + color: 'green' + } + ]) + break + case 'off': + bot.tps.off() + bot.tellraw(selector, [ + { + text: 'TPSBar is now ', + color: 'white' + }, + { + text: 'disabled', + color: 'red' + } + ]) + break + default: + throw new SyntaxError('Invalid argument') + } + }, + discordExecute (bot, username, sender, prefix, args, channeldc, message, config) { + let Embed + switch (args[0]) { + case 'on': + bot.tps.on() + Embed = new EmbedBuilder() + .setColor(config.discord.embedsColors.normal) + .setTitle('TPSBar') + .setDescription('TPSBar is now enabled') + channeldc.send({ embeds: [Embed] }) + break + case 'off': + bot.tps.off() + Embed = new EmbedBuilder() + .setColor(config.discord.embedsColors.normal) + .setTitle('TPSBar') + .setDescription('TPSBar is now disabled') + channeldc.send({ embeds: [Embed] }) + break + default: + throw new SyntaxError('Invalid argument') + } + } +} diff --git a/plugins/tps.js b/plugins/tps.js new file mode 100644 index 0000000..67c95b4 --- /dev/null +++ b/plugins/tps.js @@ -0,0 +1,77 @@ +const clamp = require('../util/clamp') +function inject (bot, dcclient, config) { + const bossbarName = 'chomens_bot:tps' + + let enabled = false + bot.tps = { + on () { + enabled = true + }, + off () { + enabled = false + bot.core.run(`minecraft:bossbar remove ${bossbarName}`) + } + } + + const tickRates = [] + let nextIndex = 0 + let timeLastTimeUpdate = -1 + let timeGameJoined + let timeUpdatesTotal = 0 + + const interval = setInterval(() => { + if (!enabled) return + + const component = { + translate: 'TPS - %s', + color: 'gray', + bold: false, + with: [ + { text: getTickRate(), color: 'green' } + ] + } + bot.core.run(`minecraft:bossbar add ${bossbarName} ""`) + bot.core.run(`minecraft:bossbar set ${bossbarName} players @a`) + bot.core.run(`minecraft:bossbar set ${bossbarName} color yellow`) + bot.core.run(`minecraft:bossbar set ${bossbarName} visible true`) + bot.core.run(`minecraft:bossbar set ${bossbarName} style progress`) + bot.core.run(`minecraft:bossbar set ${bossbarName} name ${JSON.stringify(component)}`) + bot.core.run(`minecraft:bossbar set ${bossbarName} max 20`) + bot.core.run(`minecraft:bossbar set ${bossbarName} value ${Math.floor(getTickRate())}`) + }, 50) + + function getTickRate () { + if (Date.now() - timeGameJoined < 4000) return 'Calculating...' + + let numTicks = 0 + let sumTickRates = 0.0 + for (const tickRate of tickRates) { + if (tickRate > 0) { + sumTickRates += tickRate + numTicks++ + } + } + + const value = (sumTickRates / numTicks).toFixed(2) + if (value > 20) return 20 + else return value + } + + bot.on('login', () => { + nextIndex = 0 + timeGameJoined = timeLastTimeUpdate = Date.now() + }) + + bot._client.on('update_time', () => { + const now = Date.now() + const timeElapsed = (now - timeLastTimeUpdate) / 1000.0 + tickRates[nextIndex] = clamp(20.0 / timeElapsed, 0.0, 20.0) + nextIndex = (nextIndex + 1) % tickRates.length + timeLastTimeUpdate = now + timeUpdatesTotal++ + }) + + bot.on('end', () => clearInterval(interval)) +} + +module.exports = { inject } diff --git a/util/clamp.js b/util/clamp.js new file mode 100644 index 0000000..809bd3d --- /dev/null +++ b/util/clamp.js @@ -0,0 +1,6 @@ +function clamp (value, min, max) { + if (value < min) return min + return Math.min(value, max) +} + +module.exports = clamp