← back to browse
goat command

cpanel

No description

0
views
0
likes
0
installs
raw source
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(" ");
}

View raw file