goat
command
top
Top 15 Money Leaderboard
0
views
0
likes
0
installs
raw source
const fs = require("fs");
const path = require("path");
const moment = require("moment-timezone");
const { createCanvas, loadImage, registerFont } = require("canvas");
const axios = require("axios");
try {
registerFont('./fonts/Poppins-Bold.ttf', { family: 'Poppins', weight: 'bold' });
registerFont('./fonts/Poppins-Regular.ttf', { family: 'Poppins', weight: 'normal' });
registerFont('./fonts/Orbitron-Bold.ttf', { family: 'Orbitron', weight: 'bold' });
} catch (e) {
}
function formatMoney(value) {
value = Number(value);
if (isNaN(value)) return "0";
if (value >= 1e15) return (value / 1e15).toFixed(2) + "Q";
if (value >= 1e12) return (value / 1e12).toFixed(2) + "T";
if (value >= 1e9) return (value / 1e9).toFixed(2) + "B";
if (value >= 1e6) return (value / 1e6).toFixed(2) + "M";
if (value >= 1e3) return (value / 1e3).toFixed(2) + "K";
return value.toString();
}
const avatarCache = new Map();
async function fetchAvatar(userID, usersData) {
if (avatarCache.has(userID)) return avatarCache.get(userID);
try {
let avatarURL = await usersData.getAvatarUrl(userID);
if (!avatarURL) {
avatarURL = `https://graph.facebook.com/${userID}/picture?type=large&width=500&height=500&access_token=6628568379%7Cc1e620fa708a1d5696fb991c1bde5662`;
}
const res = await axios.get(avatarURL, {
responseType: "arraybuffer",
timeout: 5000,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
});
const image = await loadImage(Buffer.from(res.data));
avatarCache.set(userID, image);
return image;
} catch (e) {
const canvas = createCanvas(200, 200);
const ctx = canvas.getContext("2d");
const hue = userID ? userID.split('').reduce((a,b)=>a+b.charCodeAt(0),0) % 360 : 200;
const gradient = ctx.createLinearGradient(0, 0, 200, 200);
gradient.addColorStop(0, `hsl(${hue}, 80%, 60%)`);
gradient.addColorStop(1, `hsl(${hue + 40}, 80%, 40%)`);
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 200, 200);
ctx.fillStyle = "rgba(255,255,255,0.1)";
ctx.fillRect(0, 0, 200, 100);
ctx.shadowColor = "rgba(0,0,0,0.5)";
ctx.shadowBlur = 10;
ctx.fillStyle = "#fff";
ctx.font = "bold 90px 'Poppins', Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
const firstLetter = userID ? userID[0] : "U";
ctx.fillText(firstLetter.toUpperCase(), 100, 100);
avatarCache.set(userID, canvas);
return canvas;
}
}
function roundRect(ctx, x, y, width, height, radius) {
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
}
async function drawTopBoard(users, usersData) {
const W = 1200, H = 1600;
const canvas = createCanvas(W, H);
const ctx = canvas.getContext("2d");
try {
const bg = ctx.createLinearGradient(0, 0, W, H);
bg.addColorStop(0, "#0a0a0f");
bg.addColorStop(0.3, "#1a1a2e");
bg.addColorStop(0.7, "#16213e");
bg.addColorStop(1, "#0f0f1a");
ctx.fillStyle = bg;
ctx.fillRect(0, 0, W, H);
// Animated-style particles with glow - reduced count
for (let i = 0; i < 150; i++) {
const x = Math.random() * W;
const y = Math.random() * H;
const size = Math.random() * 3;
const opacity = Math.random() * 0.5;
const hue = Math.random() > 0.5 ? 200 : 280;
ctx.shadowColor = `hsla(${hue}, 100%, 70%, ${opacity})`;
ctx.shadowBlur = 10;
ctx.fillStyle = `hsla(${hue}, 100%, 80%, ${opacity})`;
ctx.beginPath();
ctx.arc(x, y, size, 0, Math.PI*2);
ctx.fill();
}
ctx.shadowBlur = 0;
// Top decorative line with glow
const lineGrad = ctx.createLinearGradient(0, 0, W, 0);
lineGrad.addColorStop(0, "transparent");
lineGrad.addColorStop(0.2, "#00d4ff");
lineGrad.addColorStop(0.5, "#ff00ff");
lineGrad.addColorStop(0.8, "#00d4ff");
lineGrad.addColorStop(1, "transparent");
ctx.shadowColor = "#00d4ff";
ctx.shadowBlur = 20;
ctx.strokeStyle = lineGrad;
ctx.lineWidth = 4;
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(W - 100, 100);
ctx.stroke();
ctx.shadowBlur = 0;
// Title - smaller and higher
ctx.save();
ctx.shadowColor = "#ff00ff";
ctx.shadowBlur = 30;
ctx.font = "bold 60px 'Orbitron', 'Arial', sans-serif";
ctx.fillStyle = "#ffffff";
ctx.textAlign = "center";
ctx.fillText("TOP 15 RICHEST USERS", W/2, 65);
ctx.shadowColor = "#00d4ff";
ctx.shadowBlur = 60;
ctx.fillStyle = "rgba(255,255,255,0.3)";
ctx.fillText("TOP 15 RICHEST USERS", W/2, 65);
ctx.restore();
// Subtitle - smaller
ctx.font = "italic 24px 'Poppins', Arial";
ctx.fillStyle = "rgba(255,255,255,0.6)";
ctx.fillText("Elite Billionaires Club", W/2, 95);
// Top 3 positions - COMPACT
const positions = [
{ x: W/2 - 80, y: 130, size: 160, color: "#ffd700", glow: "#ffaa00", rank: 1 }, // Center - smaller
{ x: W/2 - 350, y: 200, size: 130, color: "#c0c0c0", glow: "#a0a0a0", rank: 2 }, // Left - smaller
{ x: W/2 + 200, y: 200, size: 130, color: "#cd7f32", glow: "#b87333", rank: 3 }, // Right - smaller
];
// Draw top 3 users
for (let i = 0; i < 3 && i < users.length; i++) {
try {
await drawTopThreeCompact(ctx, users[i], positions[i], usersData);
} catch (e) {
console.log(`Error drawing top player ${i}:`, e);
}
}
// Divider line - moved up
ctx.strokeStyle = "rgba(255,255,255,0.2)";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(100, 420);
ctx.lineTo(W - 100, 420);
ctx.stroke();
// Compact cards for 4-15
const startY = 435;
const cardHeight = 60; // Reduced from 75
const gap = 8; // Reduced from 12
for (let i = 3; i < users.length; i++) {
try {
const y = startY + (i-3) * (cardHeight + gap);
await drawCompactCard(ctx, users[i], i+1, y, usersData, W);
} catch (e) {
console.log(`Error drawing rank card ${i}:`, e);
}
}
// Bottom section - compact
const footerY = H - 80;
// Gradient line
ctx.shadowColor = "#ff00ff";
ctx.shadowBlur = 15;
const footerGrad = ctx.createLinearGradient(200, 0, W-200, 0);
footerGrad.addColorStop(0, "transparent");
footerGrad.addColorStop(0.5, "rgba(0,212,255,0.8)");
footerGrad.addColorStop(1, "transparent");
ctx.strokeStyle = footerGrad;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(200, footerY);
ctx.lineTo(W - 200, footerY);
ctx.stroke();
ctx.shadowBlur = 0;
// Stats - smaller
ctx.font = "bold 24px 'Poppins', Arial";
ctx.fillStyle = "#00d4ff";
ctx.textAlign = "center";
ctx.fillText(`Total Users: ${usersData.getAll ? (await usersData.getAll()).length : 'N/A'}`, W/2, footerY + 30);
ctx.font = "18px 'Poppins', Arial";
ctx.fillStyle = "rgba(255,255,255,0.5)";
ctx.fillText(`${moment().tz("Asia/Dhaka").format("YYYY-MM-DD | hh:mm:ss A")}`, W/2, footerY + 55);
// Save with high quality
const cacheDir = path.join(__dirname, "cache");
if (!fs.existsSync(cacheDir)) {
fs.mkdirSync(cacheDir, { recursive: true });
}
const fileName = `top_money_${Date.now()}.png`;
const filePath = path.join(cacheDir, fileName);
const buffer = canvas.toBuffer("image/png", { compressionLevel: 3, filters: canvas.PNG_FILTER_NONE });
fs.writeFileSync(filePath, buffer);
return filePath;
} catch (e) {
console.log("Error in drawTopBoard:", e);
throw e;
}
}
async function drawTopThreeCompact(ctx, user, pos, usersData) {
try {
const avatar = await fetchAvatar(user.userID, usersData);
const { x, y, size, color, glow, rank } = pos;
const centerX = x + size/2;
const centerY = y + size/2;
// Outer glow ring - thinner
ctx.shadowColor = glow;
ctx.shadowBlur = 30;
ctx.beginPath();
ctx.arc(centerX, centerY, size/2 + 15, 0, Math.PI*2);
ctx.strokeStyle = color;
ctx.lineWidth = 4;
ctx.stroke();
// Inner glow
ctx.shadowBlur = 10;
ctx.beginPath();
ctx.arc(centerX, centerY, size/2 + 8, 0, Math.PI*2);
ctx.strokeStyle = "rgba(255,255,255,0.5)";
ctx.lineWidth = 2;
ctx.stroke();
ctx.shadowBlur = 0;
// Avatar with clip
ctx.save();
ctx.beginPath();
ctx.arc(centerX, centerY, size/2, 0, Math.PI*2);
ctx.clip();
ctx.fillStyle = "#1a1a2e";
ctx.fillRect(x, y, size, size);
ctx.drawImage(avatar, x, y, size, size);
// Glass overlay
const glassGrad = ctx.createLinearGradient(0, y + size*0.6, 0, y + size);
glassGrad.addColorStop(0, "transparent");
glassGrad.addColorStop(1, "rgba(0,0,0,0.4)");
ctx.fillStyle = glassGrad;
ctx.fillRect(x, y + size*0.6, size, size*0.4);
ctx.restore();
// Rank text - smaller
ctx.font = "bold 26px 'Orbitron', Arial";
ctx.fillStyle = color;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.shadowColor = glow;
ctx.shadowBlur = 8;
ctx.fillText(`#${rank}`, centerX, y + size + 25);
ctx.shadowBlur = 0;
// Name - smaller
ctx.shadowColor = "rgba(255,255,255,0.5)";
ctx.shadowBlur = 8;
ctx.font = "bold 24px 'Poppins', Arial";
ctx.fillStyle = "#fff";
ctx.textAlign = "center";
ctx.textBaseline = "alphabetic";
const displayName = user.name && user.name.length > 10 ? user.name.slice(0, 8) + ".." : (user.name || "Unknown");
ctx.fillText(displayName, centerX, y + size + 55);
ctx.shadowBlur = 0;
// Money - smaller
ctx.font = "bold 20px 'Poppins', Arial";
ctx.fillStyle = color;
ctx.fillText(`${formatMoney(user.money || 0)}`, centerX, y + size + 80);
} catch (e) {
console.log("Error in drawTopThreeCompact:", e);
}
}
// Compact card for 4-15
async function drawCompactCard(ctx, user, rank, y, usersData, W) {
try {
const x = 60;
const w = W - 120;
const h = 60; // Reduced height
const avatar = await fetchAvatar(user.userID, usersData);
const avatarSize = 45; // Reduced from 55
// Subtle glass background
const glassGrad = ctx.createLinearGradient(x, y, x + w, y + h);
glassGrad.addColorStop(0, "rgba(255,255,255,0.05)");
glassGrad.addColorStop(0.5, "rgba(255,255,255,0.02)");
glassGrad.addColorStop(1, "rgba(255,255,255,0.05)");
ctx.fillStyle = glassGrad;
roundRect(ctx, x, y, w, h, 12);
ctx.fill();
// Single accent line on left - thinner
const rankColors = {
4: "#00d4ff", 5: "#00d4ff", 6: "#00d4ff",
7: "#ff6b6b", 8: "#ff6b6b", 9: "#ff6b6b",
10: "#ffd93d", 11: "#ffd93d", 12: "#ffd93d",
13: "#6bcf7f", 14: "#6bcf7f", 15: "#6bcf7f"
};
const accentColor = rankColors[rank] || "#00d4ff";
ctx.fillStyle = accentColor;
ctx.fillRect(x, y + 8, 3, h - 16);
// Rank number - smaller
ctx.font = "bold 22px 'Orbitron', Arial";
ctx.fillStyle = accentColor;
ctx.textAlign = "left";
ctx.textBaseline = "middle";
ctx.fillText(`#${rank}`, x + 15, y + h/2);
// Avatar with subtle ring - smaller
const avatarX = x + 65;
const avatarY = y + 7;
ctx.save();
ctx.beginPath();
ctx.arc(avatarX + avatarSize/2, avatarY + avatarSize/2, avatarSize/2, 0, Math.PI*2);
ctx.clip();
ctx.drawImage(avatar, avatarX, avatarY, avatarSize, avatarSize);
ctx.restore();
// Avatar ring - thinner
ctx.beginPath();
ctx.arc(avatarX + avatarSize/2, avatarY + avatarSize/2, avatarSize/2 + 1, 0, Math.PI*2);
ctx.strokeStyle = accentColor;
ctx.lineWidth = 2;
ctx.stroke();
// Name - smaller
ctx.font = "bold 22px 'Poppins', Arial";
ctx.fillStyle = "#fff";
ctx.textAlign = "left";
ctx.textBaseline = "middle";
const displayName = user.name && user.name.length > 18 ? user.name.slice(0, 16) + ".." : (user.name || "Unknown");
ctx.fillText(displayName, x + 120, y + h/2);
// Money - smaller
ctx.font = "bold 20px 'Orbitron', Arial";
ctx.fillStyle = "#00ff88";
ctx.textAlign = "right";
ctx.textBaseline = "middle";
ctx.fillText(`${formatMoney(user.money || 0)}`, x + w - 20, y + h/2);
} catch (e) {
console.log("Error in drawCompactCard:", e);
}
}
// Module export
module.exports = {
config: {
name: "top",
version: "0.0.7",
author: "Azadx69x",
countDown: 5,
role: 0,
shortDescription: "Top 15 Money Leaderboard",
longDescription: "Shows top 15 richest users",
category: "rank",
guide: "{pn} money"
},
onStart: async function({ api, event, usersData, message }) {
try {
// Set loading reaction
if (api && event) {
api.setMessageReaction("⚡", event.messageID, () => {}, true);
}
// Get all users
const allUsers = await usersData.getAll();
if (!allUsers || allUsers.length === 0) {
return message.reply("No users found in database!");
}
// Sort by money and get top 15
const sorted = allUsers
.map(u => ({
userID: u.userID,
name: u.name || "Unknown User",
money: u.money || 0
}))
.sort((a, b) => b.money - a.money)
.slice(0, 15);
// Generate compact image
const filePath = await drawTopBoard(sorted, usersData);
// Send message with attachment only
await message.reply({
attachment: fs.createReadStream(filePath)
});
// Success reaction
if (api && event) {
api.setMessageReaction("✓", event.messageID, () => {}, true);
}
// Cleanup after 10 seconds
setTimeout(() => {
try {
if (fs.existsSync(filePath)) {
fs.unlinkSync(filePath);
}
} catch (e) {}
}, 10000);
} catch(err) {
console.error("Top command error:", err);
if (api && event) {
try {
api.setMessageReaction("✗", event.messageID, () => {}, true);
} catch (e) {}
}
return message.reply("Error generating leaderboard. Please try again later.");
}
}
};