// code from goatstore // api: https://store.agi.bd const { createCanvas, loadImage } = require("canvas"); const GIFEncoder = require("gifencoder"); const fs = require("fs-extra"); const path = require("path"); const SIZE = 400; const FRAMES = 30; const DELAY = 70; // ms per frame const LAND_FRAME = 11; // ei frame-er por bar shob namiye fela hoy const BAR_COUNT = 7; const BAR_WIDTH = 16; const GAP = (SIZE - BAR_COUNT * BAR_WIDTH) / (BAR_COUNT + 1); const clamp = (v, a, b) => Math.min(b, Math.max(a, v)); // bar namar somoy ektu bounce korbe function easeOutBounce(x) { const n1 = 7.5625, d1 = 2.75; if (x < 1 / d1) return n1 * x * x; if (x < 2 / d1) return n1 * (x -= 1.5 / d1) * x + 0.75; if (x < 2.5 / d1) return n1 * (x -= 2.25 / d1) * x + 0.9375; return n1 * (x -= 2.625 / d1) * x + 0.984375; } // Avatar ek-bar-i black & white kore rakhi (prottek frame-e kora lagbe na) function makeGrayAvatar(avatar) { const c = createCanvas(SIZE, SIZE); const ctx = c.getContext("2d"); ctx.drawImage(avatar, 0, 0, SIZE, SIZE); const img = ctx.getImageData(0, 0, SIZE, SIZE); const d = img.data; for (let i = 0; i < d.length; i += 4) { const g = (d[i] * 0.3 + d[i + 1] * 0.59 + d[i + 2] * 0.11) * 0.8; d[i] = d[i + 1] = d[i + 2] = g; } ctx.putImageData(img, 0, 0); return c; } function drawFrame(ctx, gray, f) { const landed = f >= LAND_FRAME; // 1) avatar (jail-e dhukle ektu kapbe) const shake = landed ? Math.sin(f * 2.2) * 3 : 0; ctx.fillStyle = "#000"; ctx.fillRect(0, 0, SIZE, SIZE); ctx.drawImage(gray, shake, 0, SIZE, SIZE); // 2) police siren (lal / neel jhilik) if (landed) { const red = Math.floor((f - LAND_FRAME) / 3) % 2 === 0; const grad = ctx.createLinearGradient(red ? 0 : SIZE, 0, red ? SIZE * 0.7 : SIZE * 0.3, 0); grad.addColorStop(0, red ? "rgba(255, 30, 30, 0.55)" : "rgba(30, 90, 255, 0.55)"); grad.addColorStop(1, "rgba(0, 0, 0, 0)"); ctx.fillStyle = grad; ctx.fillRect(0, 0, SIZE, SIZE); } // 3) bar upor theke namche (ekta ekta kore, delay diye) for (let i = 0; i < BAR_COUNT; i++) { const p = clamp((f - i) / 8, 0, 1); if (p <= 0) continue; const bottom = easeOutBounce(p) * SIZE; const x = GAP + i * (BAR_WIDTH + GAP); const grad = ctx.createLinearGradient(x, 0, x + BAR_WIDTH, 0); grad.addColorStop(0, "#1a1a1a"); grad.addColorStop(0.35, "#8a8a8a"); grad.addColorStop(0.5, "#cfcfcf"); grad.addColorStop(0.7, "#555555"); grad.addColorStop(1, "#111111"); ctx.fillStyle = grad; ctx.fillRect(x, bottom - SIZE, BAR_WIDTH, SIZE); } // 4) upore-niche rail (bar bosar por ashe) if (landed) { const a = clamp((f - LAND_FRAME) / 3, 0, 1); ctx.globalAlpha = a; for (const y of [0, SIZE - 30]) { const grad = ctx.createLinearGradient(0, y, 0, y + 30); grad.addColorStop(0, "#2b2b2b"); grad.addColorStop(0.5, "#9a9a9a"); grad.addColorStop(1, "#1a1a1a"); ctx.fillStyle = grad; ctx.fillRect(0, y, SIZE, 30); } ctx.globalAlpha = 1; } // 5) "JAIL" plate (blink kore) if (f >= LAND_FRAME + 2) { const blink = (f - LAND_FRAME) % 4 < 3 ? 1 : 0.4; ctx.globalAlpha = blink; ctx.fillStyle = "rgba(0, 0, 0, 0.8)"; ctx.fillRect(SIZE / 2 - 70, SIZE - 92, 140, 46); ctx.fillStyle = "#ffffff"; ctx.font = "bold 32px sans-serif"; ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillText("JAIL", SIZE / 2, SIZE - 68); ctx.globalAlpha = 1; } } module.exports = { config: { name: "jail", aliases: ["prison", "jel"], version: "2.0", author: "Zihad", countDown: 15, role: 0, description: { en: "Kauke jail-e vore dao (animated GIF)" }, category: "image", guide: { en: "{pn}: nijer avatar jail-e" + "\n{pn} @tag: tag kora user jail-e" + "\nOthoba kono message-e reply diye {pn}" } }, onStart: async function ({ message, event, usersData }) { const { senderID, mentions, messageReply } = event; let uid = senderID; if (messageReply) uid = messageReply.senderID; else if (Object.keys(mentions || {}).length > 0) uid = Object.keys(mentions)[0]; const name = await usersData.getName(uid); const outPath = path.join(__dirname, "tmp", `jail_${uid}_${Date.now()}.gif`); try { const avatar = await loadImage(await usersData.getAvatarUrl(uid)); const gray = makeGrayAvatar(avatar); fs.ensureDirSync(path.dirname(outPath)); const encoder = new GIFEncoder(SIZE, SIZE); const stream = encoder.createReadStream().pipe(fs.createWriteStream(outPath)); const done = new Promise((resolve, reject) => { stream.on("finish", resolve); stream.on("error", reject); }); encoder.start(); encoder.setRepeat(0); // 0 = infinite loop encoder.setDelay(DELAY); encoder.setQuality(10); const canvas = createCanvas(SIZE, SIZE); const ctx = canvas.getContext("2d"); for (let f = 0; f < FRAMES; f++) { drawFrame(ctx, gray, f); encoder.addFrame(ctx); } encoder.finish(); await done; await message.reply({ body: `🚔 ${name} ke jail-e pathano holo!`, attachment: fs.createReadStream(outPath) }); } catch (err) { console.error("[jail]", err); return message.reply("GIF banate shomossha hoyeche, abar try korun."); } finally { fs.remove(outPath).catch(() => { }); } } };