goat
command
up
No description
0
views
0
likes
0
installs
Aliases: uptime
raw source
module.exports.config = {
name: "up",
version: "2.0.0",
author: "๐๐๐๐ฎ๐
",
aliases: ["uptime"],
role: 0,
category: "system"
};
const { createCanvas } = require("canvas");
const fs = require("fs-extra");
const path = require("path");
const os = require("os");
module.exports.onStart = async function ({ api, event }) {
const started = Date.now();
try {
const formatUptime = (seconds) => {
seconds = Math.floor(seconds);
const days = Math.floor(seconds / 86400);
seconds %= 86400;
const hours = Math.floor(seconds / 3600);
seconds %= 3600;
const minutes = Math.floor(seconds / 60);
const secs = seconds % 60;
const parts = [];
if (days > 0) parts.push(`${days}d`);
if (hours > 0) parts.push(`${hours}h`);
if (minutes > 0) parts.push(`${minutes}m`);
parts.push(`${secs}s`);
return parts.join(" ");
};
const getCPU = () => {
try {
const cpus = os.cpus();
if (!cpus.length) return 0;
let idle = 0;
let total = 0;
for (const cpu of cpus) {
idle += cpu.times.idle;
total +=
cpu.times.user +
cpu.times.nice +
cpu.times.sys +
cpu.times.idle +
cpu.times.irq;
}
const usage = 100 - (idle / total) * 100;
return Math.max(0, Math.min(100, usage));
} catch (_) {
return 0;
}
};
const getDisk = () => {
try {
if (typeof fs.statfsSync !== "function") {
return { used: 0, total: 0, percent: 0 };
}
const stat = fs.statfsSync("/");
const total = Number(stat.blocks) * Number(stat.bsize);
const free = Number(stat.bfree) * Number(stat.bsize);
const used = total - free;
return {
used,
total,
percent: total > 0 ? (used / total) * 100 : 0
};
} catch (_) {
return { used: 0, total: 0, percent: 0 };
}
};
const roundRect = (ctx, x, y, w, h, r) => {
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.lineTo(x + w - r, y);
ctx.quadraticCurveTo(x + w, y, x + w, y + r);
ctx.lineTo(x + w, y + h - r);
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
ctx.lineTo(x + r, y + h);
ctx.quadraticCurveTo(x, y + h, x, y + h - r);
ctx.lineTo(x, y + r);
ctx.quadraticCurveTo(x, y, x + r, y);
ctx.closePath();
};
const bubble = (ctx, x, y, r, color, alpha = 1) => {
ctx.save();
ctx.globalAlpha = alpha;
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
};
const cloud = (ctx, x, y, scale = 1) => {
ctx.save();
ctx.fillStyle = "#FFFFFF";
ctx.globalAlpha = 0.72;
ctx.beginPath();
ctx.arc(x, y + 22 * scale, 30 * scale, 0, Math.PI * 2);
ctx.arc(x + 34 * scale, y, 39 * scale, 0, Math.PI * 2);
ctx.arc(x + 75 * scale, y + 20 * scale, 31 * scale, 0, Math.PI * 2);
ctx.moveTo(x - 30 * scale, y + 22 * scale);
ctx.quadraticCurveTo(
x + 38 * scale,
y + 58 * scale,
x + 104 * scale,
y + 23 * scale
);
ctx.lineTo(x + 104 * scale, y + 43 * scale);
ctx.lineTo(x - 30 * scale, y + 43 * scale);
ctx.closePath();
ctx.fill();
ctx.restore();
};
const drawSparkle = (ctx, x, y, size, color) => {
ctx.save();
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(x, y - size);
ctx.lineTo(x + size * 0.28, y - size * 0.28);
ctx.lineTo(x + size, y);
ctx.lineTo(x + size * 0.28, y + size * 0.28);
ctx.lineTo(x, y + size);
ctx.lineTo(x - size * 0.28, y + size * 0.28);
ctx.lineTo(x - size, y);
ctx.lineTo(x - size * 0.28, y - size * 0.28);
ctx.closePath();
ctx.fill();
ctx.restore();
};
const width = 1280;
const height = 760;
const canvas = createCanvas(width, height);
const ctx = canvas.getContext("2d");
const background = ctx.createLinearGradient(0, 0, width, height);
background.addColorStop(0, "#E9F6FF");
background.addColorStop(0.45, "#F0EBFF");
background.addColorStop(1, "#FFF0F5");
ctx.fillStyle = background;
ctx.fillRect(0, 0, width, height);
cloud(ctx, 75, 70, 1);
cloud(ctx, 1010, 75, 1.25);
cloud(ctx, 1110, 280, 0.55);
bubble(ctx, 115, 300, 55, "#DCCFFF", 0.25);
bubble(ctx, 1180, 500, 75, "#B9DFF7", 0.25);
bubble(ctx, 1010, 580, 42, "#F5C9D9", 0.3);
drawSparkle(ctx, 1050, 180, 10, "#C6B7F4");
drawSparkle(ctx, 180, 180, 7, "#A8D5F0");
drawSparkle(ctx, 1125, 330, 6, "#E6AFC5");
ctx.save();
ctx.shadowColor = "rgba(93, 77, 130, 0.16)";
ctx.shadowBlur = 45;
ctx.shadowOffsetY = 18;
roundRect(ctx, 65, 55, 1150, 650, 48);
const panel = ctx.createLinearGradient(65, 55, 1215, 705);
panel.addColorStop(0, "rgba(255,255,255,0.94)");
panel.addColorStop(1, "rgba(255,249,253,0.90)");
ctx.fillStyle = panel;
ctx.fill();
ctx.restore();
ctx.fillStyle = "#443A5B";
ctx.font = "700 42px Sans";
ctx.fillText("UPTIME", 115, 125);
ctx.fillStyle = "#9389A6";
ctx.font = "500 17px Sans";
ctx.fillText("Live information", 118, 153);
bubble(ctx, 1080, 115, 9, "#B8A8E7");
ctx.fillStyle = "#8A80A0";
ctx.font = "600 13px Sans";
ctx.fillText("ONLINE", 1100, 120);
const heroX = 115;
const heroY = 185;
const heroW = 1050;
const heroH = 165;
ctx.save();
ctx.shadowColor = "rgba(114, 96, 155, 0.12)";
ctx.shadowBlur = 25;
ctx.shadowOffsetY = 10;
roundRect(ctx, heroX, heroY, heroW, heroH, 38);
const hero = ctx.createLinearGradient(
heroX,
heroY,
heroX + heroW,
heroY + heroH
);
hero.addColorStop(0, "#DDF2FF");
hero.addColorStop(0.5, "#EDE5FF");
hero.addColorStop(1, "#FFE7F0");
ctx.fillStyle = hero;
ctx.fill();
ctx.restore();
ctx.fillStyle = "#817596";
ctx.font = "600 15px Sans";
ctx.fillText("RUNNING FOR", 155, 228);
ctx.fillStyle = "#403652";
ctx.font = "700 48px Sans";
ctx.fillText(
formatUptime(process.uptime()),
155,
282
);
ctx.fillStyle = "#9489A7";
ctx.font = "500 16px Sans";
ctx.fillText("process uptime", 158, 313);
bubble(ctx, 1030, 260, 50, "#FFFFFF", 0.55);
bubble(ctx, 1080, 285, 32, "#FFFFFF", 0.42);
bubble(ctx, 990, 290, 25, "#FFFFFF", 0.35);
drawSparkle(ctx, 1075, 230, 9, "#B39DEB");
const response = Date.now() - started;
const cpu = getCPU();
const totalMemory = os.totalmem();
const freeMemory = os.freemem();
const usedMemory = totalMemory - freeMemory;
const ramPercent =
totalMemory > 0
? (usedMemory / totalMemory) * 100
: 0;
const disk = getDisk();
const cards = [
{
x: 115,
title: "RESPONSE",
value: `${response} ms`,
bg: "#FFF0E5",
dot: "#E8AE80"
},
{
x: 380,
title: "CPU",
value: `${cpu.toFixed(1)}%`,
bg: "#EAE5FF",
dot: "#9E8BD7"
},
{
x: 645,
title: "RAM",
value: `${ramPercent.toFixed(1)}%`,
bg: "#E4F3FF",
dot: "#82B8D8"
},
{
x: 910,
title: "DISK",
value: `${disk.percent.toFixed(1)}%`,
bg: "#FFE8F0",
dot: "#D89AB4"
}
];
cards.forEach((card) => {
ctx.save();
ctx.shadowColor = "rgba(105, 88, 130, 0.09)";
ctx.shadowBlur = 18;
ctx.shadowOffsetY = 9;
roundRect(ctx, card.x, 385, 235, 120, 30);
ctx.fillStyle = card.bg;
ctx.fill();
ctx.restore();
bubble(ctx, card.x + 28, 415, 6, card.dot);
ctx.fillStyle = "#827791";
ctx.font = "600 12px Sans";
ctx.fillText(card.title, card.x + 43, 420);
ctx.fillStyle = "#463B58";
ctx.font = "700 27px Sans";
ctx.fillText(card.value, card.x + 25, 463);
ctx.fillStyle = "#A39AAD";
ctx.font = "500 12px Sans";
if (card.title === "RAM") {
ctx.fillText(
`${Math.round(usedMemory / 1024 / 1024)} MB used`,
card.x + 25,
486
);
} else if (card.title === "DISK") {
ctx.fillText(
`${Math.round(disk.used / 1024 / 1024 / 1024)} GB used`,
card.x + 25,
486
);
} else {
ctx.fillText("current value", card.x + 25, 486);
}
});
const details = [
["PLATFORM", process.platform],
["NODE", process.version],
["CORES", String(os.cpus().length)],
["LOAD", (os.loadavg()[0] || 0).toFixed(2)]
];
details.forEach((item, index) => {
const x = 115 + index * 265;
ctx.fillStyle = "#978CA9";
ctx.font = "600 11px Sans";
ctx.fillText(item[0], x, 548);
ctx.fillStyle = "#554967";
ctx.font = "600 17px Sans";
ctx.fillText(item[1], x, 578);
});
ctx.save();
ctx.globalAlpha = 0.8;
ctx.fillStyle = "#D9CEFA";
ctx.beginPath();
ctx.ellipse(135, 650, 70, 25, -0.15, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "#C9E7FA";
ctx.beginPath();
ctx.ellipse(235, 660, 100, 27, 0.12, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "#F4D4E0";
ctx.beginPath();
ctx.ellipse(1090, 650, 95, 26, -0.1, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
drawSparkle(ctx, 320, 630, 6, "#B5A3E9");
drawSparkle(ctx, 930, 625, 8, "#D9A8BE");
const now = new Date();
const dateText = now.toLocaleDateString("en-GB", {
day: "2-digit",
month: "short",
year: "numeric"
});
const timeText = now.toLocaleTimeString("en-US", {
hour: "2-digit",
minute: "2-digit",
second: "2-digit"
});
ctx.fillStyle = "#A097A9";
ctx.font = "500 12px Sans";
ctx.fillText(
`${dateText} โข ${timeText}`,
115,
670
);
const filePath = path.join(
__dirname,
`uptime_${Date.now()}.png`
);
fs.writeFileSync(
filePath,
canvas.toBuffer("image/png")
);
await api.sendMessage(
{
attachment: fs.createReadStream(filePath)
},
event.threadID,
() => {
try {
fs.unlinkSync(filePath);
} catch (_) {}
},
event.messageID
);
} catch (_) {}
};