From be059d13983d90b5dcee7d1fa36f0ed1e55369e8 Mon Sep 17 00:00:00 2001 From: Hirzi <64255651+HirziDevs@users.noreply.github.com> Date: Thu, 3 Nov 2022 08:17:11 +0000 Subject: [PATCH 01/32] Some changes --- Indo.md | 2 ++ README.md | 2 ++ package.json | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Indo.md b/Indo.md index 3436700..f736902 100644 --- a/Indo.md +++ b/Indo.md @@ -122,6 +122,8 @@ Jika kamu mengalami error 403 coba aktifkan `read & write` di semua opsi permiss ## Links +- [PteroStats DiscordJS v13](https://github.com/HirziDevs/PteroStats/tree/3d0512c3323ecf079101104c7ecf3c94d265e298) +- [PteroStats DiscordJS v12](https://github.com/HirziDevs/PteroStats/tree/bcfa266be64dda11955f0bf9732da086bcea522c) - [Pterodactyl Panel](https://pterodactyl.io) - [Pterodactyl Api Documentation](https://dashflo/docs/api/pterodactyl/v1) - [Pterodactyl Discord Server](https://discord.gg/pterodactyl) diff --git a/README.md b/README.md index e8a4391..ff1be25 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,8 @@ If you having issue with 403 error try to enable `read & write` on all options ## Links +- [PteroStats DiscordJS v13](https://github.com/HirziDevs/PteroStats/tree/3d0512c3323ecf079101104c7ecf3c94d265e298) +- [PteroStats DiscordJS v12](https://github.com/HirziDevs/PteroStats/tree/bcfa266be64dda11955f0bf9732da086bcea522c) - [Pterodactyl Panel](https://pterodactyl.io) - [Pterodactyl Api Documentation](https://dashflo/docs/api/pterodactyl/v1) - [Pterodactyl Discord Server](https://discord.gg/pterodactyl) diff --git a/package.json b/package.json index 36fbe00..e0788b1 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "PteroStats is a bot designed to check Pterodactyl Panel and Nodes status and post it to your discord server", "license": "MIT", "repository": "HirziDevs/PteroStats", - "homepage": "https://pterostats.hirzidevs.net", + "homepage": "https://pterostats.hirzidevs.xyz", "bugs": { "email": "hirzidevs@gmail.com", "url": "https://github.com/HirziDevs/PteroStats" From b2709151133760b41dd41ab4c69fa766fab0fa41 Mon Sep 17 00:00:00 2001 From: Hirzi <64255651+HirziDevs@users.noreply.github.com> Date: Thu, 3 Nov 2022 08:19:18 +0000 Subject: [PATCH 02/32] Some changes --- Indo.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Indo.md b/Indo.md index f736902..7ec23b7 100644 --- a/Indo.md +++ b/Indo.md @@ -3,7 +3,7 @@ PteroStats Banner ## Bahasa / Language -[[Indonesia]](https://github.com/HirziDevs/PteroStats/blob/dev/Indo.md) | [[Inggris]](https://github.com/HirziDevs/PteroStats/blob/dev/README.md) +[[Indonesia]](https://github.com/HirziDevs/PteroStats/blob/main/Indo.md) | [[Inggris]](https://github.com/HirziDevs/PteroStats/blob/main/README.md) diff --git a/README.md b/README.md index ff1be25..3fe7082 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ PteroStats Banner ## Language / Bahasa -[[English]](https://github.com/HirziDevs/PteroStats/blob/dev/README.md) | [[Indonesia]](https://github.com/HirziDevs/PteroStats/blob/dev/Indo.md) +[[English]](https://github.com/HirziDevs/PteroStats/blob/main/README.md) | [[Indonesia]](https://github.com/HirziDevs/PteroStats/blob/main/Indo.md) From 76bd98d692262258607ab25fd7c59375a70a3d15 Mon Sep 17 00:00:00 2001 From: Hirzi <64255651+HirziDevs@users.noreply.github.com> Date: Fri, 25 Nov 2022 06:22:24 +0700 Subject: [PATCH 03/32] Temporary downgrade axios to 1.1.3 (fix pagination error) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e0788b1..b08e1d7 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "start": "node index.js" }, "dependencies": { - "axios": "^1.1.3", + "axios": "1.1.3", "chalk": "4.1.1", "discord.js": "^14.6.0", "js-yaml": "^4.1.0" From 750118e287f1b02224b35edc12f451d5d2ff17cf Mon Sep 17 00:00:00 2001 From: Hirzi <64255651+HirziDevs@users.noreply.github.com> Date: Mon, 28 Nov 2022 07:59:49 +0000 Subject: [PATCH 04/32] refactor --- events/ready.js | 12 +++++------ handlers/checkStatus.js | 48 +++++++++++++++++++---------------------- handlers/postStatus.js | 33 +++++++++++----------------- index.js | 37 ++++++++++++++++--------------- package.json | 2 +- 5 files changed, 60 insertions(+), 72 deletions(-) diff --git a/events/ready.js b/events/ready.js index 0927b0e..082fadc 100644 --- a/events/ready.js +++ b/events/ready.js @@ -8,22 +8,20 @@ module.exports = { console.log(chalk.cyan('[PteroStats] ') + chalk.green('Bot is up!')) console.log(chalk.cyan('[PteroStats] ') + chalk.green('If you need support you can join our discord server https://discord.gg/zv6maQRah3')) - if (client.guilds.cache.size < 1) return console.log(chalk.cyan('[PteroStats] ') + chalk.red('Err! This bot is not on any discord servers')) - + if (client.guilds.cache.size < 1) return console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! This bot is not on any discord servers')) + if (client.config.refresh < 10) console.log(chalk.cyan('[PteroStats] ') + chalk.red('Refresh lower than 10 seconds is not recommended!')) if (client.config.bot_status.enable && client.config.bot_status.text.length > 0) { if (!['PLAYING', 'WATCHING', 'LISTENING', 'COMPETING'].includes(client.config.bot_status.type.toUpperCase() || client.config.bot_status.type.length < 1)) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Err! Invalid Status Type!, Can be "WATCHING", "PLAYING", "LISTENING", or "COMPETING"')) + console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Status Type!, Can be "WATCHING", "PLAYING", "LISTENING", or "COMPETING"')) } else { client.user.setActivity(client.config.bot_status.text, { type: client.config.bot_status.type.toUpperCase() }) } } - if (client.config.refresh < 10) console.log('Refresh lower than 10 seconds is not recommended!') - - checkStatus(client) + checkStatus({ client: client }) setInterval(() => { - checkStatus(client) + checkStatus({ client: client }) }, client.config.refresh * 1000) } } \ No newline at end of file diff --git a/handlers/checkStatus.js b/handlers/checkStatus.js index 2bab4e7..ef1d119 100644 --- a/handlers/checkStatus.js +++ b/handlers/checkStatus.js @@ -3,19 +3,19 @@ const chalk = require('chalk') const postStatus = require('./postStatus') -module.exports = function checkStatus(client) { +module.exports = function checkStatus({ client }) { if (client.config.channel.startsWith('Put')) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Err! Invalid Channel ID')) + console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Channel ID')) process.exit() } else if (client.config.panel.url.startsWith('Put')) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Err! Invalid Panel URL')) + console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Panel URL')) process.exit() } else if (client.config.panel.key.startsWith('Put')) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Err! Invalid Apikey')) + console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Apikey')) process.exit() } else if (!client.config.panel.url.startsWith('http')) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Err! Invalid Panel URL')) + console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Panel URL')) console.log(chalk.cyan('[PteroStats] ') + chalk.red('1. Make sure the panel url is starts with "https://" or "http://"')) process.exit() } @@ -40,7 +40,7 @@ module.exports = function checkStatus(client) { 'Content-Type': 'application/json', Authorization: 'Bearer ' + client.config.panel.key } - }).then((usr) => { + }).then((users) => { axios(client.config.panel.url + '/api/application/servers', { method: 'GET', headers: { @@ -48,25 +48,25 @@ module.exports = function checkStatus(client) { 'Content-Type': 'application/json', Authorization: 'Bearer ' + client.config.panel.key } - }).then((ser) => { - panel.total_users = usr.data.meta.pagination.total - panel.total_servers = ser.data.meta.pagination.total + }).then((servers) => { + panel.total_users = users.data.meta.pagination.total + panel.total_servers = servers.data.meta.pagination.total panel.status = true resolve() }) - }).catch((err) => { - if (err.response) { - if (err.response.status === 403) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Err! Invalid apikey')) + }).catch((error) => { + if (error.response) { + if (error.response.status === 403) { + console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid apikey')) console.log(chalk.cyan('[PteroStats] ') + chalk.red('1. Make sure the apikey is from admin page not account page')) console.log(chalk.cyan('[PteroStats] ') + chalk.red('2. Make sure the apikey has read permission on all options')) console.log(chalk.cyan('[PteroStats] ') + chalk.red('3. Make sure the apikey is exist')) - } else if (err.response.status === 404) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Err! Invalid Panel URL')) + } else if (error.response.status === 404) { + console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Panel URL')) console.log(chalk.cyan('[PteroStats] ') + chalk.red('1. Make sure the panel url is like "https://panel.example.com"')) - } else console.log(chalk.cyan('[PteroStats] ') + chalk.red('Err! ' + err)) - } else console.log(chalk.cyan('[PteroStats] ') + chalk.red('Err! ' + err)) + } else console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! ' + error)) + } else console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! ' + error)) resolve() }) }) @@ -111,9 +111,9 @@ module.exports = function checkStatus(client) { 'Content-Type': 'application/json', Authorization: 'Bearer ' + data.data.token } - }).then((status) => { + }).then(() => { return statsResolve() - }).catch((err) => { + }).catch(() => { body.status = false return statsResolve() }) @@ -126,19 +126,15 @@ module.exports = function checkStatus(client) { nodes.push(body) if (nodes.length === res.data.data.length) resolve() }) - }).catch((err) => { - resolve() - }) + }).catch(() => resolve()) }) - }).catch((err) => { - resolve() - }) + }).catch(() => resolve()) }) panelStats.then(() => { nodeStats.then(() => { nodes.sort(function (a, b) { return a.id - b.id }) - postStatus(client, panel, nodes) + postStatus({ client: client, panel: panel, nodes: nodes }) }) }) } \ No newline at end of file diff --git a/handlers/postStatus.js b/handlers/postStatus.js index 7c57495..5a269d0 100644 --- a/handlers/postStatus.js +++ b/handlers/postStatus.js @@ -1,38 +1,29 @@ const { EmbedBuilder, time, ActionRowBuilder, ButtonBuilder, ButtonStyle, AttachmentBuilder } = require('discord.js') const chalk = require('chalk') -module.exports = async function postStatus(client, panel, nodes) { - - if (!client.config.nodes_resource) client.config.nodes_resource = client.config.resource - if (!client.config.nodes_resource.blacklist) client.config.nodes_resource.blacklist = [] - if (!Array.isArray(client.config.nodes_resource.blacklist) && Number.isInteger(client.config.nodes_resource.blacklist)) client.config.nodes_resource.blacklist = [client.config.nodes_resource.blacklist] - if (!client.config.message.attachment) client.config.message.attachment = client.config.message.image - - if (client.guilds.cache.size < 1) return console.log(chalk.cyan('[PteroStats] ') + chalk.red('Err! This bot is not on any discord servers')) +module.exports = async function postStatus({ client, panel, nodes }) { const channel = await client.channels.cache.get(client.config.channel) + if (!channel) return console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Channel ID')) - if (!channel) return console.log(chalk.cyan('[PteroStats] ') + chalk.red('Err! Invalid Channel ID')) + const files = [] + const embed = new EmbedBuilder() + let messages = await channel.messages.fetch({ limit: 10 }).then(msg => msg.filter(m => m.author.id === client.user.id).last()) + let text = '' + let desc = '' + let blacklist = 0 + let content = null - let messages = await channel.messages.fetch({ limit: 10 }) - messages = messages.filter(m => m.author.id === client.user.id).last(); + if (!client.config.nodes_resource.blacklist) client.config.nodes_resource.blacklist = [] + if (!Array.isArray(client.config.nodes_resource.blacklist) && Number.isInteger(client.config.nodes_resource.blacklist)) client.config.nodes_resource.blacklist = [client.config.nodes_resource.blacklist] + if (client.guilds.cache.size < 1) return console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! This bot is not on any discord servers')) if (messages && messages.embeds.length < 1) { messages.delete() messages = null } - const embed = new EmbedBuilder() - - let text = '' - let desc = '' - let blacklist = 0 - - let content = null - const files = [] - if (client.config.message.content) content = client.config.message.content if (client.config.message.attachment) files.push(new AttachmentBuilder(client.config.message.attachment)) - if (client.config.embed.title) embed.setTitle(client.config.embed.title) if (client.config.embed.description) desc = client.config.embed.description + '\n' if (client.config.embed.color) embed.setColor(client.config.embed.color) diff --git a/index.js b/index.js index 9098250..13cc7a3 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,7 @@ const fs = require('fs'); const child = require('child_process'); +const chalk = require('chalk'); +const yaml = require('js-yaml'); if (Number(process.version.split('.')[0]) < 16) { console.log('Invalid NodeJS Version!, Please use NodeJS 16.x or upper') @@ -19,34 +21,35 @@ if (fs.existsSync('./node_modules')) { console.log('Install complete!, please run "node index" command again!') process.exit() } catch (err) { - console.log('Err! ', err) + console.log('Error! ', err) console.log('Support Server: https://discord.gg/zv6maQRah3') process.exit() } } -const chalk = require('chalk'); -const yaml = require('js-yaml'); const { Client, GatewayIntentBits } = require('discord.js'); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); -const config = yaml.load(fs.readFileSync('./config.yml', 'utf8')); -client.config = config +client.config = yaml.load(fs.readFileSync('./config.yml', 'utf8')); + +if (client.config.panel.adminkey || client.config.resource || client.config.message.image) { + console.log(chalk.cyan('[PteroStats] ') + chalk.red('You are using old config file, please update your config file at https://github.com/HirziDevs/PteroStats/blob/main/config.yml !')) + process.exit() +} +if (client.config.token.startsWith('Put') || !client.config.token.length) { + console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Discord Bot Token')) + process.exit() +} const eventFiles = fs.readdirSync('./events').filter(file => file.endsWith('.js')); for (const file of eventFiles) { - const event = require(`./events/${file}`); - if (event.once) { - client.once(event.name, (...args) => event.execute(...args)); - } else { - client.on(event.name, (...args) => event.execute(...args)); - } + const event = require(`./events/${file}`); + if (event.once) { + client.once(event.name, (...args) => event.execute(...args)); + } else { + client.on(event.name, (...args) => event.execute(...args)); + } } -if (client.config.token.startsWith('Put') || client.config.token.length < 1) { - console.log(chalk.cyan('[PteroStats]') + chalk.red(' Err! Invalid Discord Bot Token')) - process.exit() -} - -client.login(config.token); \ No newline at end of file +client.login(client.config.token); \ No newline at end of file diff --git a/package.json b/package.json index b08e1d7..61efb73 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "homepage": "https://pterostats.hirzidevs.xyz", "bugs": { "email": "hirzidevs@gmail.com", - "url": "https://github.com/HirziDevs/PteroStats" + "url": "https://github.com/HirziDevs/PteroStats/issues" }, "scripts": { "start": "node index.js" From f7ace8008927ee9c6692c144598b1794cbbfbde7 Mon Sep 17 00:00:00 2001 From: Hirzi <64255651+HirziDevs@users.noreply.github.com> Date: Tue, 29 Nov 2022 14:44:15 +0000 Subject: [PATCH 05/32] fix bot activity & config update --- config.yml | 32 ++++++++++++++++---------------- events/ready.js | 35 ++++++++++++++++++++++++++++++----- handlers/postStatus.js | 26 +++++++++++++------------- index.js | 2 +- 4 files changed, 60 insertions(+), 35 deletions(-) diff --git a/config.yml b/config.yml index fe1759b..81e9ddb 100644 --- a/config.yml +++ b/config.yml @@ -3,10 +3,10 @@ # Bot Configuration token: 'Put bot token here' -bot_status: - enable: false +presence: text: 'Hosting Panel' - type: 'WATCHING' # can be 'WATCHING', 'PLAYING', 'LISTENING', or 'COMPETING'. for 'STREAMING' is not working for now + type: 'watching' # can be 'watching', 'playing', 'listening', or 'competing'. for 'streaming' is not working for now + status: 'online' # can be 'online', 'idle', 'dnd', or 'invisible' # Discord Channel and Refresh Time Configuration channel: 'Put channel id here' @@ -18,10 +18,10 @@ panel: key: 'Put panel apikey here' # Message Configuration -# set to false if you want to disable option +# leave '' if you want to disable option message: - content: false - attachment: false # If you enable attachment on message it upload the attachment first before sending or editing message and it will delay the stats + content: '' + attachment: '' # If you enable attachment on message it upload the attachment first before sending or editing message and it will delay the stats embed: title: 'PteroStats' @@ -29,12 +29,11 @@ embed: description: 'Next update {{time}}' # You can use {{time}} to make "in X seconds" time format footer: 'By Hirzi#8701' timestamp: true - thumbnail: false - image: false + thumbnail: '' + image: '' field: - enable: false - title: 'Custom Field' - description: 'Custom Field' # You can use {{time}} to make "in X seconds" time format + title: '' + description: '' # You can use {{time}} to make "in X seconds" time format # Message Button Configuration button: @@ -56,12 +55,14 @@ button: url: '' # Status Message Configuration +# How to use custom emoji: htttps://github.com/HirziDevs/PteroStats#using-custom-emoji status: online: ':green_circle: Online' offline: ':red_circle: Offline' -# Nodes Resource -nodes_resource: +# Nodes Settings +# How to get nodes id: htttps://github.com/HirziDevs/PteroStats#blacklist-nodes +nodes_settings: blacklist: [] # You can add node id to remove the node from status embed (Example: "blacklist: [1]") enable: false servers: true @@ -69,8 +70,7 @@ nodes_resource: allocations: true unit: 'gb' # You can use "gb", "mb", "tb", or "percent" -# Panel Users and Servers -panel_resource: - enable: true +# Panel Users and Servers Settings +panel_settings: servers: true users: true \ No newline at end of file diff --git a/events/ready.js b/events/ready.js index 082fadc..c02c793 100644 --- a/events/ready.js +++ b/events/ready.js @@ -1,3 +1,4 @@ +const { ActivityType } = require('discord.js') const chalk = require('chalk') const checkStatus = require('../handlers/checkStatus') @@ -10,12 +11,36 @@ module.exports = { if (client.guilds.cache.size < 1) return console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! This bot is not on any discord servers')) if (client.config.refresh < 10) console.log(chalk.cyan('[PteroStats] ') + chalk.red('Refresh lower than 10 seconds is not recommended!')) - if (client.config.bot_status.enable && client.config.bot_status.text.length > 0) { - if (!['PLAYING', 'WATCHING', 'LISTENING', 'COMPETING'].includes(client.config.bot_status.type.toUpperCase() || client.config.bot_status.type.length < 1)) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Status Type!, Can be "WATCHING", "PLAYING", "LISTENING", or "COMPETING"')) - } else { - client.user.setActivity(client.config.bot_status.text, { type: client.config.bot_status.type.toUpperCase() }) + + if (client.config.bot_status || client.config.nodes_resource || client.config.panel_resource) { + console.log(chalk.cyan('[PteroStats] ') + chalk.red('You used `bot_status`, `panel_resource` and `nodes_resource` instead of `presence`, `panel_settings` and `nodes_settings` in the config, please update your config file at ') + chalk.green('https://github.com/HirziDevs/PteroStats/blob/main/config.yml ') + chalk.red('before it can no longer be supported')) + client.config.presence = client.config.bot_status + client.config.nodes_settings = client.config.nodes_resource + client.config.panel_settings = client.config.panel_resource + } + + if (client.config.presence.text && client.config.presence.type) { + switch (client.config.presence.type.toLowerCase()) { + case 'playing': + client.config.presence.type = ActivityType.Playing + break; + case 'listening': + client.config.presence.type = ActivityType.Listening + break; + case 'competing': + client.config.presence.type = ActivityType.Competing + break; + default: + client.config.presence.type = ActivityType.Watching } + + client.user.setActivity(client.config.presence.text, { type: client.config.presence.type }) + } + + if (client.config.presence.status) { + if (!['idle', 'online', 'dnd', 'invisible'].includes(client.config.presence.status.toLowerCase())) client.config.presence.status = 'online' + + client.user.setStatus(client.config.presence.status); } checkStatus({ client: client }) diff --git a/handlers/postStatus.js b/handlers/postStatus.js index 5a269d0..c34cae5 100644 --- a/handlers/postStatus.js +++ b/handlers/postStatus.js @@ -14,8 +14,8 @@ module.exports = async function postStatus({ client, panel, nodes }) { let blacklist = 0 let content = null - if (!client.config.nodes_resource.blacklist) client.config.nodes_resource.blacklist = [] - if (!Array.isArray(client.config.nodes_resource.blacklist) && Number.isInteger(client.config.nodes_resource.blacklist)) client.config.nodes_resource.blacklist = [client.config.nodes_resource.blacklist] + if (!client.config.nodes_settings.blacklist) client.config.nodes_settings.blacklist = [] + if (!Array.isArray(client.config.nodes_settings.blacklist) && Number.isInteger(client.config.nodes_settings.blacklist)) client.config.nodes_settings.blacklist = [client.config.nodes_settings.blacklist] if (client.guilds.cache.size < 1) return console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! This bot is not on any discord servers')) if (messages && messages.embeds.length < 1) { messages.delete() @@ -37,10 +37,10 @@ module.exports = async function postStatus({ client, panel, nodes }) { const stats = new Promise((resolve, reject) => { if (nodes.length !== 0) { nodes.forEach((data, i) => { - if (!client.config.nodes_resource.blacklist.includes(data.id)) { + if (!client.config.nodes_settings.blacklist.includes(data.id)) { const title = data.name + ': ' + String(data.status).replace('true', client.config.status.online).replace('false', client.config.status.offline) let description = '```' - switch (client.config.nodes_resource.unit.toLowerCase()) { + switch (client.config.nodes_settings.unit.toLowerCase()) { case 'tb': description = description + '\nMemory : ' + Math.floor(data.memory_min / (1024 * 1000)).toLocaleString() + ' TB / ' + Math.floor(data.memory_max / (1024 * 1000)).toLocaleString() + ' TB' + @@ -62,20 +62,20 @@ module.exports = async function postStatus({ client, panel, nodes }) { '\nDisk : ' + data.disk_min.toLocaleString() + ' MB / ' + data.disk_max.toLocaleString() + ' MB' } - if (client.config.nodes_resource.servers) description = description + '\nServers : ' + data.total_servers.toLocaleString() - if (client.config.nodes_resource.location) description = description + '\nLocation : ' + data.location - if (client.config.nodes_resource.allocations) description = description + '\nAllocations : ' + data.allocations.toLocaleString() + if (client.config.nodes_settings.servers) description = description + '\nServers : ' + data.total_servers.toLocaleString() + if (client.config.nodes_settings.location) description = description + '\nLocation : ' + data.location + if (client.config.nodes_settings.allocations) description = description + '\nAllocations : ' + data.allocations.toLocaleString() description = description + '\n```' - if (client.config.nodes_resource.enable) { + if (client.config.nodes_settings.enable) { text = text + '\n**' + title.replace(':', ':**') + '\n' + description } else { text = text + '\n**' + title.replace(':', ':**') } } else { blacklist = blacklist + 1 - if (nodes.length - client.config.nodes_resource.blacklist.length < 1) text = '\nThere is no nodes to display' + if (nodes.length - client.config.nodes_settings.blacklist.length < 1) text = '\nThere is no nodes to display' } if (i + 1 === nodes.length) resolve() @@ -100,16 +100,16 @@ module.exports = async function postStatus({ client, panel, nodes }) { embed.setDescription(desc.replaceAll('{{time}}', format) + '\n**Nodes Stats [' + Math.floor(nodes.length - blacklist) + ']**' + text) const EmbedFields = [] - if (client.config.panel_resource.enable) { + if (client.config.panel_settings.users || client.config.panel_settings.servers) { let stats = '**Status:** ' + String(panel.status).replace('true', client.config.status.online).replace('false', client.config.status.offline) + '\n\n' - if (client.config.panel_resource.users) stats = stats + 'Users: ' + String(panel.total_users).replace('-1', '`Unknown`') + '\n' - if (client.config.panel_resource.servers) stats = stats + 'Servers: ' + String(panel.total_servers).replace('-1', '`Unknown`') + if (client.config.panel_settings.users) stats = stats + 'Users: ' + String(panel.total_users).replace('-1', '`Unknown`') + '\n' + if (client.config.panel_settings.servers) stats = stats + 'Servers: ' + String(panel.total_servers).replace('-1', '`Unknown`') EmbedFields.push({ name: 'Panel Stats', value: stats }) } - if (client.config.embed.field.enable) EmbedFields.push({ name: client.config.embed.field.title, value: client.config.embed.field.description.replaceAll('{{time}}', format) }) + if (client.config.embed.field.title && client.config.embed.field.description) EmbedFields.push({ name: client.config.embed.field.title, value: client.config.embed.field.description.replaceAll('{{time}}', format) }) if (client.config.embed.timestamp) embed.setTimestamp() if (EmbedFields.length > 0) embed.addFields(EmbedFields) diff --git a/index.js b/index.js index 13cc7a3..4b49c6c 100644 --- a/index.js +++ b/index.js @@ -33,7 +33,7 @@ const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.config = yaml.load(fs.readFileSync('./config.yml', 'utf8')); if (client.config.panel.adminkey || client.config.resource || client.config.message.image) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('You are using old config file, please update your config file at https://github.com/HirziDevs/PteroStats/blob/main/config.yml !')) + console.log(chalk.cyan('[PteroStats] ') + chalk.red('You are using old config file, please update your config file at ') + chalk.green('https://github.com/HirziDevs/PteroStats/blob/main/config.yml ')) process.exit() } if (client.config.token.startsWith('Put') || !client.config.token.length) { From 991f42aec0afe1d07355516f41d711034bc1ca0f Mon Sep 17 00:00:00 2001 From: Hirzi <64255651+HirziDevs@users.noreply.github.com> Date: Tue, 29 Nov 2022 15:11:34 +0000 Subject: [PATCH 06/32] Fix typo --- config.yml | 6 +++--- index.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config.yml b/config.yml index 81e9ddb..b29fb40 100644 --- a/config.yml +++ b/config.yml @@ -17,7 +17,7 @@ panel: url: 'Put panel url here' key: 'Put panel apikey here' -# Message Configuration +# Message and Embed Configuration # leave '' if you want to disable option message: content: '' @@ -55,13 +55,13 @@ button: url: '' # Status Message Configuration -# How to use custom emoji: htttps://github.com/HirziDevs/PteroStats#using-custom-emoji +# How to use custom emoji: https://github.com/HirziDevs/PteroStats#using-custom-emoji status: online: ':green_circle: Online' offline: ':red_circle: Offline' # Nodes Settings -# How to get nodes id: htttps://github.com/HirziDevs/PteroStats#blacklist-nodes +# How to get nodes id: https://github.com/HirziDevs/PteroStats#blacklist-nodes nodes_settings: blacklist: [] # You can add node id to remove the node from status embed (Example: "blacklist: [1]") enable: false diff --git a/index.js b/index.js index 4b49c6c..6d3bffb 100644 --- a/index.js +++ b/index.js @@ -33,7 +33,7 @@ const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.config = yaml.load(fs.readFileSync('./config.yml', 'utf8')); if (client.config.panel.adminkey || client.config.resource || client.config.message.image) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('You are using old config file, please update your config file at ') + chalk.green('https://github.com/HirziDevs/PteroStats/blob/main/config.yml ')) + console.log(chalk.cyan('[PteroStats] ') + chalk.red('You are using old config file, please update your config file at ') + chalk.green('https://github.com/HirziDevs/PteroStats/blob/main/config.yml')) process.exit() } if (client.config.token.startsWith('Put') || !client.config.token.length) { From fa062bb42e525c4ab8a65c6ac8cf57734b7ae449 Mon Sep 17 00:00:00 2001 From: Hirzi <64255651+HirziDevs@users.noreply.github.com> Date: Sun, 25 Dec 2022 12:39:53 +0000 Subject: [PATCH 07/32] feat: Nodes error logging --- Indo.md | 6 ++--- README.md | 6 ++--- config.yml | 14 ++++++++-- events/ready.js | 12 ++++++++- handlers/checkStatus.js | 60 +++++++++++++++++++++++++++++++++++++---- handlers/postStatus.js | 10 ++++--- index.js | 46 ++++++++++++++++++++++--------- package.json | 6 ++--- 8 files changed, 124 insertions(+), 36 deletions(-) diff --git a/Indo.md b/Indo.md index 7ec23b7..a41df97 100644 --- a/Indo.md +++ b/Indo.md @@ -114,11 +114,9 @@ Kamu bisa memasukan lebih dari 1 node untuk di blacklist Blacklist Config -## Permission apikey +## Nodenya online tapi di embed dibilang offline -Jika kamu mengalami error 403 coba aktifkan `read & write` di semua opsi permission - -Application API Permission +Jika kamu mengalami isu ini, atur `log_error` menjadi true di file config dan beri tahu kami di [Support Server](https://discord.gg/zv6maQRah3) ## Links diff --git a/README.md b/README.md index 3fe7082..7baa5bd 100644 --- a/README.md +++ b/README.md @@ -114,11 +114,9 @@ You can add more than one node in the blacklist Blacklist Config -## Apikey permission +## The node is online but the embed is read as offline -If you having issue with 403 error try to enable `read & write` on all options - -Application API Permission +If you having this issue, you can enable `log_error` on the config file and report it to our discord server at [Support Server](https://discord.gg/zv6maQRah3) ## Links diff --git a/config.yml b/config.yml index b29fb40..434817c 100644 --- a/config.yml +++ b/config.yml @@ -10,7 +10,8 @@ presence: # Discord Channel and Refresh Time Configuration channel: 'Put channel id here' -refresh: 60 +refresh: 60 # How much time the bot will refresh the stats +timeout: 1 # How much time to wait some node to respond to the bot (if you change this, it will add more time to refresh the stats) # Panel Configuration panel: @@ -73,4 +74,13 @@ nodes_settings: # Panel Users and Servers Settings panel_settings: servers: true - users: true \ No newline at end of file + users: true + +# Mentions a User or Role if some nodes are offline (this feature is still in testing, please report if you have a problem) +mentions: # to enable atleast put 1 ID on user or role bellow + user: [] # Put User ID here (Example: "user: ['548867757517570058', '816219634390663230']") + role: [] # Put Role ID here (Example: "role: ['796083838236622858', '858198863973187585']") + channel: '' # Put Channel ID here for the logging + +# Log error to console if server offline (enable this if you have a problem that you wanted to report) +log_error: false # set to "true" to enable \ No newline at end of file diff --git a/events/ready.js b/events/ready.js index c02c793..e222be0 100644 --- a/events/ready.js +++ b/events/ready.js @@ -8,9 +8,19 @@ module.exports = { execute(client) { console.log(chalk.cyan('[PteroStats] ') + chalk.green('Bot is up!')) console.log(chalk.cyan('[PteroStats] ') + chalk.green('If you need support you can join our discord server https://discord.gg/zv6maQRah3')) + console.log(chalk.cyan('[PteroStats] ') + chalk.yellow('If some node is online but the embed is read as offline, please enable ') + chalk.green('log_error') + chalk.yellow(' on config file and report it at https://discord.gg/zv6maQRah3')) if (client.guilds.cache.size < 1) return console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! This bot is not on any discord servers')) - if (client.config.refresh < 10) console.log(chalk.cyan('[PteroStats] ') + chalk.red('Refresh lower than 10 seconds is not recommended!')) + if (client.config.timeout < 1) { + console.log(chalk.cyan('[PteroStats] ') + chalk.red('Timeout cannot be less than 1 seconds!')) + client.config.timeout = 1 + } + + if (client.config.refresh > 1 && client.config.refresh < 10) console.log(chalk.cyan('[PteroStats] ') + chalk.red('Refresh Time below 10 seconds is not recommended!')) + else if (client.config.refresh < 1) { + console.log(chalk.cyan('[PteroStats] ') + chalk.red('Refresh Time cannot be less than 1 seconds!')) + client.config.refresh = 10 + } if (client.config.bot_status || client.config.nodes_resource || client.config.panel_resource) { console.log(chalk.cyan('[PteroStats] ') + chalk.red('You used `bot_status`, `panel_resource` and `nodes_resource` instead of `presence`, `panel_settings` and `nodes_settings` in the config, please update your config file at ') + chalk.green('https://github.com/HirziDevs/PteroStats/blob/main/config.yml ') + chalk.red('before it can no longer be supported')) diff --git a/handlers/checkStatus.js b/handlers/checkStatus.js index ef1d119..0b21feb 100644 --- a/handlers/checkStatus.js +++ b/handlers/checkStatus.js @@ -1,3 +1,4 @@ +const { EmbedBuilder } = require('discord.js') const axios = require('axios') const chalk = require('chalk') @@ -5,6 +6,15 @@ const postStatus = require('./postStatus') module.exports = function checkStatus({ client }) { + function Embed({ node }) { + return new EmbedBuilder() + .setTitle('Node Logging') //if you wanted to change this please change at line 175 too + .setDescription('`' + node.name + '` is down!') + .setFooter({ text: 'Please see console for more details' }) + .setTimestamp() + .setColor('ED4245') + } + if (client.config.channel.startsWith('Put')) { console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Channel ID')) process.exit() @@ -23,6 +33,7 @@ module.exports = function checkStatus({ client }) { if (client.config.panel.url.endsWith('/')) client.config.panel.url = client.config.panel.url.slice(0, -1) const nodes = [] + const embeds = [] const panel = { status: false, @@ -113,14 +124,21 @@ module.exports = function checkStatus({ client }) { } }).then(() => { return statsResolve() - }).catch(() => { + }).catch((error) => { + if (client.config.log_error) console.log(chalk.cyan('[PteroStats] ') + chalk.yellow('[Node: ' + node.attributes.name + '] ') + chalk.red(error)) + embeds.push(Embed({ node: body })) body.status = false return statsResolve() }) setTimeout(() => { - body.status = false - return statsResolve() - }, 1000) + if (body.status === undefined) { + console.log(body.status) + if (client.config.log_error) console.log(chalk.cyan('[PteroStats] ') + chalk.yellow('[Node: ' + node.attributes.name + '] ') + chalk.red('Timeout!')) + embeds.push(Embed({ node: body })) + body.status = false + return statsResolve() + } + }, client.config.timeout * 1000) }) stats.then(() => { nodes.push(body) @@ -132,9 +150,41 @@ module.exports = function checkStatus({ client }) { }) panelStats.then(() => { - nodeStats.then(() => { + nodeStats.then(async () => { nodes.sort(function (a, b) { return a.id - b.id }) postStatus({ client: client, panel: panel, nodes: nodes }) + + // this feature is still in testing + if (client.config.mentions.user.length > 0 || client.config.mentions.role.length > 0 && client.config.mentions.channel) { + if (Array.isArray(client.config.mentions.user) || Array.isArray(client.config.mentions.role)) { + let mentions = '' + + await client.config.mentions.user.forEach((user) => { + if (!isNaN(Number(user))) { + mentions = mentions + ' <@' + user + '>' + } + }) + await client.config.mentions.role.forEach((role) => { + if (!isNaN(Number(role))) { + mentions = mentions + ' <@&' + role + '>' + } + }) + + const channel = await client.channels.cache.get(client.config.mentions.channel) + if (channel) { + const messages = await channel.messages.fetch({ limit: 10 }).then(msg => msg.filter(m => m.author.id === client.user.id && m.embeds[0].data.title === 'Node Logging').first()) + if (messages) messages.embeds.forEach((MsgEmbed) => { + embeds.forEach((embed, i) => { + if (MsgEmbed.data.description === embed.data.description) embeds.splice(i, 1) + nodes.forEach((node) => { + if (MsgEmbed.data.description.startsWith('`' + node.name) && node.status === true) messages.delete() + }) + }) + }) + if (embeds.length > 0) channel.send({ content: mentions, embeds: embeds }) + } + } + } }) }) } \ No newline at end of file diff --git a/handlers/postStatus.js b/handlers/postStatus.js index c34cae5..2389473 100644 --- a/handlers/postStatus.js +++ b/handlers/postStatus.js @@ -85,10 +85,12 @@ module.exports = async function postStatus({ client, panel, nodes }) { text = '\nThere is no nodes to display' resolve() } else { - text = messages.embeds[0].description.replaceAll(client.config.status.online, client.config.status.offline) - if (!panel.status && String(String(messages.embeds[0].fields[0].value).split('\n')[2]).split('')[String(String(messages.embeds[0].fields[0].value).split('\n')[2]).length - 1] !== '`') { - panel.total_users = String(String(messages.embeds[0].fields[0].value).split('\n')[2]).split('')[String(String(messages.embeds[0].fields[0].value).split('\n')[2]).length - 1] - panel.total_servers = String(String(messages.embeds[0].fields[0].value).split('\n')[3]).split('')[String(String(messages.embeds[0].fields[0].value).split('\n')[3]).length - 1] + if (messages.embeds.length > 0 && client.config.embed.title && messages.embeds[0].data.title === client.config.embed.title) { + text = messages.embeds[0].description.replaceAll(client.config.status.online, client.config.status.offline) + if (!panel.status && String(String(messages.embeds[0].fields[0].value).split('\n')[2]).split('')[String(String(messages.embeds[0].fields[0].value).split('\n')[2]).length - 1] !== '`') { + panel.total_users = String(String(messages.embeds[0].fields[0].value).split('\n')[2]).split('')[String(String(messages.embeds[0].fields[0].value).split('\n')[2]).length - 1] + panel.total_servers = String(String(messages.embeds[0].fields[0].value).split('\n')[3]).split('')[String(String(messages.embeds[0].fields[0].value).split('\n')[3]).length - 1] + } } resolve() } diff --git a/index.js b/index.js index 6d3bffb..82a7657 100644 --- a/index.js +++ b/index.js @@ -1,21 +1,10 @@ const fs = require('fs'); const child = require('child_process'); -const chalk = require('chalk'); -const yaml = require('js-yaml'); -if (Number(process.version.split('.')[0]) < 16) { - console.log('Invalid NodeJS Version!, Please use NodeJS 16.x or upper') - process.exit() -} -if (fs.existsSync('./node_modules')) { - const check = require('./node_modules/discord.js/package.json') - if (Number(check.version.split('.')[0]) !== 14) { - console.log('Invalid Discord.JS Version!, Please use Discord.JS 14.x') - process.exit() - } -} else { +function InstallPackages() { console.log('You didn\'t install the required node packages first!') console.log('Please wait... starting to install all required node packages using child process') + console.log('If the bot can\'t install the package please install it manually') try { child.execSync('npm i') console.log('Install complete!, please run "node index" command again!') @@ -27,6 +16,37 @@ if (fs.existsSync('./node_modules')) { } } +if (Number(process.version.split('.')[0]) < 16) { + console.log('Invalid NodeJS Version!, Please use NodeJS 16.x or upper') + process.exit() +} +if (fs.existsSync('./node_modules')) { + if (fs.existsSync('./node_modules/discord.js')) { + const check = require('./node_modules/discord.js/package.json') + if (Number(check.version.split('.')[0]) !== 14) { + console.log('Invalid Discord.JS Version!, Please use Discord.JS 14.x') + process.exit() + } + } else InstallPackages() + if (fs.existsSync('./node_modules/axios')) { + const check = require('./node_modules/axios/package.json') + if (Number(check.version.split('.')[1]) > 1) { + console.log('Invalid Axios Version!, Please use Axios 1.1.3') + process.exit() + } + } else InstallPackages() + if (fs.existsSync('./node_modules/chalk')) { + const check = require('./node_modules/chalk/package.json') + if (Number(check.version.split('.')[0]) > 4) { + console.log('Invalid Chalk Version!, Please use Chalk 4.1.2') + process.exit() + } + } else InstallPackages() + if (!fs.existsSync('./node_modules/js-yaml')) InstallPackages() +} else InstallPackages() + +const chalk = require('chalk'); +const yaml = require('js-yaml'); const { Client, GatewayIntentBits } = require('discord.js'); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); diff --git a/package.json b/package.json index 61efb73..9a00948 100644 --- a/package.json +++ b/package.json @@ -14,11 +14,11 @@ }, "dependencies": { "axios": "1.1.3", - "chalk": "4.1.1", - "discord.js": "^14.6.0", + "chalk": "4.1.2", + "discord.js": "^14.7.1", "js-yaml": "^4.1.0" }, "engines": { - "node": "^16.x" + "node": ">=16.9.0" } } \ No newline at end of file From e03c0daf2f0ff3c2b60a218d60cd628ef992559b Mon Sep 17 00:00:00 2001 From: Hirzi <64255651+HirziDevs@users.noreply.github.com> Date: Tue, 27 Dec 2022 04:10:39 +0000 Subject: [PATCH 08/32] fix: cannot post stats --- handlers/checkStatus.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/handlers/checkStatus.js b/handlers/checkStatus.js index 0b21feb..240782d 100644 --- a/handlers/checkStatus.js +++ b/handlers/checkStatus.js @@ -105,7 +105,6 @@ module.exports = function checkStatus({ client }) { name: node.attributes.name, location: node.attributes.relationships.location.attributes.short, allocations: node.attributes.relationships.allocations.data.length, - status: true, maintenance: node.attributes.maintenance_mode, total_servers: node.attributes.relationships.servers.data.length, memory_min: node.attributes.allocated_resources.memory, @@ -123,6 +122,7 @@ module.exports = function checkStatus({ client }) { Authorization: 'Bearer ' + data.data.token } }).then(() => { + body.status = true return statsResolve() }).catch((error) => { if (client.config.log_error) console.log(chalk.cyan('[PteroStats] ') + chalk.yellow('[Node: ' + node.attributes.name + '] ') + chalk.red(error)) @@ -132,7 +132,6 @@ module.exports = function checkStatus({ client }) { }) setTimeout(() => { if (body.status === undefined) { - console.log(body.status) if (client.config.log_error) console.log(chalk.cyan('[PteroStats] ') + chalk.yellow('[Node: ' + node.attributes.name + '] ') + chalk.red('Timeout!')) embeds.push(Embed({ node: body })) body.status = false From 46c94908dfcbb608d672b867e5517a2288adf927 Mon Sep 17 00:00:00 2001 From: Hirzi <64255651+HirziDevs@users.noreply.github.com> Date: Mon, 2 Jan 2023 13:15:40 +0000 Subject: [PATCH 09/32] refactor!: change `enable` at nodes_settings to `details` and add `status` at panel_settings to enable or disable panel status field --- config.yml | 3 ++- events/ready.js | 7 ------- handlers/postStatus.js | 4 ++-- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/config.yml b/config.yml index 434817c..671a8f4 100644 --- a/config.yml +++ b/config.yml @@ -65,7 +65,7 @@ status: # How to get nodes id: https://github.com/HirziDevs/PteroStats#blacklist-nodes nodes_settings: blacklist: [] # You can add node id to remove the node from status embed (Example: "blacklist: [1]") - enable: false + details: false # enable nodes details like memory and disk servers: true location: true allocations: true @@ -73,6 +73,7 @@ nodes_settings: # Panel Users and Servers Settings panel_settings: + status: true # enable panel stats under nodes stats servers: true users: true diff --git a/events/ready.js b/events/ready.js index e222be0..ab21a3a 100644 --- a/events/ready.js +++ b/events/ready.js @@ -22,13 +22,6 @@ module.exports = { client.config.refresh = 10 } - if (client.config.bot_status || client.config.nodes_resource || client.config.panel_resource) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('You used `bot_status`, `panel_resource` and `nodes_resource` instead of `presence`, `panel_settings` and `nodes_settings` in the config, please update your config file at ') + chalk.green('https://github.com/HirziDevs/PteroStats/blob/main/config.yml ') + chalk.red('before it can no longer be supported')) - client.config.presence = client.config.bot_status - client.config.nodes_settings = client.config.nodes_resource - client.config.panel_settings = client.config.panel_resource - } - if (client.config.presence.text && client.config.presence.type) { switch (client.config.presence.type.toLowerCase()) { case 'playing': diff --git a/handlers/postStatus.js b/handlers/postStatus.js index 2389473..c4977ab 100644 --- a/handlers/postStatus.js +++ b/handlers/postStatus.js @@ -68,7 +68,7 @@ module.exports = async function postStatus({ client, panel, nodes }) { description = description + '\n```' - if (client.config.nodes_settings.enable) { + if (client.config.nodes_settings.details) { text = text + '\n**' + title.replace(':', ':**') + '\n' + description } else { text = text + '\n**' + title.replace(':', ':**') @@ -102,7 +102,7 @@ module.exports = async function postStatus({ client, panel, nodes }) { embed.setDescription(desc.replaceAll('{{time}}', format) + '\n**Nodes Stats [' + Math.floor(nodes.length - blacklist) + ']**' + text) const EmbedFields = [] - if (client.config.panel_settings.users || client.config.panel_settings.servers) { + if (client.config.panel_settings.status) { let stats = '**Status:** ' + String(panel.status).replace('true', client.config.status.online).replace('false', client.config.status.offline) + '\n\n' if (client.config.panel_settings.users) stats = stats + 'Users: ' + String(panel.total_users).replace('-1', '`Unknown`') + '\n' From 69d545da3312def96c5ebdbfadc5b50081f5fd25 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Date: Sun, 19 Mar 2023 21:17:26 -0300 Subject: [PATCH 10/32] fix: Pterodactyl Api Documentation link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7baa5bd..cf3aafc 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ If you having this issue, you can enable `log_error` on the config file and repo - [PteroStats DiscordJS v13](https://github.com/HirziDevs/PteroStats/tree/3d0512c3323ecf079101104c7ecf3c94d265e298) - [PteroStats DiscordJS v12](https://github.com/HirziDevs/PteroStats/tree/bcfa266be64dda11955f0bf9732da086bcea522c) - [Pterodactyl Panel](https://pterodactyl.io) -- [Pterodactyl Api Documentation](https://dashflo/docs/api/pterodactyl/v1) +- [Pterodactyl Api Documentation](https://dashflo.net/docs/api/pterodactyl/v1) - [Pterodactyl Discord Server](https://discord.gg/pterodactyl) - [PteroBot Support Server](https://discord.gg/zv6maQRah3) -- [PteroBot Support Server (Indonesia)](https://discord.gg/EYaFB7WSg6) \ No newline at end of file +- [PteroBot Support Server (Indonesia)](https://discord.gg/EYaFB7WSg6) From bf2cbf24a199ebfe23bb3b103cb3f892a2064037 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Date: Sun, 19 Mar 2023 21:54:58 -0300 Subject: [PATCH 11/32] fix: Pterodactyl Api Documentation 404 Not Found --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf3aafc..96efd82 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ If you having this issue, you can enable `log_error` on the config file and repo - [PteroStats DiscordJS v13](https://github.com/HirziDevs/PteroStats/tree/3d0512c3323ecf079101104c7ecf3c94d265e298) - [PteroStats DiscordJS v12](https://github.com/HirziDevs/PteroStats/tree/bcfa266be64dda11955f0bf9732da086bcea522c) - [Pterodactyl Panel](https://pterodactyl.io) -- [Pterodactyl Api Documentation](https://dashflo.net/docs/api/pterodactyl/v1) +- [Pterodactyl Api Documentation](https://dashflo.net/docs/api/pterodactyl/v1/) - [Pterodactyl Discord Server](https://discord.gg/pterodactyl) - [PteroBot Support Server](https://discord.gg/zv6maQRah3) - [PteroBot Support Server (Indonesia)](https://discord.gg/EYaFB7WSg6) From 9b2e6adefad700e20c8aebc4c023e7c6944ba748 Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Tue, 11 Jul 2023 18:11:17 +0530 Subject: [PATCH 12/32] New Features-Replace promises with async await, recoded and fixed bugs i could find, created seperate modules for calculation, made the pakcges intrigity check better, updated packages version --- events/ready.js | 125 +++++--- handlers/checkStatus.js | 500 +++++++++++++++++++++----------- handlers/postStatus.js | 496 +++++++++++++++++++++---------- index.js | 103 +++---- modules/intigrityCheck.js | 127 ++++++++ modules/memorySizeConverter.js | 44 +++ modules/percentageCalculator.js | 16 + package.json | 9 +- 8 files changed, 985 insertions(+), 435 deletions(-) create mode 100644 modules/intigrityCheck.js create mode 100644 modules/memorySizeConverter.js create mode 100644 modules/percentageCalculator.js diff --git a/events/ready.js b/events/ready.js index ab21a3a..1a5a0ed 100644 --- a/events/ready.js +++ b/events/ready.js @@ -1,55 +1,90 @@ -const { ActivityType } = require('discord.js') -const chalk = require('chalk') -const checkStatus = require('../handlers/checkStatus') +const { ActivityType } = require("discord.js"); +const chalk = require("chalk"); +const checkStatus = require("../handlers/checkStatus"); module.exports = { - name: 'ready', - once: true, - execute(client) { - console.log(chalk.cyan('[PteroStats] ') + chalk.green('Bot is up!')) - console.log(chalk.cyan('[PteroStats] ') + chalk.green('If you need support you can join our discord server https://discord.gg/zv6maQRah3')) - console.log(chalk.cyan('[PteroStats] ') + chalk.yellow('If some node is online but the embed is read as offline, please enable ') + chalk.green('log_error') + chalk.yellow(' on config file and report it at https://discord.gg/zv6maQRah3')) + name: "ready", + once: true, + execute(client) { + console.log(chalk.cyan("[PteroStats] ") + chalk.green("Bot is up!")); + console.log( + chalk.cyan("[PteroStats] ") + + chalk.green( + "If you need support you can join our discord server https://discord.gg/zv6maQRah3" + ) + ); + console.log( + chalk.cyan("[PteroStats] ") + + chalk.yellow( + "If some node is online but the embed is read as offline, please enable " + ) + + chalk.green("log_error") + + chalk.yellow( + " on config file and report it at https://discord.gg/zv6maQRah3" + ) + ); - if (client.guilds.cache.size < 1) return console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! This bot is not on any discord servers')) - if (client.config.timeout < 1) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Timeout cannot be less than 1 seconds!')) - client.config.timeout = 1 - } + if (client.guilds.cache.size < 1) + return console.log( + chalk.cyan("[PteroStats] ") + + chalk.red("Error! This bot is not on any discord servers") + ); + if (client.config.timeout < 1) { + console.log( + chalk.cyan("[PteroStats] ") + + chalk.red("Timeout cannot be less than 1 seconds!") + ); + client.config.timeout = 1; + } - if (client.config.refresh > 1 && client.config.refresh < 10) console.log(chalk.cyan('[PteroStats] ') + chalk.red('Refresh Time below 10 seconds is not recommended!')) - else if (client.config.refresh < 1) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Refresh Time cannot be less than 1 seconds!')) - client.config.refresh = 10 - } + if (client.config.refresh > 1 && client.config.refresh < 10) + console.log( + chalk.cyan("[PteroStats] ") + + chalk.red("Refresh Time below 10 seconds is not recommended!") + ); + else if (client.config.refresh < 1) { + console.log( + chalk.cyan("[PteroStats] ") + + chalk.red("Refresh Time cannot be less than 1 seconds!") + ); + client.config.refresh = 10; + } - if (client.config.presence.text && client.config.presence.type) { - switch (client.config.presence.type.toLowerCase()) { - case 'playing': - client.config.presence.type = ActivityType.Playing - break; - case 'listening': - client.config.presence.type = ActivityType.Listening - break; - case 'competing': - client.config.presence.type = ActivityType.Competing - break; - default: - client.config.presence.type = ActivityType.Watching - } + if (client.config.presence.text && client.config.presence.type) { + switch (client.config.presence.type.toLowerCase()) { + case "playing": + client.config.presence.type = ActivityType.Playing; + break; + case "listening": + client.config.presence.type = ActivityType.Listening; + break; + case "competing": + client.config.presence.type = ActivityType.Competing; + break; + default: + client.config.presence.type = ActivityType.Watching; + } - client.user.setActivity(client.config.presence.text, { type: client.config.presence.type }) - } + client.user.setActivity(client.config.presence.text, { + type: client.config.presence.type, + }); + } - if (client.config.presence.status) { - if (!['idle', 'online', 'dnd', 'invisible'].includes(client.config.presence.status.toLowerCase())) client.config.presence.status = 'online' + if (client.config.presence.status) { + if ( + !["idle", "online", "dnd", "invisible"].includes( + client.config.presence.status.toLowerCase() + ) + ) + client.config.presence.status = "online"; - client.user.setStatus(client.config.presence.status); - } + client.user.setStatus(client.config.presence.status); + } - checkStatus({ client: client }) + checkStatus({ client: client }); - setInterval(() => { - checkStatus({ client: client }) - }, client.config.refresh * 1000) - } -} \ No newline at end of file + setInterval(async () => { + await checkStatus({ client: client }); + }, client.config.refresh * 1000); + }, +}; diff --git a/handlers/checkStatus.js b/handlers/checkStatus.js index 240782d..e5a2002 100644 --- a/handlers/checkStatus.js +++ b/handlers/checkStatus.js @@ -1,189 +1,343 @@ -const { EmbedBuilder } = require('discord.js') -const axios = require('axios') -const chalk = require('chalk') +const { EmbedBuilder } = require("discord.js"); +const axios = require("axios"); +const axiosRetry = require("axios-retry"); +const chalk = require("chalk"); -const postStatus = require('./postStatus') +const postStatus = require("./postStatus"); -module.exports = function checkStatus({ client }) { +axiosRetry(axios, { retries: 5 }); - function Embed({ node }) { - return new EmbedBuilder() - .setTitle('Node Logging') //if you wanted to change this please change at line 175 too - .setDescription('`' + node.name + '` is down!') - .setFooter({ text: 'Please see console for more details' }) - .setTimestamp() - .setColor('ED4245') - } +module.exports = async ({ client }) => { + function Embed({ node }) { + return new EmbedBuilder() + .setTitle("Node Logging") //if you wanted to change this please change at line 175 too + .setDescription("`" + node.name + "` is down!") + .setFooter({ text: "Please see console for more details" }) + .setTimestamp() + .setColor("ED4245"); + } - if (client.config.channel.startsWith('Put')) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Channel ID')) - process.exit() - } else if (client.config.panel.url.startsWith('Put')) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Panel URL')) - process.exit() - } else if (client.config.panel.key.startsWith('Put')) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Apikey')) - process.exit() - } else if (!client.config.panel.url.startsWith('http')) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Panel URL')) - console.log(chalk.cyan('[PteroStats] ') + chalk.red('1. Make sure the panel url is starts with "https://" or "http://"')) - process.exit() - } + if (client.config.channel.startsWith("Put")) { + console.log( + chalk.cyan("[PteroStats] ") + chalk.red("Error! Invalid Channel ID") + ); + process.exit(); + } else if (client.config.panel.url.startsWith("Put")) { + console.log( + chalk.cyan("[PteroStats] ") + chalk.red("Error! Invalid Panel URL") + ); + process.exit(); + } else if (client.config.panel.key.startsWith("Put")) { + console.log( + chalk.cyan("[PteroStats] ") + chalk.red("Error! Invalid Apikey") + ); + process.exit(); + } else if (!client.config.panel.url.startsWith("http")) { + console.log( + chalk.cyan("[PteroStats] ") + chalk.red("Error! Invalid Panel URL") + ); + console.log( + chalk.cyan("[PteroStats] ") + + chalk.red( + '1. Make sure the panel url is starts with "https://" or "http://"' + ) + ); + process.exit(); + } - if (client.config.panel.url.endsWith('/')) client.config.panel.url = client.config.panel.url.slice(0, -1) + if (client.config.panel.url.endsWith("/")) + client.config.panel.url = client.config.panel.url.slice(0, -1); - const nodes = [] - const embeds = [] + const nodes = []; + const embeds = []; - const panel = { - status: false, - total_servers: -1, - total_users: -1, - } + const panel = { + status: false, + total_servers: -1, + total_users: -1, + }; - console.log(chalk.cyan('[PteroStats] ') + chalk.green('Getting nodes stats')) + console.log(chalk.cyan("[PteroStats] ") + chalk.green("Getting nodes stats")); - const panelStats = new Promise((resolve, reject) => { - axios(client.config.panel.url + '/api/application/users', { - method: 'GET', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - Authorization: 'Bearer ' + client.config.panel.key - } - }).then((users) => { - axios(client.config.panel.url + '/api/application/servers', { - method: 'GET', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - Authorization: 'Bearer ' + client.config.panel.key - } - }).then((servers) => { - panel.total_users = users.data.meta.pagination.total - panel.total_servers = servers.data.meta.pagination.total - panel.status = true + try { + const users = await axios( + client.config.panel.url + "/api/application/users", + { + method: "GET", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + Authorization: "Bearer " + client.config.panel.key, + }, + } + ); - resolve() - }) - }).catch((error) => { - if (error.response) { - if (error.response.status === 403) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid apikey')) - console.log(chalk.cyan('[PteroStats] ') + chalk.red('1. Make sure the apikey is from admin page not account page')) - console.log(chalk.cyan('[PteroStats] ') + chalk.red('2. Make sure the apikey has read permission on all options')) - console.log(chalk.cyan('[PteroStats] ') + chalk.red('3. Make sure the apikey is exist')) - } else if (error.response.status === 404) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Panel URL')) - console.log(chalk.cyan('[PteroStats] ') + chalk.red('1. Make sure the panel url is like "https://panel.example.com"')) - } else console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! ' + error)) - } else console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! ' + error)) - resolve() - }) - }) + if (users?.status === 200 && users?.data) { + const servers = await axios( + client.config.panel.url + "/api/application/servers", + { + method: "GET", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + Authorization: "Bearer " + client.config.panel.key, + }, + } + ); - const nodeStats = new Promise((resolve, reject) => { - axios(client.config.panel.url + '/api/application/nodes?include=servers,location,allocations', { - method: 'GET', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - Authorization: 'Bearer ' + client.config.panel.key - } - }).then((res) => { - res.data.data.forEach((node, i) => { - axios(client.config.panel.url + '/api/application/nodes/' + node.attributes.id + '/configuration', { - method: 'GET', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - Authorization: 'Bearer ' + client.config.panel.key - } - }).then((data) => { - const body = { - id: node.attributes.id, - name: node.attributes.name, - location: node.attributes.relationships.location.attributes.short, - allocations: node.attributes.relationships.allocations.data.length, - maintenance: node.attributes.maintenance_mode, - total_servers: node.attributes.relationships.servers.data.length, - memory_min: node.attributes.allocated_resources.memory, - memory_max: node.attributes.memory, - disk_min: node.attributes.allocated_resources.disk, - disk_max: node.attributes.disk, - } + if (servers?.status === 200 && users?.data) { + panel.total_users = users?.data?.meta?.pagination?.total || "ERROR"; + panel.total_servers = servers?.data.meta?.pagination?.total || "ERROR"; + panel.status = true; - const stats = new Promise((statsResolve, statsReject) => { - axios(node.attributes.scheme + '://' + node.attributes.fqdn + ':' + node.attributes.daemon_listen + '/api/servers', { - method: 'GET', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - Authorization: 'Bearer ' + data.data.token - } - }).then(() => { - body.status = true - return statsResolve() - }).catch((error) => { - if (client.config.log_error) console.log(chalk.cyan('[PteroStats] ') + chalk.yellow('[Node: ' + node.attributes.name + '] ') + chalk.red(error)) - embeds.push(Embed({ node: body })) - body.status = false - return statsResolve() - }) - setTimeout(() => { - if (body.status === undefined) { - if (client.config.log_error) console.log(chalk.cyan('[PteroStats] ') + chalk.yellow('[Node: ' + node.attributes.name + '] ') + chalk.red('Timeout!')) - embeds.push(Embed({ node: body })) - body.status = false - return statsResolve() - } - }, client.config.timeout * 1000) - }) - stats.then(() => { - nodes.push(body) - if (nodes.length === res.data.data.length) resolve() - }) - }).catch(() => resolve()) - }) - }).catch(() => resolve()) - }) + const res = await axios( + client.config.panel.url + + "/api/application/nodes?include=servers,location,allocations", + { + method: "GET", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + Authorization: "Bearer " + client.config.panel.key, + }, + } + ); - panelStats.then(() => { - nodeStats.then(async () => { - nodes.sort(function (a, b) { return a.id - b.id }) - postStatus({ client: client, panel: panel, nodes: nodes }) + if (res?.status === 200 && res?.data?.data) { + for (const node of res.data.data) { + const data = await axios( + client.config.panel.url + + "/api/application/nodes/" + + node.attributes.id + + "/configuration", + { + method: "GET", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + Authorization: "Bearer " + client.config.panel.key, + }, + } + ); - // this feature is still in testing - if (client.config.mentions.user.length > 0 || client.config.mentions.role.length > 0 && client.config.mentions.channel) { - if (Array.isArray(client.config.mentions.user) || Array.isArray(client.config.mentions.role)) { - let mentions = '' + if (data?.status === 200 && data?.data) { + const body = { + id: node.attributes.id, + name: node.attributes.name, + location: + node.attributes.relationships.location.attributes.short, + allocations: + node.attributes.relationships.allocations.data.length, + maintenance: node.attributes.maintenance_mode, + total_servers: + node.attributes.relationships.servers.data.length, + memory_min: node.attributes.allocated_resources.memory, + memory_max: node.attributes.memory, + disk_min: node.attributes.allocated_resources.disk, + disk_max: node.attributes.disk, + }; - await client.config.mentions.user.forEach((user) => { - if (!isNaN(Number(user))) { - mentions = mentions + ' <@' + user + '>' - } - }) - await client.config.mentions.role.forEach((role) => { - if (!isNaN(Number(role))) { - mentions = mentions + ' <@&' + role + '>' - } - }) + try { + const stats = await axios( + node.attributes.scheme + + "://" + + node.attributes.fqdn + + ":" + + node.attributes.daemon_listen + + "/api/servers", + { + method: "GET", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + Authorization: "Bearer " + data.data.token, + }, + } + ); - const channel = await client.channels.cache.get(client.config.mentions.channel) - if (channel) { - const messages = await channel.messages.fetch({ limit: 10 }).then(msg => msg.filter(m => m.author.id === client.user.id && m.embeds[0].data.title === 'Node Logging').first()) - if (messages) messages.embeds.forEach((MsgEmbed) => { - embeds.forEach((embed, i) => { - if (MsgEmbed.data.description === embed.data.description) embeds.splice(i, 1) - nodes.forEach((node) => { - if (MsgEmbed.data.description.startsWith('`' + node.name) && node.status === true) messages.delete() - }) - }) - }) - if (embeds.length > 0) channel.send({ content: mentions, embeds: embeds }) - } - } - } - }) - }) -} \ No newline at end of file + if (stats?.status === 200 && stats?.data) { + body.status = true; + } else { + body.status = false; + } + + setTimeout(() => { + if (!body?.status) { + if (client.config.log_error) + console.log( + chalk.cyan("[PteroStats] ") + + chalk.yellow( + "[Node: " + node.attributes.name + "] " + ) + + chalk.red("Timeout!") + ); + embeds.push(Embed({ node: body })); + + body.status = false; + + return statsResolve(); + } + }, client.config.timeout * 1000); + } catch (error) { + if (client.config.log_error) + console.log( + chalk.cyan("[PteroStats] ") + + chalk.yellow("[Node: " + node.attributes.name + "] ") + + chalk.red(error) + ); + embeds.push(Embed({ node: body })); + + body.status = false; + } + + nodes.push(body); + } else { + throw new Error( + JSON.stringify({ + response: { + status: data.status, + }, + }) + ); + } + } + + nodes.sort(function (a, b) { + return a.id - b.id; + }); + + await postStatus({ client: client, panel: panel, nodes: nodes }); + + if ( + client.config.mentions.user.length > 0 || + (client.config.mentions.role.length > 0 && + client.config.mentions.channel) + ) { + if ( + Array.isArray(client.config.mentions.user) || + Array.isArray(client.config.mentions.role) + ) { + let mentions = ""; + + await client.config.mentions.user.forEach((user) => { + if (!isNaN(Number(user))) { + mentions = mentions + " <@" + user + ">"; + } + }); + await client.config.mentions.role.forEach((role) => { + if (!isNaN(Number(role))) { + mentions = mentions + " <@&" + role + ">"; + } + }); + + const channel = await client.channels.cache.get( + client.config.mentions.channel + ); + if (channel) { + const messages = await channel.messages + .fetch({ limit: 10 }) + .then((msg) => + msg + .filter( + (m) => + m.author.id === client.user.id && + m.embeds[0].data.title === "Node Logging" + ) + .first() + ); + if (messages) + messages.embeds.forEach((MsgEmbed) => { + for (const embed of embeds) { + if (MsgEmbed.data.description === embed.data.description) + embeds.splice(i, 1); + nodes.forEach((node) => { + if ( + MsgEmbed.data.description.startsWith( + "`" + node.name + ) && + node.status === true + ) + messages.delete(); + }); + } + }); + if (embeds.length > 0) + channel.send({ content: mentions, embeds: embeds }); + } + } + } + } else { + throw new Error( + JSON.stringify({ + response: { + status: res.status, + }, + }) + ); + } + } else { + throw new Error( + JSON.stringify({ + response: { + status: servers.status, + }, + }) + ); + } + } else { + throw new Error( + JSON.stringify({ + response: { + status: users.status, + }, + }) + ); + } + } catch (error) { + try { + if (typeof error === "string") { + error = JSON.parse(error); + } + } catch {} + + if (error?.response) { + if (error.response?.status === 403) { + console.log( + chalk.cyan("[PteroStats] ") + chalk.red("Error! Invalid apikey") + ); + console.log( + chalk.cyan("[PteroStats] ") + + chalk.red( + "1. Make sure the apikey is from admin page not account page" + ) + ); + console.log( + chalk.cyan("[PteroStats] ") + + chalk.red( + "2. Make sure the apikey has read permission on all options" + ) + ); + console.log( + chalk.cyan("[PteroStats] ") + + chalk.red("3. Make sure the apikey is exist") + ); + } else if (error.response?.status === 404) { + console.log( + chalk.cyan("[PteroStats] ") + chalk.red("Error! Invalid Panel URL") + ); + console.log( + chalk.cyan("[PteroStats] ") + + chalk.red( + '1. Make sure the panel url is like "https://panel.example.com"' + ) + ); + } else { + console.log( + chalk.cyan("[PteroStats] ") + chalk.red("Error! " + error) + ); + } + } else { + console.log(chalk.cyan("[PteroStats] ") + chalk.red("Error! " + error)); + } + } +}; diff --git a/handlers/postStatus.js b/handlers/postStatus.js index c4977ab..d07cbc7 100644 --- a/handlers/postStatus.js +++ b/handlers/postStatus.js @@ -1,169 +1,365 @@ -const { EmbedBuilder, time, ActionRowBuilder, ButtonBuilder, ButtonStyle, AttachmentBuilder } = require('discord.js') -const chalk = require('chalk') +const { + EmbedBuilder, + time, + ActionRowBuilder, + ButtonBuilder, + ButtonStyle, + AttachmentBuilder, +} = require("discord.js"); +const chalk = require("chalk"); -module.exports = async function postStatus({ client, panel, nodes }) { +const memorySizeConverter = require("../modules/memorySizeConverter"); +const percentageCalculator = require("../modules/percentageCalculator"); - const channel = await client.channels.cache.get(client.config.channel) - if (!channel) return console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Channel ID')) +const BUFFER_MS = 2000; //Added these extra milliseconds to prevent the stats timer from showing "1 or 2 seconds ago" before updating the stats. - const files = [] - const embed = new EmbedBuilder() - let messages = await channel.messages.fetch({ limit: 10 }).then(msg => msg.filter(m => m.author.id === client.user.id).last()) - let text = '' - let desc = '' - let blacklist = 0 - let content = null +module.exports = async ({ client, panel, nodes }) => { + const channel = await client.channels.cache.get(client.config.channel); + if (!channel) { + return console.log( + chalk.cyan("[PteroStats] ") + chalk.red("Error! Invalid Channel ID") + ); + } - if (!client.config.nodes_settings.blacklist) client.config.nodes_settings.blacklist = [] - if (!Array.isArray(client.config.nodes_settings.blacklist) && Number.isInteger(client.config.nodes_settings.blacklist)) client.config.nodes_settings.blacklist = [client.config.nodes_settings.blacklist] - if (client.guilds.cache.size < 1) return console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! This bot is not on any discord servers')) - if (messages && messages.embeds.length < 1) { - messages.delete() - messages = null - } + const files = []; - if (client.config.message.content) content = client.config.message.content - if (client.config.message.attachment) files.push(new AttachmentBuilder(client.config.message.attachment)) - if (client.config.embed.title) embed.setTitle(client.config.embed.title) - if (client.config.embed.description) desc = client.config.embed.description + '\n' - if (client.config.embed.color) embed.setColor(client.config.embed.color) - if (client.config.embed.footer) embed.setFooter({ text: client.config.embed.footer }) - if (client.config.embed.thumbnail) embed.setThumbnail(client.config.embed.thumbnail) - if (client.config.embed.image) embed.setImage(client.config.embed.image) + const embed = new EmbedBuilder(); - panel.total_users = panel.total_users.toLocaleString() - panel.total_servers = panel.total_servers.toLocaleString() + let messages = await channel.messages + .fetch({ limit: 10 }) + .then((msg) => msg.filter((m) => m.author.id === client.user.id).last()); - const stats = new Promise((resolve, reject) => { - if (nodes.length !== 0) { - nodes.forEach((data, i) => { - if (!client.config.nodes_settings.blacklist.includes(data.id)) { - const title = data.name + ': ' + String(data.status).replace('true', client.config.status.online).replace('false', client.config.status.offline) - let description = '```' - switch (client.config.nodes_settings.unit.toLowerCase()) { - case 'tb': - description = description + - '\nMemory : ' + Math.floor(data.memory_min / (1024 * 1000)).toLocaleString() + ' TB / ' + Math.floor(data.memory_max / (1024 * 1000)).toLocaleString() + ' TB' + - '\nDisk : ' + Math.floor(data.disk_min / (1024 * 1000)).toLocaleString() + ' TB / ' + Math.floor(data.disk_max / (1024 * 1000)).toLocaleString() + ' TB' - break; - case 'gb': - description = description + - '\nMemory : ' + Math.floor(data.memory_min / 1024).toLocaleString() + ' GB / ' + Math.floor(data.memory_max / 1024).toLocaleString() + ' GB' + - '\nDisk : ' + Math.floor(data.disk_min / 1024).toLocaleString() + ' GB / ' + Math.floor(data.disk_max / 1024).toLocaleString() + ' GB' - break; - case 'percent': - description = description + - '\nMemory : ' + Math.floor(data.memory_min / data.memory_max * 100) + ' %' + - '\nDisk : ' + Math.floor(data.disk_min / data.disk_max * 100) + ' %' - break; - default: - description = description + - '\nMemory : ' + data.memory_min.toLocaleString() + ' MB / ' + data.memory_max.toLocaleString() + ' MB' + - '\nDisk : ' + data.disk_min.toLocaleString() + ' MB / ' + data.disk_max.toLocaleString() + ' MB' - } + let text = ""; + let desc = ""; + let blacklist = 0; + let content = null; - if (client.config.nodes_settings.servers) description = description + '\nServers : ' + data.total_servers.toLocaleString() - if (client.config.nodes_settings.location) description = description + '\nLocation : ' + data.location - if (client.config.nodes_settings.allocations) description = description + '\nAllocations : ' + data.allocations.toLocaleString() + if (!client.config.nodes_settings.blacklist) { + client.config.nodes_settings.blacklist = []; + } - description = description + '\n```' + if ( + !Array.isArray(client.config.nodes_settings.blacklist) && + Number.isInteger(client.config.nodes_settings.blacklist) + ) { + client.config.nodes_settings.blacklist = [ + client.config.nodes_settings.blacklist, + ]; + } - if (client.config.nodes_settings.details) { - text = text + '\n**' + title.replace(':', ':**') + '\n' + description - } else { - text = text + '\n**' + title.replace(':', ':**') - } - } else { - blacklist = blacklist + 1 - if (nodes.length - client.config.nodes_settings.blacklist.length < 1) text = '\nThere is no nodes to display' - } + if (client.guilds.cache.size < 1) { + return console.log( + chalk.cyan("[PteroStats] ") + + chalk.red("Error! This bot is not on any discord servers") + ); + } - if (i + 1 === nodes.length) resolve() - }) - } else if (nodes.length < 1) { - if (!messages) { - text = '\nThere is no nodes to display' - resolve() - } else { - if (messages.embeds.length > 0 && client.config.embed.title && messages.embeds[0].data.title === client.config.embed.title) { - text = messages.embeds[0].description.replaceAll(client.config.status.online, client.config.status.offline) - if (!panel.status && String(String(messages.embeds[0].fields[0].value).split('\n')[2]).split('')[String(String(messages.embeds[0].fields[0].value).split('\n')[2]).length - 1] !== '`') { - panel.total_users = String(String(messages.embeds[0].fields[0].value).split('\n')[2]).split('')[String(String(messages.embeds[0].fields[0].value).split('\n')[2]).length - 1] - panel.total_servers = String(String(messages.embeds[0].fields[0].value).split('\n')[3]).split('')[String(String(messages.embeds[0].fields[0].value).split('\n')[3]).length - 1] - } - } - resolve() - } - } - }) + if (messages && messages.embeds.length < 1) { + messages.delete(); + messages = null; + } - stats.then(async () => { - const format = await time(new Date(Date.now() + client.config.refresh * 1000), 'R') - embed.setDescription(desc.replaceAll('{{time}}', format) + '\n**Nodes Stats [' + Math.floor(nodes.length - blacklist) + ']**' + text) - const EmbedFields = [] + if (client.config.message.content) { + content = client.config.message.content; + } - if (client.config.panel_settings.status) { - let stats = '**Status:** ' + String(panel.status).replace('true', client.config.status.online).replace('false', client.config.status.offline) + '\n\n' + if (client.config.message.attachment) { + files.push(new AttachmentBuilder(client.config.message.attachment)); + } + if (client.config.embed.title) { + embed.setTitle(client.config.embed.title); + } - if (client.config.panel_settings.users) stats = stats + 'Users: ' + String(panel.total_users).replace('-1', '`Unknown`') + '\n' - if (client.config.panel_settings.servers) stats = stats + 'Servers: ' + String(panel.total_servers).replace('-1', '`Unknown`') + if (client.config.embed.description) { + desc = client.config.embed.description + "\n"; + } - EmbedFields.push({ name: 'Panel Stats', value: stats }) - } + if (client.config.embed.color) { + embed.setColor(client.config.embed.color); + } - if (client.config.embed.field.title && client.config.embed.field.description) EmbedFields.push({ name: client.config.embed.field.title, value: client.config.embed.field.description.replaceAll('{{time}}', format) }) - if (client.config.embed.timestamp) embed.setTimestamp() - if (EmbedFields.length > 0) embed.addFields(EmbedFields) + if (client.config.embed.footer) { + embed.setFooter({ text: client.config.embed.footer }); + } - const row = [] + if (client.config.embed.thumbnail) { + embed.setThumbnail(client.config.embed.thumbnail); + } - if (client.config.button.enable) { - const button = new ActionRowBuilder - if (client.config.button.btn1.label.length !== 0 && client.config.button.btn1.url.length !== 0) { - button.addComponents( - new ButtonBuilder() - .setLabel(client.config.button.btn1.label) - .setStyle(ButtonStyle.Link) - .setURL(client.config.button.btn1.url) - ) - } - if (client.config.button.btn2.label.length !== 0 && client.config.button.btn2.url.length !== 0) { - button.addComponents( - new ButtonBuilder() - .setLabel(client.config.button.btn2.label) - .setStyle(ButtonStyle.Link) - .setURL(client.config.button.btn2.url) - ) - } - if (client.config.button.btn3.label.length !== 0 && client.config.button.btn3.url.length !== 0) { - button.addComponents( - new ButtonBuilder() - .setLabel(client.config.button.btn3.label) - .setStyle(ButtonStyle.Link) - .setURL(client.config.button.btn3.url) - ) - } - if (client.config.button.btn4.label.length !== 0 && client.config.button.btn4.url.length !== 0) { - button.addComponents( - new ButtonBuilder() - .setLabel(client.config.button.btn4.label) - .setStyle(ButtonStyle.Link) - .setURL(client.config.button.btn4.url) - ) - } - if (client.config.button.btn5.label.length !== 0 && client.config.button.btn5.url.length !== 0) { - button.addComponents( - new ButtonBuilder() - .setLabel(client.config.button.btn5.label) - .setStyle(ButtonStyle.Link) - .setURL(client.config.button.btn5.url) - ) - } - row.push(button) - } + if (client.config.embed.image) { + embed.setImage(client.config.embed.image); + } - if (!messages) channel.send({ content: content, embeds: [embed], components: row, files: files }) - else messages.edit({ content: content, embeds: [embed], components: row, files: files }) - console.log(chalk.cyan('[PteroStats] ') + chalk.green('Stats posted!')) - }) -} \ No newline at end of file + panel.total_users = panel.total_users.toLocaleString(); + panel.total_servers = panel.total_servers.toLocaleString(); + + if (nodes?.length >= 1) { + for (const data of nodes) { + if (!client.config.nodes_settings.blacklist.includes(data.id)) { + const title = + data?.name + + ": " + + String(data?.status) + .replace("true", client.config.status.online) + .replace("false", client.config.status.offline); + + let description = "```"; + + switch (client.config.nodes_settings.unit.toLowerCase()) { + case "tb": + description = + description + + "\nMemory : " + + memorySizeConverter(data.memory_min, "TB") + + " / " + + memorySizeConverter(data.memory_max, "TB") + + "\nDisk : " + + memorySizeConverter(data.disk_min, "TB") + + " / " + + memorySizeConverter(data.disk_max, "TB"); + break; + case "gb": + description = + description + + "\nMemory : " + + memorySizeConverter(data.memory_min, "GB") + + " / " + + memorySizeConverter(data.memory_max, "GB") + + "\nDisk : " + + memorySizeConverter(data.disk_min, "GB") + + " / " + + memorySizeConverter(data.disk_max, "GB"); + break; + case "percent": + description = + description + + "\nMemory : " + + percentageCalculator(data.memory_min, data.memory_max) + + "\nDisk : " + + percentageCalculator(data.disk_min, data.disk_max); + break; + default: + description = + description + + "\nMemory : " + + memorySizeConverter(data.memory_min, "MB") + + " / " + + memorySizeConverter(data.memory_max, "MB") + + "\nDisk : " + + memorySizeConverter(data.disk_min, "MB") + + " / " + + memorySizeConverter(data.disk_max, "MB"); + } + + if (client.config.nodes_settings.servers) { + description = + description + "\nServers : " + data.total_servers.toLocaleString(); + } + + if (client.config.nodes_settings.location) { + description = description + "\nLocation : " + data.location; + } + + if (client.config.nodes_settings.allocations) { + description = + description + + "\nAllocations : " + + data.allocations.toLocaleString(); + } + + description = description + "\n```"; + + if (client.config.nodes_settings.details) { + text = text + "\n**" + title.replace(":", ":**") + "\n" + description; + } else { + text = text + "\n**" + title.replace(":", ":**"); + } + } else { + blacklist = blacklist + 1; + if (nodes.length - client.config.nodes_settings.blacklist.length < 1) { + text = "\nThere is no nodes to display"; + } + } + } + + const format = time( + new Date(Date.now() + client.config.refresh * 1000 + BUFFER_MS), + "R" + ); + + embed.setDescription( + desc.replaceAll("{{time}}", format) + + "\n**Nodes Stats [" + + Math.floor(nodes.length - blacklist) + + "]**" + + text + ); + + const EmbedFields = []; + + if (client.config.panel_settings.status) { + let stats = + "**Status:** " + + String(panel.status) + .replace("true", client.config.status.online) + .replace("false", client.config.status.offline) + + "\n\n"; + + if (client.config.panel_settings.users) { + stats = + stats + + "Users: " + + String(panel.total_users).replace("-1", "`Unknown`") + + "\n"; + } + + if (client.config.panel_settings.servers) { + stats = + stats + + "Servers: " + + String(panel.total_servers).replace("-1", "`Unknown`"); + } + + EmbedFields.push({ name: "Panel Stats", value: stats }); + } + + if ( + client.config.embed.field.title && + client.config.embed.field.description + ) { + EmbedFields.push({ + name: client.config.embed.field.title, + value: client.config.embed.field.description.replaceAll( + "{{time}}", + format + ), + }); + } + + if (client.config.embed.timestamp) { + embed.setTimestamp(); + } + + if (EmbedFields.length > 0) { + embed.setFields(EmbedFields); //try it and see + } + + const row = []; + + if (client.config.button.enable) { + const button = new ActionRowBuilder(); + + if (client.config.button.btn1.label.length >= 1 && client.config.button.btn1.url.length >= 1) { + button.addComponents( + new ButtonBuilder() + .setLabel(client.config.button.btn1.label) + .setStyle(ButtonStyle.Link) + .setURL(client.config.button.btn1.url) + ); + } + + if (client.config.button.btn2.label.length >= 1 && client.config.button.btn2.url.length >= 1) { + button.addComponents( + new ButtonBuilder() + .setLabel(client.config.button.btn2.label) + .setStyle(ButtonStyle.Link) + .setURL(client.config.button.btn2.url) + ); + } + + if (client.config.button.btn3.label.length >= 1 && client.config.button.btn3.url.length >= 1) { + button.addComponents( + new ButtonBuilder() + .setLabel(client.config.button.btn3.label) + .setStyle(ButtonStyle.Link) + .setURL(client.config.button.btn3.url) + ); + } + + if (client.config.button.btn4.label.length >= 1 && client.config.button.btn4.url.length >= 1) { + button.addComponents( + new ButtonBuilder() + .setLabel(client.config.button.btn4.label) + .setStyle(ButtonStyle.Link) + .setURL(client.config.button.btn4.url) + ); + } + + if (client.config.button.btn5.label.length >= 1 && client.config.button.btn5.url.length >= 1) { + button.addComponents( + new ButtonBuilder() + .setLabel(client.config.button.btn5.label) + .setStyle(ButtonStyle.Link) + .setURL(client.config.button.btn5.url) + ); + } + + row.push(button); + } + + try { + if (!messages) { + channel.send({ + content: content, + embeds: [embed], + components: row, + files: files, + }); + } else { + messages.edit({ + content: content, + embeds: [embed], + components: row, + files: files, + }); + } + } catch (error) { + console.log(error); + } + + console.log(chalk.cyan("[PteroStats] ") + chalk.green("Stats posted!")); + } else { + if (!messages) { + text = "\nThere are no nodes to display."; + } else { + if ( + messages?.embeds?.length > 0 && + client.config.embed.title && + messages?.embeds[0]?.data?.title === client.config.embed.title + ) { + text = messages.embeds[0].description.replaceAll( + client.config.status.online, + client.config.status.offline + ); + + if ( + !panel?.status && + String( + String(messages?.embeds[0]?.fields[0]?.value)?.split("\n")[2] + ).split("")[ + String( + String(messages?.embeds[0]?.fields[0]?.value)?.split("\n")[2] + )?.length - 1 + ] !== "`" + ) { + panel.total_users = + String( + String(messages?.embeds[0]?.fields[0]?.value)?.split("\n")[2] + ).split("")[ + String( + String(messages?.embeds[0]?.fields[0]?.value)?.split("\n")[2] + )?.length - 1 + ] || 0; + panel.total_servers = + String( + String(messages?.embeds[0]?.fields[0]?.value)?.split("\n")[3] + )?.split("")[ + String( + String(messages?.embeds[0]?.fields[0]?.value)?.split("\n")[3] + )?.length - 1 + ] || 0; + } + } + } + } +}; diff --git a/index.js b/index.js index 82a7657..940587e 100644 --- a/index.js +++ b/index.js @@ -1,75 +1,52 @@ -const fs = require('fs'); -const child = require('child_process'); +const intigrityCheck = require("./modules/intigrityCheck"); -function InstallPackages() { - console.log('You didn\'t install the required node packages first!') - console.log('Please wait... starting to install all required node packages using child process') - console.log('If the bot can\'t install the package please install it manually') - try { - child.execSync('npm i') - console.log('Install complete!, please run "node index" command again!') - process.exit() - } catch (err) { - console.log('Error! ', err) - console.log('Support Server: https://discord.gg/zv6maQRah3') - process.exit() - } +if(!intigrityCheck()){ + return console.log("Intigrity check failed!"); } -if (Number(process.version.split('.')[0]) < 16) { - console.log('Invalid NodeJS Version!, Please use NodeJS 16.x or upper') - process.exit() -} -if (fs.existsSync('./node_modules')) { - if (fs.existsSync('./node_modules/discord.js')) { - const check = require('./node_modules/discord.js/package.json') - if (Number(check.version.split('.')[0]) !== 14) { - console.log('Invalid Discord.JS Version!, Please use Discord.JS 14.x') - process.exit() - } - } else InstallPackages() - if (fs.existsSync('./node_modules/axios')) { - const check = require('./node_modules/axios/package.json') - if (Number(check.version.split('.')[1]) > 1) { - console.log('Invalid Axios Version!, Please use Axios 1.1.3') - process.exit() - } - } else InstallPackages() - if (fs.existsSync('./node_modules/chalk')) { - const check = require('./node_modules/chalk/package.json') - if (Number(check.version.split('.')[0]) > 4) { - console.log('Invalid Chalk Version!, Please use Chalk 4.1.2') - process.exit() - } - } else InstallPackages() - if (!fs.existsSync('./node_modules/js-yaml')) InstallPackages() -} else InstallPackages() - -const chalk = require('chalk'); -const yaml = require('js-yaml'); -const { Client, GatewayIntentBits } = require('discord.js'); +const fs = require("node:fs"); +const chalk = require("chalk"); +const yaml = require("js-yaml"); +const { Client, GatewayIntentBits } = require("discord.js"); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); -client.config = yaml.load(fs.readFileSync('./config.yml', 'utf8')); +client.config = yaml.load(fs.readFileSync("./config.yml", "utf8")); -if (client.config.panel.adminkey || client.config.resource || client.config.message.image) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('You are using old config file, please update your config file at ') + chalk.green('https://github.com/HirziDevs/PteroStats/blob/main/config.yml')) - process.exit() -} -if (client.config.token.startsWith('Put') || !client.config.token.length) { - console.log(chalk.cyan('[PteroStats] ') + chalk.red('Error! Invalid Discord Bot Token')) - process.exit() +if ( + client.config.panel.adminkey || + client.config.resource || + client.config.message.image +) { + console.log( + chalk.cyan("[PteroStats] ") + + chalk.red( + "You are using old config file, please update your config file at " + ) + + chalk.green( + "https://github.com/HirziDevs/PteroStats/blob/main/config.yml" + ) + ); + process.exit(); } -const eventFiles = fs.readdirSync('./events').filter(file => file.endsWith('.js')); +if (client.config.token.startsWith("Put") || !client.config.token.length) { + console.log( + chalk.cyan("[PteroStats] ") + chalk.red("Error! Invalid Discord Bot Token") + ); + process.exit(); +} + +const eventFiles = fs + .readdirSync("./events") + .filter((file) => file.endsWith(".js")); for (const file of eventFiles) { - const event = require(`./events/${file}`); - if (event.once) { - client.once(event.name, (...args) => event.execute(...args)); - } else { - client.on(event.name, (...args) => event.execute(...args)); - } + const event = require(`./events/${file}`); + if (event.once) { + client.once(event.name, (...args) => event.execute(...args)); + } else { + client.on(event.name, (...args) => event.execute(...args)); + } } -client.login(client.config.token); \ No newline at end of file +client.login(client.config.token); diff --git a/modules/intigrityCheck.js b/modules/intigrityCheck.js new file mode 100644 index 0000000..0bd261e --- /dev/null +++ b/modules/intigrityCheck.js @@ -0,0 +1,127 @@ +const fs = require("node:fs"); +const child = require("node:child_process"); +const path = require("node:path"); + +const REQUIRED_PACKAGES = [ + { + name: "axios", + version: "1.4.0", + }, + { + name: "axios-retry", + version: "3.5.1", + }, + { + name: "chalk", + version: "4.1.2", + }, + { + name: "discord.js", + version: "14.11.0", + }, + { + name: "js-yaml", + version: "4.1.0", + }, +]; +const NODE_VERSION = 16; + +function InstallPackages() { + console.log("Required nodejs packages not found!"); + console.log("Please wait... starting to install all required node packages."); + console.log( + "If the bot can't install the packages please install them manually." + ); + + try { + let packagesList = ""; + + for (const package of REQUIRED_PACKAGES) { + packagesList += ` ${package.name}@${package.version}`; + } + + child.execSync(`npm i${packagesList}`); + console.log('Install complete!, please run "node index" command again!'); + + process.exit(); + } catch (err) { + console.log("Error! ", err); + console.log("Support Server: https://discord.gg/zv6maQRah3"); + + process.exit(); + } +} + +module.exports = () => { + if (Number(process.version.split(".")[0]) < NODE_VERSION) { + console.log( + `Unsupported NodeJS Version!, Please use NodeJS ${NODE_VERSION}.x or higher.` + ); + + process.exit(); + } + + const nodeModulesFolderPath = path.join(__dirname, "../", "node_modules"); + + if (fs.existsSync(nodeModulesFolderPath)) { + let success = false; + let errorMessage = ""; + + for (const package of REQUIRED_PACKAGES) { + const packageFilePath = path.join( + __dirname, + "../", + "node_modules", + package.name, + "package.json" + ); + + if (fs.existsSync(packageFilePath)) { + let packageFile = fs.readFileSync(packageFilePath, 'utf-8'); + + if (packageFile) { + packageFile = JSON.parse(packageFile); + + if ( + Number(packageFile.version.split(".")[1]) !== + Number(package.version.split(".")[1]) + ) { + console.log( + `Unsupported "${package.name}" version!.\nPlease delete your "node_modules" and "package-lock.json".\nAnd restart the bot.` + ); + + process.exit(); + } else { + success = true; + + continue; + } + } else { + success = false; + + errorMessage = `Unknown package version- "${package.name}".`; + + break; + } + } else { + success = false; + + errorMessage = `Missing package- "${package.name}".`; + + break; + } + } + + if (!success) { + if (errorMessage) { + console.log(errorMessage); + } + + InstallPackages(); + } + } else { + InstallPackages(); + } + + return true; +}; diff --git a/modules/memorySizeConverter.js b/modules/memorySizeConverter.js new file mode 100644 index 0000000..22c6fc8 --- /dev/null +++ b/modules/memorySizeConverter.js @@ -0,0 +1,44 @@ +const SUPPORTED_TYPES = ["MB", "GB", "TB"]; + +module.exports = (value, type) => { + if (value && type) { + value = parseInt(value); + + if (value > 0) { + if (SUPPORTED_TYPES.includes(type)) { + let result = ""; + + switch (type) { + case "MB": + result = + value.toFixed(2).toLocaleString().replace(".00", "") + " MB"; + break; + case "GB": + result = + (value / 1024).toFixed(2).toLocaleString().replace(".00", "") + + " GB"; + break; + case "TB": + result = + (value / (1024 * 1000)) + .toFixed(2) + .toLocaleString() + .replace(".00", "") + " TB"; + break; + default: + result = + value.toFixed(2).toLocaleString().replace(".00", "") + " MB"; + break; + } + + return result; + } else { + return "INVALID TYPE"; + } + } else { + return "INVALID VALUE"; + } + } else { + return "ERROR"; + } +}; diff --git a/modules/percentageCalculator.js b/modules/percentageCalculator.js new file mode 100644 index 0000000..7fa9462 --- /dev/null +++ b/modules/percentageCalculator.js @@ -0,0 +1,16 @@ +module.exports = (used, total) => { + if (used && total) { + used = parseInt(used); + total = parseInt(total); + + if (used >= 1 && total >= 1) { + let percentage = ((used / total) * 100).toFixed(2).toLocaleString().replace(".00", "") + " %"; + + return percentage; + } else { + return "ERROR"; + } + } else { + return "ERROR"; + } +}; diff --git a/package.json b/package.json index 9a00948..e98022d 100644 --- a/package.json +++ b/package.json @@ -13,12 +13,13 @@ "start": "node index.js" }, "dependencies": { - "axios": "1.1.3", - "chalk": "4.1.2", - "discord.js": "^14.7.1", + "axios": "^1.4.0", + "axios-retry": "^3.5.1", + "chalk": "^4.1.2", + "discord.js": "^14.11.0", "js-yaml": "^4.1.0" }, "engines": { "node": ">=16.9.0" } -} \ No newline at end of file +} From 1842dc3cb3d5a5be3a08a893158035f05cede768 Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Tue, 11 Jul 2023 19:22:50 +0530 Subject: [PATCH 13/32] Update ready.js --- events/ready.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/events/ready.js b/events/ready.js index 1a5a0ed..80091d2 100644 --- a/events/ready.js +++ b/events/ready.js @@ -24,11 +24,13 @@ module.exports = { ) ); - if (client.guilds.cache.size < 1) + if (client.guilds.cache.size < 1) { return console.log( chalk.cyan("[PteroStats] ") + chalk.red("Error! This bot is not on any discord servers") ); + } + if (client.config.timeout < 1) { console.log( chalk.cyan("[PteroStats] ") + @@ -37,12 +39,12 @@ module.exports = { client.config.timeout = 1; } - if (client.config.refresh > 1 && client.config.refresh < 10) + if (client.config.refresh >= 1 && client.config.refresh <= 10) { console.log( chalk.cyan("[PteroStats] ") + chalk.red("Refresh Time below 10 seconds is not recommended!") ); - else if (client.config.refresh < 1) { + } else if (client.config.refresh < 1) { console.log( chalk.cyan("[PteroStats] ") + chalk.red("Refresh Time cannot be less than 1 seconds!") From d4b741b9c167ff68b00be1bc4d7eabf40f59d572 Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Tue, 11 Jul 2023 19:52:50 +0530 Subject: [PATCH 14/32] Update postStatus.js --- handlers/postStatus.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handlers/postStatus.js b/handlers/postStatus.js index d07cbc7..8a8cd62 100644 --- a/handlers/postStatus.js +++ b/handlers/postStatus.js @@ -177,7 +177,7 @@ module.exports = async ({ client, panel, nodes }) => { } else { blacklist = blacklist + 1; if (nodes.length - client.config.nodes_settings.blacklist.length < 1) { - text = "\nThere is no nodes to display"; + text = "\nThere are no nodes to display"; } } } From d38ec4463846e82817f2201edcafae3ecfe5665d Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Tue, 11 Jul 2023 19:55:41 +0530 Subject: [PATCH 15/32] Update checkStatus.js --- handlers/checkStatus.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handlers/checkStatus.js b/handlers/checkStatus.js index e5a2002..bc7c3eb 100644 --- a/handlers/checkStatus.js +++ b/handlers/checkStatus.js @@ -10,7 +10,7 @@ axiosRetry(axios, { retries: 5 }); module.exports = async ({ client }) => { function Embed({ node }) { return new EmbedBuilder() - .setTitle("Node Logging") //if you wanted to change this please change at line 175 too + .setTitle("Node Logging") //if you wanted to change this please change at line 244 too .setDescription("`" + node.name + "` is down!") .setFooter({ text: "Please see console for more details" }) .setTimestamp() From 1659032c2160a90781c66e2094467c84830864dc Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Tue, 11 Jul 2023 20:26:36 +0530 Subject: [PATCH 16/32] updates --- handlers/postStatus.js | 57 +++++++++++++------------------ modules/intigrityCheck.js | 2 +- modules/memorySizeConverter.js | 61 +++++++++++++++++----------------- 3 files changed, 56 insertions(+), 64 deletions(-) diff --git a/handlers/postStatus.js b/handlers/postStatus.js index 8a8cd62..aabb07d 100644 --- a/handlers/postStatus.js +++ b/handlers/postStatus.js @@ -106,30 +106,6 @@ module.exports = async ({ client, panel, nodes }) => { let description = "```"; switch (client.config.nodes_settings.unit.toLowerCase()) { - case "tb": - description = - description + - "\nMemory : " + - memorySizeConverter(data.memory_min, "TB") + - " / " + - memorySizeConverter(data.memory_max, "TB") + - "\nDisk : " + - memorySizeConverter(data.disk_min, "TB") + - " / " + - memorySizeConverter(data.disk_max, "TB"); - break; - case "gb": - description = - description + - "\nMemory : " + - memorySizeConverter(data.memory_min, "GB") + - " / " + - memorySizeConverter(data.memory_max, "GB") + - "\nDisk : " + - memorySizeConverter(data.disk_min, "GB") + - " / " + - memorySizeConverter(data.disk_max, "GB"); - break; case "percent": description = description + @@ -142,13 +118,13 @@ module.exports = async ({ client, panel, nodes }) => { description = description + "\nMemory : " + - memorySizeConverter(data.memory_min, "MB") + + memorySizeConverter(data.memory_min, type) + " / " + - memorySizeConverter(data.memory_max, "MB") + + memorySizeConverter(data.memory_max, type) + "\nDisk : " + - memorySizeConverter(data.disk_min, "MB") + + memorySizeConverter(data.disk_min, type) + " / " + - memorySizeConverter(data.disk_max, "MB"); + memorySizeConverter(data.disk_max, type); } if (client.config.nodes_settings.servers) { @@ -249,7 +225,10 @@ module.exports = async ({ client, panel, nodes }) => { if (client.config.button.enable) { const button = new ActionRowBuilder(); - if (client.config.button.btn1.label.length >= 1 && client.config.button.btn1.url.length >= 1) { + if ( + client.config.button.btn1.label.length >= 1 && + client.config.button.btn1.url.length >= 1 + ) { button.addComponents( new ButtonBuilder() .setLabel(client.config.button.btn1.label) @@ -258,7 +237,10 @@ module.exports = async ({ client, panel, nodes }) => { ); } - if (client.config.button.btn2.label.length >= 1 && client.config.button.btn2.url.length >= 1) { + if ( + client.config.button.btn2.label.length >= 1 && + client.config.button.btn2.url.length >= 1 + ) { button.addComponents( new ButtonBuilder() .setLabel(client.config.button.btn2.label) @@ -267,7 +249,10 @@ module.exports = async ({ client, panel, nodes }) => { ); } - if (client.config.button.btn3.label.length >= 1 && client.config.button.btn3.url.length >= 1) { + if ( + client.config.button.btn3.label.length >= 1 && + client.config.button.btn3.url.length >= 1 + ) { button.addComponents( new ButtonBuilder() .setLabel(client.config.button.btn3.label) @@ -276,7 +261,10 @@ module.exports = async ({ client, panel, nodes }) => { ); } - if (client.config.button.btn4.label.length >= 1 && client.config.button.btn4.url.length >= 1) { + if ( + client.config.button.btn4.label.length >= 1 && + client.config.button.btn4.url.length >= 1 + ) { button.addComponents( new ButtonBuilder() .setLabel(client.config.button.btn4.label) @@ -285,7 +273,10 @@ module.exports = async ({ client, panel, nodes }) => { ); } - if (client.config.button.btn5.label.length >= 1 && client.config.button.btn5.url.length >= 1) { + if ( + client.config.button.btn5.label.length >= 1 && + client.config.button.btn5.url.length >= 1 + ) { button.addComponents( new ButtonBuilder() .setLabel(client.config.button.btn5.label) diff --git a/modules/intigrityCheck.js b/modules/intigrityCheck.js index 0bd261e..c9e599a 100644 --- a/modules/intigrityCheck.js +++ b/modules/intigrityCheck.js @@ -99,7 +99,7 @@ module.exports = () => { } else { success = false; - errorMessage = `Unknown package version- "${package.name}".`; + errorMessage = `Unknown package version- "${package.name}@${package.version}".`; break; } diff --git a/modules/memorySizeConverter.js b/modules/memorySizeConverter.js index 22c6fc8..1584af2 100644 --- a/modules/memorySizeConverter.js +++ b/modules/memorySizeConverter.js @@ -1,40 +1,41 @@ -const SUPPORTED_TYPES = ["MB", "GB", "TB"]; +const SUPPORTED_TYPES = ["mb", "gb", "tb"]; module.exports = (value, type) => { - if (value && type) { + if (value) { value = parseInt(value); if (value > 0) { - if (SUPPORTED_TYPES.includes(type)) { - let result = ""; - - switch (type) { - case "MB": - result = - value.toFixed(2).toLocaleString().replace(".00", "") + " MB"; - break; - case "GB": - result = - (value / 1024).toFixed(2).toLocaleString().replace(".00", "") + - " GB"; - break; - case "TB": - result = - (value / (1024 * 1000)) - .toFixed(2) - .toLocaleString() - .replace(".00", "") + " TB"; - break; - default: - result = - value.toFixed(2).toLocaleString().replace(".00", "") + " MB"; - break; - } - - return result; + if (!type) { + type = "mb"; } else { - return "INVALID TYPE"; + type = type.toLowerCase(); + + if (!SUPPORTED_TYPES.includes(type)) { + type = "mb"; + } } + + let result = ""; + + switch (type) { + case "mb": + result = value.toFixed(2).toLocaleString().replace(".00", "") + " MB"; + break; + case "gb": + result = + (value / 1024).toFixed(2).toLocaleString().replace(".00", "") + + " GB"; + break; + case "tb": + result = + (value / (1024 * 1000)) + .toFixed(2) + .toLocaleString() + .replace(".00", "") + " TB"; + break; + } + + return result; } else { return "INVALID VALUE"; } From 064acca7231d1eed46f0bad2181a208a5ed53ce1 Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Tue, 11 Jul 2023 20:32:40 +0530 Subject: [PATCH 17/32] fixes --- PteroStats.zip | Bin 0 -> 9279 bytes handlers/postStatus.js | 8 ++++---- modules/memorySizeConverter.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 PteroStats.zip diff --git a/PteroStats.zip b/PteroStats.zip new file mode 100644 index 0000000000000000000000000000000000000000..0e8636a5d616abd924a74dea16f87f012ec6c575 GIT binary patch literal 9279 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 fV47k4?3XA0 { description = description + "\nMemory : " + - memorySizeConverter(data.memory_min, type) + + memorySizeConverter(data.memory_min, client.config.nodes_settings.unit.toLowerCase()) + " / " + - memorySizeConverter(data.memory_max, type) + + memorySizeConverter(data.memory_max, client.config.nodes_settings.unit.toLowerCase()) + "\nDisk : " + - memorySizeConverter(data.disk_min, type) + + memorySizeConverter(data.disk_min, client.config.nodes_settings.unit.toLowerCase()) + " / " + - memorySizeConverter(data.disk_max, type); + memorySizeConverter(data.disk_max, client.config.nodes_settings.unit.toLowerCase()); } if (client.config.nodes_settings.servers) { diff --git a/modules/memorySizeConverter.js b/modules/memorySizeConverter.js index 1584af2..17d7f6f 100644 --- a/modules/memorySizeConverter.js +++ b/modules/memorySizeConverter.js @@ -8,13 +8,13 @@ module.exports = (value, type) => { if (!type) { type = "mb"; } else { - type = type.toLowerCase(); + type = type?.toLowerCase() || "mb"; if (!SUPPORTED_TYPES.includes(type)) { type = "mb"; } } - + let result = ""; switch (type) { From cd7b1ad06a6f85e67186cbc26fcf171d62a10fba Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Tue, 11 Jul 2023 20:55:27 +0530 Subject: [PATCH 18/32] Update config.yml --- config.yml | 100 ++++++++++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/config.yml b/config.yml index 671a8f4..bdbff1b 100644 --- a/config.yml +++ b/config.yml @@ -2,86 +2,86 @@ # If you need help, join our discord server here: https://discord.gg/zv6maQRah3 # Bot Configuration -token: 'Put bot token here' +token: "Put bot token here" presence: - text: 'Hosting Panel' - type: 'watching' # can be 'watching', 'playing', 'listening', or 'competing'. for 'streaming' is not working for now - status: 'online' # can be 'online', 'idle', 'dnd', or 'invisible' + text: "Hosting Panel" + type: "watching" # can be 'watching', 'playing', 'listening', or 'competing'. for 'streaming' is not working for now + status: "online" # can be 'online', 'idle', 'dnd', or 'invisible' # Discord Channel and Refresh Time Configuration -channel: 'Put channel id here' +channel: "Put channel id here" refresh: 60 # How much time the bot will refresh the stats timeout: 1 # How much time to wait some node to respond to the bot (if you change this, it will add more time to refresh the stats) # Panel Configuration panel: - url: 'Put panel url here' - key: 'Put panel apikey here' + url: "Put panel url here" + key: "Put panel apikey here" # Message and Embed Configuration # leave '' if you want to disable option message: - content: '' - attachment: '' # If you enable attachment on message it upload the attachment first before sending or editing message and it will delay the stats + content: "" + attachment: "" # If you enable attachment on message it upload the attachment first before sending or editing message and it will delay the stats embed: - title: 'PteroStats' - color: '5865F2' - description: 'Next update {{time}}' # You can use {{time}} to make "in X seconds" time format - footer: 'By Hirzi#8701' - timestamp: true - thumbnail: '' - image: '' - field: - title: '' - description: '' # You can use {{time}} to make "in X seconds" time format + title: "PteroStats" + color: "5865F2" + description: "Next update {{time}}" # You can use {{time}} to make "in X seconds" time format + footer: "By Hirzi#8701" + timestamp: true + thumbnail: "" + image: "" + field: + title: "" + description: "" # You can use {{time}} to make "in X seconds" time format # Message Button Configuration button: - enable: true - btn1: - label: 'PteroStats' - url: 'https://github.com/HirziDevs/PteroStats' - btn2: - label: '' - url: '' - btn3: - label: '' - url: '' - btn4: - label: '' - url: '' - btn5: - label: '' - url: '' + enable: true + btn1: + label: "PteroStats" + url: "https://github.com/HirziDevs/PteroStats" + btn2: + label: "" + url: "" + btn3: + label: "" + url: "" + btn4: + label: "" + url: "" + btn5: + label: "" + url: "" # Status Message Configuration # How to use custom emoji: https://github.com/HirziDevs/PteroStats#using-custom-emoji status: - online: ':green_circle: Online' - offline: ':red_circle: Offline' + online: ":green_circle: Online" + offline: ":red_circle: Offline" # Nodes Settings # How to get nodes id: https://github.com/HirziDevs/PteroStats#blacklist-nodes nodes_settings: - blacklist: [] # You can add node id to remove the node from status embed (Example: "blacklist: [1]") - details: false # enable nodes details like memory and disk - servers: true - location: true - allocations: true - unit: 'gb' # You can use "gb", "mb", "tb", or "percent" + blacklist: [] # You can add node id to remove the node from status embed (Example: "blacklist: [1]") + details: false # enable nodes details like memory and disk + servers: true + location: true + allocations: true + unit: "gb" # You can use "gb", "mb", "tb", or "percent" # Panel Users and Servers Settings panel_settings: - status: true # enable panel stats under nodes stats - servers: true - users: true + status: true # enable panel stats under nodes stats + servers: true + users: true # Mentions a User or Role if some nodes are offline (this feature is still in testing, please report if you have a problem) mentions: # to enable atleast put 1 ID on user or role bellow - user: [] # Put User ID here (Example: "user: ['548867757517570058', '816219634390663230']") - role: [] # Put Role ID here (Example: "role: ['796083838236622858', '858198863973187585']") - channel: '' # Put Channel ID here for the logging + user: [] # Put User ID here (Example: "user: ['548867757517570058', '816219634390663230']") + role: [] # Put Role ID here (Example: "role: ['796083838236622858', '858198863973187585']") + channel: "" # Put Channel ID here for the logging # Log error to console if server offline (enable this if you have a problem that you wanted to report) -log_error: false # set to "true" to enable \ No newline at end of file +log_error: false # set to "true" to enable From cb27e96aeb143925793606015c08951243a21d58 Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Tue, 11 Jul 2023 21:00:12 +0530 Subject: [PATCH 19/32] Update config.yml --- config.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/config.yml b/config.yml index bdbff1b..a4e6a9b 100644 --- a/config.yml +++ b/config.yml @@ -5,13 +5,13 @@ token: "Put bot token here" presence: text: "Hosting Panel" - type: "watching" # can be 'watching', 'playing', 'listening', or 'competing'. for 'streaming' is not working for now + type: "watching" # can be 'watching', 'playing', 'listening', or 'competing'. 'streaming' is not working for now status: "online" # can be 'online', 'idle', 'dnd', or 'invisible' # Discord Channel and Refresh Time Configuration channel: "Put channel id here" refresh: 60 # How much time the bot will refresh the stats -timeout: 1 # How much time to wait some node to respond to the bot (if you change this, it will add more time to refresh the stats) +timeout: 1 # How much time to wait for a node to respond to the bot (if you change this, it will add more time to refresh the stats) # Panel Configuration panel: @@ -19,10 +19,10 @@ panel: key: "Put panel apikey here" # Message and Embed Configuration -# leave '' if you want to disable option +# set the option as '' if you want to disable it message: content: "" - attachment: "" # If you enable attachment on message it upload the attachment first before sending or editing message and it will delay the stats + attachment: "" # If you enable attachment on message it will upload the attachment first before sending or editing message and will result in delayed stats embed: title: "PteroStats" @@ -65,11 +65,11 @@ status: # How to get nodes id: https://github.com/HirziDevs/PteroStats#blacklist-nodes nodes_settings: blacklist: [] # You can add node id to remove the node from status embed (Example: "blacklist: [1]") - details: false # enable nodes details like memory and disk + details: false # enable nodes details i.e memory and disk usage servers: true location: true allocations: true - unit: "gb" # You can use "gb", "mb", "tb", or "percent" + unit: "gb" # Allowed values- "gb", "mb", "tb", or "percent" # Panel Users and Servers Settings panel_settings: @@ -77,11 +77,11 @@ panel_settings: servers: true users: true -# Mentions a User or Role if some nodes are offline (this feature is still in testing, please report if you have a problem) +# Mentions a User or Role if any node is offline (this feature is still in testing, please report if you have a problem) mentions: # to enable atleast put 1 ID on user or role bellow user: [] # Put User ID here (Example: "user: ['548867757517570058', '816219634390663230']") role: [] # Put Role ID here (Example: "role: ['796083838236622858', '858198863973187585']") channel: "" # Put Channel ID here for the logging -# Log error to console if server offline (enable this if you have a problem that you wanted to report) +# Log error to console if a server offline (enable this when you have a problem that you want to report) log_error: false # set to "true" to enable From dd3227e9967e5e31c4dac21d965913ca74aa96e0 Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Tue, 11 Jul 2023 21:11:28 +0530 Subject: [PATCH 20/32] Update checkStatus.js --- handlers/checkStatus.js | 53 ++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/handlers/checkStatus.js b/handlers/checkStatus.js index bc7c3eb..f2e3f60 100644 --- a/handlers/checkStatus.js +++ b/handlers/checkStatus.js @@ -21,16 +21,19 @@ module.exports = async ({ client }) => { console.log( chalk.cyan("[PteroStats] ") + chalk.red("Error! Invalid Channel ID") ); + process.exit(); } else if (client.config.panel.url.startsWith("Put")) { console.log( chalk.cyan("[PteroStats] ") + chalk.red("Error! Invalid Panel URL") ); + process.exit(); } else if (client.config.panel.key.startsWith("Put")) { console.log( chalk.cyan("[PteroStats] ") + chalk.red("Error! Invalid Apikey") ); + process.exit(); } else if (!client.config.panel.url.startsWith("http")) { console.log( @@ -42,11 +45,13 @@ module.exports = async ({ client }) => { '1. Make sure the panel url is starts with "https://" or "http://"' ) ); + process.exit(); } - if (client.config.panel.url.endsWith("/")) + if (client.config.panel.url.endsWith("/")) { client.config.panel.url = client.config.panel.url.slice(0, -1); + } const nodes = []; const embeds = []; @@ -174,8 +179,6 @@ module.exports = async ({ client }) => { embeds.push(Embed({ node: body })); body.status = false; - - return statsResolve(); } }, client.config.timeout * 1000); } catch (error) { @@ -185,6 +188,7 @@ module.exports = async ({ client }) => { chalk.yellow("[Node: " + node.attributes.name + "] ") + chalk.red(error) ); + embeds.push(Embed({ node: body })); body.status = false; @@ -209,9 +213,9 @@ module.exports = async ({ client }) => { await postStatus({ client: client, panel: panel, nodes: nodes }); if ( - client.config.mentions.user.length > 0 || - (client.config.mentions.role.length > 0 && - client.config.mentions.channel) + (client.config.mentions.user.length > 0 || + client.config.mentions.role.length > 0) && + client.config.mentions.channel ) { if ( Array.isArray(client.config.mentions.user) || @@ -219,20 +223,22 @@ module.exports = async ({ client }) => { ) { let mentions = ""; - await client.config.mentions.user.forEach((user) => { + for (const user of client.config.mentions.user) { if (!isNaN(Number(user))) { - mentions = mentions + " <@" + user + ">"; + mentions += " <@" + user + ">"; } - }); - await client.config.mentions.role.forEach((role) => { + } + + for (const role of client.config.mentions.role) { if (!isNaN(Number(role))) { - mentions = mentions + " <@&" + role + ">"; + mentions += " <@&" + role + ">"; } - }); + } const channel = await client.channels.cache.get( client.config.mentions.channel ); + if (channel) { const messages = await channel.messages .fetch({ limit: 10 }) @@ -245,22 +251,27 @@ module.exports = async ({ client }) => { ) .first() ); + if (messages) - messages.embeds.forEach((MsgEmbed) => { + for (const MsgEmbed of messages.embeds) { for (const embed of embeds) { - if (MsgEmbed.data.description === embed.data.description) + if ( + MsgEmbed.data.description === embed.data.description + ) { embeds.splice(i, 1); - nodes.forEach((node) => { + } + for (const node of nodes) { if ( MsgEmbed.data.description.startsWith( "`" + node.name ) && - node.status === true - ) + node.status + ) { messages.delete(); - }); + } + } } - }); + } if (embeds.length > 0) channel.send({ content: mentions, embeds: embeds }); } @@ -332,9 +343,7 @@ module.exports = async ({ client }) => { ) ); } else { - console.log( - chalk.cyan("[PteroStats] ") + chalk.red("Error! " + error) - ); + console.log(chalk.cyan("[PteroStats] ") + chalk.red("Error! " + error)); } } else { console.log(chalk.cyan("[PteroStats] ") + chalk.red("Error! " + error)); From 7b2c3cb7a42e3d37660ee69db88dac0ddaf2d930 Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Tue, 11 Jul 2023 21:16:04 +0530 Subject: [PATCH 21/32] Update checkStatus.js --- handlers/checkStatus.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/handlers/checkStatus.js b/handlers/checkStatus.js index f2e3f60..073a36c 100644 --- a/handlers/checkStatus.js +++ b/handlers/checkStatus.js @@ -252,14 +252,15 @@ module.exports = async ({ client }) => { .first() ); - if (messages) + if (messages) { for (const MsgEmbed of messages.embeds) { for (const embed of embeds) { if ( MsgEmbed.data.description === embed.data.description ) { - embeds.splice(i, 1); + embeds.splice(i, 1);//This code is wrong i is not defined } + for (const node of nodes) { if ( MsgEmbed.data.description.startsWith( @@ -272,8 +273,11 @@ module.exports = async ({ client }) => { } } } - if (embeds.length > 0) + } + + if (embeds.length > 0) { channel.send({ content: mentions, embeds: embeds }); + } } } } From d4ab92b26ecaa1081548c45e55b168e5cb16c6aa Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Tue, 11 Jul 2023 21:25:25 +0530 Subject: [PATCH 22/32] Update checkStatus.js --- handlers/checkStatus.js | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/handlers/checkStatus.js b/handlers/checkStatus.js index 073a36c..98a6d85 100644 --- a/handlers/checkStatus.js +++ b/handlers/checkStatus.js @@ -7,10 +7,13 @@ const postStatus = require("./postStatus"); axiosRetry(axios, { retries: 5 }); +const EMBED_TITLE = "Node Loggin"; +const MENTION_DELETE_TIMEOUT = 1; + module.exports = async ({ client }) => { function Embed({ node }) { return new EmbedBuilder() - .setTitle("Node Logging") //if you wanted to change this please change at line 244 too + .setTitle(EMBED_TITLE) //if you wanted to change this please change at line 244 too .setDescription("`" + node.name + "` is down!") .setFooter({ text: "Please see console for more details" }) .setTimestamp() @@ -247,18 +250,18 @@ module.exports = async ({ client }) => { .filter( (m) => m.author.id === client.user.id && - m.embeds[0].data.title === "Node Logging" + m.embeds[0].data.title === EMBED_TITLE ) .first() ); if (messages) { for (const MsgEmbed of messages.embeds) { - for (const embed of embeds) { + for (const [index, embed] of embeds.entries()) { if ( MsgEmbed.data.description === embed.data.description ) { - embeds.splice(i, 1);//This code is wrong i is not defined + embeds.splice(index, 1); } for (const node of nodes) { @@ -268,7 +271,7 @@ module.exports = async ({ client }) => { ) && node.status ) { - messages.delete(); + await messages.delete(); } } } @@ -276,8 +279,16 @@ module.exports = async ({ client }) => { } if (embeds.length > 0) { - channel.send({ content: mentions, embeds: embeds }); + await channel.send({ embeds: embeds }); } + + await channel.send({ content: mentions }).then(async (msg) => { + setTimeout(async () => { + if (msg) { + await msg.delete(); + } + }, MENTION_DELETE_TIMEOUT * 1000); + }); } } } From 6d637038cd07ac76234d29a323d650f102849ec1 Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Fri, 14 Jul 2023 21:27:18 +0530 Subject: [PATCH 23/32] Delete PteroStats.zip --- PteroStats.zip | Bin 9279 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 PteroStats.zip diff --git a/PteroStats.zip b/PteroStats.zip deleted file mode 100644 index 0e8636a5d616abd924a74dea16f87f012ec6c575..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9279 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 fV47k4?3XA0 Date: Fri, 14 Jul 2023 21:53:12 +0530 Subject: [PATCH 24/32] Update intigrityCheck.js --- modules/intigrityCheck.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/intigrityCheck.js b/modules/intigrityCheck.js index c9e599a..c838920 100644 --- a/modules/intigrityCheck.js +++ b/modules/intigrityCheck.js @@ -87,7 +87,7 @@ module.exports = () => { Number(package.version.split(".")[1]) ) { console.log( - `Unsupported "${package.name}" version!.\nPlease delete your "node_modules" and "package-lock.json".\nAnd restart the bot.` + `Unsupported "${package.name}" version!.\nPlease delete your "node_modules" and "package-lock.json".\nAnd restart the bot.\nPlease make sure to check and remove "npm install" command from your startup params.` ); process.exit(); From 725641a03405256c99350ae03004376e659945cc Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Fri, 14 Jul 2023 22:28:06 +0530 Subject: [PATCH 25/32] Update intigrityCheck.js --- modules/intigrityCheck.js | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/modules/intigrityCheck.js b/modules/intigrityCheck.js index c838920..75f7c02 100644 --- a/modules/intigrityCheck.js +++ b/modules/intigrityCheck.js @@ -29,18 +29,26 @@ const NODE_VERSION = 16; function InstallPackages() { console.log("Required nodejs packages not found!"); console.log("Please wait... starting to install all required node packages."); + + let packagesList = ""; + for (const package of REQUIRED_PACKAGES) { + packagesList += `\n- ${package.name}@${package.version}`; + } + + console.log("The following packages will be installed:", packagesList); + console.log( - "If the bot can't install the packages please install them manually." + "If the bot can't install the packages, please install them manually." ); try { - let packagesList = ""; + packagesList = ""; for (const package of REQUIRED_PACKAGES) { packagesList += ` ${package.name}@${package.version}`; } - child.execSync(`npm i${packagesList}`); + child.execSync(`npm i --force${packagesList}`); console.log('Install complete!, please run "node index" command again!'); process.exit(); @@ -77,20 +85,15 @@ module.exports = () => { ); if (fs.existsSync(packageFilePath)) { - let packageFile = fs.readFileSync(packageFilePath, 'utf-8'); + let packageFile = fs.readFileSync(packageFilePath, "utf-8"); if (packageFile) { packageFile = JSON.parse(packageFile); - if ( - Number(packageFile.version.split(".")[1]) !== - Number(package.version.split(".")[1]) - ) { - console.log( - `Unsupported "${package.name}" version!.\nPlease delete your "node_modules" and "package-lock.json".\nAnd restart the bot.\nPlease make sure to check and remove "npm install" command from your startup params.` - ); + if (packageFile.version !== package.version) { + errorMessage = `Unsupported "${package.name}" version!.\nStarting to install the supported version...`; - process.exit(); + break; } else { success = true; @@ -99,7 +102,7 @@ module.exports = () => { } else { success = false; - errorMessage = `Unknown package version- "${package.name}@${package.version}".`; + errorMessage = `Unknown package version- "${package.name}".`; break; } From 5bea4895371d12662ad3e62454a65febba5109df Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Fri, 14 Jul 2023 22:29:45 +0530 Subject: [PATCH 26/32] Update intigrityCheck.js --- modules/intigrityCheck.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/intigrityCheck.js b/modules/intigrityCheck.js index 75f7c02..a1b33b2 100644 --- a/modules/intigrityCheck.js +++ b/modules/intigrityCheck.js @@ -31,10 +31,9 @@ function InstallPackages() { console.log("Please wait... starting to install all required node packages."); let packagesList = ""; - for (const package of REQUIRED_PACKAGES) { + for(const package of REQUIRED_PACKAGES){ packagesList += `\n- ${package.name}@${package.version}`; } - console.log("The following packages will be installed:", packagesList); console.log( @@ -42,13 +41,13 @@ function InstallPackages() { ); try { - packagesList = ""; + let packagesList = ""; for (const package of REQUIRED_PACKAGES) { packagesList += ` ${package.name}@${package.version}`; } - child.execSync(`npm i --force${packagesList}`); + child.execSync(`npm i${packagesList}`); console.log('Install complete!, please run "node index" command again!'); process.exit(); @@ -91,9 +90,11 @@ module.exports = () => { packageFile = JSON.parse(packageFile); if (packageFile.version !== package.version) { - errorMessage = `Unsupported "${package.name}" version!.\nStarting to install the supported version...`; + console.log( + `Unsupported "${package.name}" version!.\nPlease delete your "node_modules" and "package-lock.json".\nAnd restart the bot.\nPlease make sure to check and remove "npm install" command from your startup params.` + ); - break; + process.exit(); } else { success = true; From 0216b86024ad86ed99525303c4aca38164242815 Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Wed, 16 Aug 2023 20:21:14 +0530 Subject: [PATCH 27/32] Update checkStatus.js --- handlers/checkStatus.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handlers/checkStatus.js b/handlers/checkStatus.js index 98a6d85..5d4e915 100644 --- a/handlers/checkStatus.js +++ b/handlers/checkStatus.js @@ -13,7 +13,7 @@ const MENTION_DELETE_TIMEOUT = 1; module.exports = async ({ client }) => { function Embed({ node }) { return new EmbedBuilder() - .setTitle(EMBED_TITLE) //if you wanted to change this please change at line 244 too + .setTitle(EMBED_TITLE) .setDescription("`" + node.name + "` is down!") .setFooter({ text: "Please see console for more details" }) .setTimestamp() From 628a5366c9f9fc81dd8ba5152650824710cd15ab Mon Sep 17 00:00:00 2001 From: ShreshthTiwari <68736752+ShreshthTiwari@users.noreply.github.com> Date: Wed, 3 Jan 2024 19:14:21 +0530 Subject: [PATCH 28/32] updates packages version --- .gitignore | 3 +++ modules/intigrityCheck.js | 6 +++--- package.json | 6 +++--- 3 files changed, 9 insertions(+), 6 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d225ef6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +package-lock.json +.vscode +node_modules \ No newline at end of file diff --git a/modules/intigrityCheck.js b/modules/intigrityCheck.js index a1b33b2..93707ac 100644 --- a/modules/intigrityCheck.js +++ b/modules/intigrityCheck.js @@ -5,11 +5,11 @@ const path = require("node:path"); const REQUIRED_PACKAGES = [ { name: "axios", - version: "1.4.0", + version: "1.6.3", }, { name: "axios-retry", - version: "3.5.1", + version: "3.9.1", }, { name: "chalk", @@ -17,7 +17,7 @@ const REQUIRED_PACKAGES = [ }, { name: "discord.js", - version: "14.11.0", + version: "14.14.1", }, { name: "js-yaml", diff --git a/package.json b/package.json index e98022d..4d12eb7 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,10 @@ "start": "node index.js" }, "dependencies": { - "axios": "^1.4.0", - "axios-retry": "^3.5.1", + "axios": "^1.6.3", + "axios-retry": "^3.9.1", "chalk": "^4.1.2", - "discord.js": "^14.11.0", + "discord.js": "^14.14.1", "js-yaml": "^4.1.0" }, "engines": { From 9972a051a4f3507c920b1d4c31489df43dcfc8bf Mon Sep 17 00:00:00 2001 From: Hirzi <64255651+HirziDevs@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:11:03 +0700 Subject: [PATCH 29/32] Stop using latest axios version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4d12eb7..5aa4a68 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "start": "node index.js" }, "dependencies": { - "axios": "^1.6.3", + "axios": "1.6.3", "axios-retry": "^3.9.1", "chalk": "^4.1.2", "discord.js": "^14.14.1", From c5d9f87eb4e157be2bb9750f51758162d4af2475 Mon Sep 17 00:00:00 2001 From: Hirzi <64255651+HirziDevs@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:12:18 +0700 Subject: [PATCH 30/32] Update README --- README.md | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 96efd82..69c72b8 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@
-PteroStats Banner +PteroStats Banner -## Language / Bahasa -[[English]](https://github.com/HirziDevs/PteroStats/blob/main/README.md) | [[Indonesia]](https://github.com/HirziDevs/PteroStats/blob/main/Indo.md)
@@ -13,14 +11,10 @@ PteroStats is a bot designed to check Pterodactyl Panel and Nodes status and pos ## Example - Test Panel - Example - -- [Calvs Cloud](https://discord.gg/ssCQjhrBJN) - - Calvs Cloud + Example ## Installation -1. [Getting apikey from pterodactyl](#getting-apikey-from-pterodactyl) +1. [Getting API key from pterodactyl](#getting-apikey-from-pterodactyl) 2. [Creating Discord Bot](#creating-discord-bot) 3. [Inviting Discord Bot](#inviting-discord-bot) 4. [Getting Channel ID](#getting-channel-id) @@ -29,24 +23,28 @@ PteroStats is a bot designed to check Pterodactyl Panel and Nodes status and pos - [Using Custom Emoji](#using-custom-emoji) - [Blacklist Nodes](#blacklist-nodes) -### Getting apikey from pterodactyl -1. Go to your `pterodactyl admin page` and go to `Application API`. +### Getting API key from pterodactyl - Admin Panel +> [!WARNING] +> The use of Application API keys are **deprecated**, you should use **Client API keys** in the config file -2. Click on the `Create New` button +1. Go to your `Pterodactyl Panel` and go to `Account Page`. - Application API Page + Home -3. Set all options permission to `read` and for description you can put whatever you want +2. Click on the `API Credentials` button - Create Application API + Account Page -4. Copy the apikey. +3. Fill the `Description` and click on the `Create` button - Application API List + Create Client API Key -5. Paste the panel apikey and panel url at the config +4. Copy the API key. + + API Key + +5. Paste the panel API key and panel url at the config Panel Config @@ -78,10 +76,10 @@ Please refer to [this website](https://discordjs.guide/preparations/adding-your- 2. Run `npm install` in the root directory of the bot files. 3. Run `node index` and you are done. -if you need help contact me on discord `Hirzi#8701` or join [our discord support server](https://discord.gg/zv6maQRah3) +if you need help contact me on discord `@hirzidevs` or join [our discord support server](https://discord.gg/zv6maQRah3) ### Using Custom Emoji -1. type `\` in guild that has custom emoji you want +1. type `\` in server that has custom emoji you want Type \ on the chat @@ -123,7 +121,6 @@ If you having this issue, you can enable `log_error` on the config file and repo - [PteroStats DiscordJS v13](https://github.com/HirziDevs/PteroStats/tree/3d0512c3323ecf079101104c7ecf3c94d265e298) - [PteroStats DiscordJS v12](https://github.com/HirziDevs/PteroStats/tree/bcfa266be64dda11955f0bf9732da086bcea522c) - [Pterodactyl Panel](https://pterodactyl.io) -- [Pterodactyl Api Documentation](https://dashflo.net/docs/api/pterodactyl/v1/) +- [Pterodactyl API Documentation](https://github.com/devnote-dev/ptero-notes/) - [Pterodactyl Discord Server](https://discord.gg/pterodactyl) - [PteroBot Support Server](https://discord.gg/zv6maQRah3) -- [PteroBot Support Server (Indonesia)](https://discord.gg/EYaFB7WSg6) From 90076146b4f1d84c1a263cbe8e8870e277914854 Mon Sep 17 00:00:00 2001 From: Hirzi <64255651+HirziDevs@users.noreply.github.com> Date: Fri, 17 May 2024 20:25:36 +0700 Subject: [PATCH 31/32] Fix error text if the node has 0 disk/memory usage --- modules/memorySizeConverter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/memorySizeConverter.js b/modules/memorySizeConverter.js index 17d7f6f..d20edce 100644 --- a/modules/memorySizeConverter.js +++ b/modules/memorySizeConverter.js @@ -37,9 +37,9 @@ module.exports = (value, type) => { return result; } else { - return "INVALID VALUE"; + return "0"; } } else { - return "ERROR"; + return "0"; } }; From c12148bc58adfdc7b5e57eac39032b2e5171e7e8 Mon Sep 17 00:00:00 2001 From: Lezetho <126505858+lezetho@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:13:11 -0400 Subject: [PATCH 32/32] Update package.json --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 5aa4a68..8cf92a8 100644 --- a/package.json +++ b/package.json @@ -14,10 +14,10 @@ }, "dependencies": { "axios": "1.6.3", - "axios-retry": "^3.9.1", - "chalk": "^4.1.2", - "discord.js": "^14.14.1", - "js-yaml": "^4.1.0" + "axios-retry": "3.9.1", + "chalk": "4.1.2", + "discord.js": "14.14.1", + "js-yaml": "4.1.0" }, "engines": { "node": ">=16.9.0"