const fs = require("fs-extra"); const path = require("path"); const { createCanvas } = require("canvas"); const si = require("systeminformation"); const GIFEncoder = require("gifencoder"); function getHostingName() { const env = process.env; if (env.RENDER) return "Render"; if (env.RAILWAY_ENVIRONMENT) return "Railway"; if (env.VERCEL) return "Vercel"; if (env.REPL_ID) return "Replit"; if (env.FLY_APP_NAME) return "Fly.io"; if (env.AWS_EXECUTION_ENV) return "AWS"; if (env.DYNO) return "Heroku"; if (env.GITHUB_ACTIONS) return "GitHub"; return "VPS / Local"; } module.exports = { config: { name: "cpanel", version: "2.0.0", author: "Asif Evo", category: "info", guide: { en: "{pn} - Shows Bot System Panel" } }, onStart: async function ({ message }) { try { const [cpu, load, mem, osInfo] = await Promise.all([ si.cpu(), si.currentLoad(), si.mem(), si.osInfo() ]); // ========================= // UPTIME // ========================= const uptime = process.uptime() * 1000; const uptimeFormatted = formatUptime(uptime); // ========================= // BANGLADESH TIME // ========================= const bdTime = new Date().toLocaleString("en-US", { timeZone: "Asia/Dhaka", hour12: true }); // ========================= // CANVAS // ========================= const canvasWidth = 900; const canvasHeight = 600; const cacheDir = path.join(__dirname, "cache"); await fs.ensureDir(cacheDir); const outputPath = path.join( cacheDir, `asif_evo_cpanel_${Date.now()}.gif` ); // ========================= // GIF // ========================= const encoder = new GIFEncoder( canvasWidth, canvasHeight ); const gifStream = fs.createWriteStream(outputPath); encoder .createReadStream() .pipe(gifStream); encoder.start(); encoder.setRepeat(0); encoder.setDelay(160); encoder.setQuality(10); // ========================= // CANVAS // ========================= const canvas = createCanvas( canvasWidth, canvasHeight ); const ctx = canvas.getContext("2d"); const centerX = canvasWidth / 2; const centerY = canvasHeight / 2 + 15; // ========================= // CENTER // ========================= const centerData = { value: "𝐀𝐬𝐢𝐟 𝐄𝐯𝐨", radius: 105 }; // ========================= // SYSTEM DATA // ========================= const stats = [ { label: "𝐂𝐎𝐑𝐄𝐒", value: `𝟎${cpu.physicalCores || cpu.cores}` }, { label: "𝐓𝐇𝐑𝐄𝐀𝐃𝐒", value: String(cpu.cores) }, { label: "𝐋𝐎𝐀𝐃", value: `${load.currentLoad.toFixed(1)}%` }, { label: "𝐔𝐒𝐄𝐑", value: `${load.currentLoadUser.toFixed(1)}%` }, { label: "𝐑𝐀𝐌", value: `${(mem.total / 1e9).toFixed(1)}GB` }, { label: "𝐅𝐑𝐄𝐄", value: `${(mem.available / 1e9).toFixed(1)}GB` }, { label: "𝐎𝐒", value: osInfo.distro ? osInfo.distro .split(" ")[0] : "Linux" }, { label: "𝐇𝐎𝐒𝐓", value: getHostingName() }, { label: "𝐍𝐎𝐃𝐄", value: process.version .replace("v", "") }, { label: "𝐔𝐏𝐓𝐈𝐌𝐄", value: uptimeFormatted } ]; // ========================= // POSITIONS // ========================= const orbitRadius = 210; const circleRadius = 70; const statCircles = stats.map((stat, index) => { const angle = (Math.PI * 2 / stats.length) * index - Math.PI / 2; const x = centerX + orbitRadius * Math.cos(angle); const y = centerY + orbitRadius * Math.sin(angle); return { x, y, label: stat.label, value: stat.value, valueFont: fitFont( ctx, stat.value, 100, 17, true ), labelFont: fitFont( ctx, stat.label, 100, 11, true ) }; }); // ========================= // ANIMATION // ========================= const totalFrames = 36; for ( let frame = 0; frame < totalFrames; frame++ ) { const hue = (frame * 10) % 360; const glowColor = `hsl(${hue}, 100%, 65%)`; // ========================= // BACKGROUND // ========================= const gradient = ctx.createLinearGradient( 0, 0, canvasWidth, canvasHeight ); gradient.addColorStop( 0, "#030611" ); gradient.addColorStop( 0.5, "#0a1020" ); gradient.addColorStop( 1, "#020409" ); ctx.fillStyle = gradient; ctx.fillRect( 0, 0, canvasWidth, canvasHeight ); // ========================= // GRID // ========================= drawGrid( ctx, canvasWidth, canvasHeight, glowColor ); // ========================= // HEADER // ========================= ctx.textAlign = "left"; ctx.textBaseline = "alphabetic"; ctx.font = "bold 27px Arial"; ctx.shadowColor = glowColor; ctx.shadowBlur = 12; ctx.fillStyle = "#ffffff"; ctx.fillText( "🤖 𝐀𝐒𝐈𝐅 𝐄𝐕𝐎 𝐁𝐎𝐓 𝐕𝟑", 30, 38 ); ctx.shadowBlur = 0; ctx.font = "bold 12px Arial"; ctx.fillStyle = glowColor; ctx.fillText( "𝐒𝐘𝐒𝐓𝐄𝐌 𝐈𝐍𝐅𝐎𝐑𝐌𝐀𝐓𝐈𝐎𝐍 𝐏𝐀𝐍𝐄𝐋", 32, 60 ); // ========================= // TIME // ========================= ctx.textAlign = "right"; ctx.font = "bold 15px Arial"; ctx.fillStyle = "#ffffff"; ctx.fillText( bdTime, canvasWidth - 30, 38 ); ctx.font = "bold 10px Arial"; ctx.fillStyle = "#8994a6"; ctx.fillText( "𝐁𝐀𝐍𝐆𝐋𝐀𝐃𝐄𝐒𝐇 𝐓𝐈𝐌𝐄", canvasWidth - 30, 58 ); // ========================= // CONNECTION // ========================= statCircles.forEach( circle => { drawConnection( ctx, centerX, centerY, circle.x, circle.y, glowColor ); } ); // ========================= // CENTER CIRCLE // ========================= drawCircle( ctx, centerX, centerY, centerData.radius, glowColor ); drawCenterText( ctx, centerX, centerY, centerData.value, glowColor ); // ========================= // STAT CIRCLES // ========================= statCircles.forEach( circle => { drawCircle( ctx, circle.x, circle.y, circleRadius, glowColor ); drawStatText( ctx, circle, glowColor ); } ); // ========================= // FOOTER // ========================= ctx.textAlign = "center"; ctx.font = "bold 12px Arial"; ctx.fillStyle = "#707b8c"; ctx.fillText( "𝐀𝐒𝐈𝐅 𝐄𝐕𝐎 • 𝐁𝐎𝐓 𝐒𝐘𝐒𝐓𝐄𝐌 • 🟢 𝐎𝐍𝐋𝐈𝐍𝐄", centerX, canvasHeight - 20 ); encoder.addFrame(ctx); } // ========================= // FINISH // ========================= encoder.finish(); await new Promise( (resolve, reject) => { gifStream.on( "finish", resolve ); gifStream.on( "error", reject ); } ); // ========================= // SEND // ========================= await message.reply({ attachment: fs.createReadStream( outputPath ) }); // ========================= // DELETE CACHE // ========================= setTimeout(() => { fs.unlink( outputPath ).catch(() => {}); }, 10000); } catch (error) { console.error( "ASIF EVO CPANEL ERROR:", error ); return message.reply( "❌ 𝐂𝐏𝐀𝐍𝐄𝐋 𝐆𝐄𝐍𝐄𝐑𝐀𝐓𝐈𝐎𝐍 𝐅𝐀𝐈𝐋𝐄𝐃." ); } } }; // ====================================== // FONT FIT // ====================================== function fitFont( ctx, text, maxWidth, baseSize, bold ) { let size = baseSize; ctx.font = `${bold ? "bold " : ""}${size}px Arial`; while ( ctx.measureText(text).width > maxWidth && size > 8 ) { size--; ctx.font = `${bold ? "bold " : ""}${size}px Arial`; } return `${bold ? "bold " : ""}${size}px Arial`; } // ====================================== // CIRCLE // ====================================== function drawCircle( ctx, x, y, radius, glowColor ) { ctx.save(); // Outer glow ctx.shadowColor = glowColor; ctx.shadowBlur = 28; ctx.beginPath(); ctx.arc( x, y, radius, 0, Math.PI * 2 ); ctx.fillStyle = "#0b1320"; ctx.fill(); // Border ctx.shadowBlur = 0; ctx.strokeStyle = glowColor; ctx.lineWidth = 3; ctx.stroke(); // Inner ring ctx.beginPath(); ctx.arc( x, y, radius - 8, 0, Math.PI * 2 ); ctx.strokeStyle = "rgba(255,255,255,0.08)"; ctx.lineWidth = 1; ctx.stroke(); ctx.restore(); } // ====================================== // CENTER TEXT // ====================================== function drawCenterText( ctx, x, y, text, glowColor ) { ctx.save(); ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.font = "bold 27px Arial"; ctx.shadowColor = glowColor; ctx.shadowBlur = 18; ctx.fillStyle = glowColor; ctx.fillText( text, x, y ); ctx.restore(); } // ====================================== // STAT TEXT // ====================================== function drawStatText( ctx, circle, glowColor ) { ctx.save(); ctx.textAlign = "center"; ctx.textBaseline = "middle"; // Value ctx.font = circle.valueFont; ctx.shadowColor = glowColor; ctx.shadowBlur = 12; ctx.fillStyle = glowColor; ctx.fillText( circle.value, circle.x, circle.y - 7 ); // Label ctx.shadowBlur = 0; ctx.font = circle.labelFont; ctx.fillStyle = "#c5ccd6"; ctx.fillText( circle.label, circle.x, circle.y + 13 ); ctx.restore(); } // ====================================== // CONNECTION // ====================================== function drawConnection( ctx, x1, y1, x2, y2, glowColor ) { ctx.save(); ctx.beginPath(); ctx.moveTo( x1, y1 ); ctx.lineTo( x2, y2 ); ctx.strokeStyle = glowColor; ctx.globalAlpha = 0.15; ctx.lineWidth = 1; ctx.stroke(); ctx.restore(); } // ====================================== // GRID // ====================================== function drawGrid( ctx, width, height, glowColor ) { ctx.save(); ctx.globalAlpha = 0.06; ctx.strokeStyle = glowColor; ctx.lineWidth = 1; const gap = 45; for ( let x = 0; x < width; x += gap ) { ctx.beginPath(); ctx.moveTo( x, 0 ); ctx.lineTo( x, height ); ctx.stroke(); } for ( let y = 0; y < height; y += gap ) { ctx.beginPath(); ctx.moveTo( 0, y ); ctx.lineTo( width, y ); ctx.stroke(); } ctx.restore(); } // ====================================== // UPTIME FORMAT // ====================================== function formatUptime(ms) { if (ms <= 0) return "𝟎𝐬"; let sec = Math.floor(ms / 1000); const days = Math.floor( sec / 86400 ); sec %= 86400; const hours = Math.floor( sec / 3600 ); sec %= 3600; const minutes = Math.floor( sec / 60 ); const seconds = sec % 60; const parts = []; if (days > 0) parts.push(`${days}𝐝`); if (hours > 0) parts.push(`${hours}𝐡`); if (minutes > 0) parts.push(`${minutes}𝐦`); if ( seconds > 0 && parts.length === 0 ) { parts.push(`${seconds}𝐬`); } return parts.join(" "); }