const express = require('express'); const path = require('path'); const fs = require('fs'); const { performance } = require('perf_hooks'); const app = express(); const PORT = process.env.PORT || 7860; const systemStats = { status: 'ON', totalRequests: 0, success: 0, failed: 0, uptimeStart: Date.now(), history: [] }; const kumpulanFitur = {}; const folderFitur = path.join(__dirname, 'fitur'); if (!fs.existsSync(folderFitur)) { fs.mkdirSync(folderFitur); } fs.readdirSync(folderFitur).forEach(file => { if (file.endsWith('.js')) { const fitur = require(`./fitur/${file}`); kumpulanFitur[fitur.cmd] = fitur; } }); app.use(express.json({ limit: '50mb' })); app.use(express.urlencoded({ limit: '50mb', extended: true })); const apiTracker = (req, res, next) => { const start = performance.now(); const cmd = req.method === 'POST' ? (req.body?.cmd || 'unknown') : (req.query?.cmd || 'unknown'); const bytes = req.headers['content-length'] || 0; let sizeStr = ''; if (bytes > 1048576) { sizeStr = (bytes / 1048576).toFixed(2) + ' MB'; } else if (bytes > 1024) { sizeStr = (bytes / 1024).toFixed(2) + ' KB'; } else { sizeStr = 'Ringan'; } const now = new Date(); const formatter = new Intl.DateTimeFormat('id-ID', { timeZone: 'Asia/Jakarta', hour: '2-digit', minute: '2-digit', second: '2-digit' }); const timeStr = formatter.format(now).replace(/\./g, ':'); const logEntry = { time: timeStr, cmd: cmd, status: `MEMPROSES | ${sizeStr} ⏳` }; systemStats.history.push(logEntry); if (systemStats.history.length > 50) { systemStats.history.shift(); } res.on('finish', () => { const durationMs = performance.now() - start; const durationStr = durationMs > 1000 ? (durationMs / 1000).toFixed(2) + 's' : Math.round(durationMs) + 'ms'; const isSuccess = res.statusCode >= 200 && res.statusCode < 400; systemStats.totalRequests++; if (isSuccess) systemStats.success++; else systemStats.failed++; logEntry.status = isSuccess ? `SUCCESS | ${durationStr}` : `ERROR | ${durationStr}`; }); next(); }; app.get('/', (req, res) => { res.sendFile(path.join(__dirname, 'index.html')); }); app.get('/api/stats', (req, res) => { res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); const sendUpdate = () => { const currentStats = { ...systemStats, uptime: Math.floor((Date.now() - systemStats.uptimeStart) / 1000) }; res.write(`data: ${JSON.stringify(currentStats)}\n\n`); }; sendUpdate(); const streamInterval = setInterval(sendUpdate, 1000); req.on('close', () => clearInterval(streamInterval)); }); app.get('/api/menu', (req, res) => { const listFitur = Object.values(kumpulanFitur).map(f => ({ cmd: f.cmd, desc: f.desc || 'Tanpa deskripsi' })); res.json({ status: true, creator: "𝐂𝐑𝐄𝐀𝐓𝐄 𝐁𝐘 𝐒𝐈𝐆𝐈𝐓", total_fitur: listFitur.length, data: listFitur }); }); app.all('/api/execute', apiTracker, async (req, res) => { const cmd = req.method === 'POST' ? req.body.cmd : req.query.cmd; if (kumpulanFitur[cmd]) { try { await kumpulanFitur[cmd].execute(req, res); } catch (error) { res.status(500).json({ status: false, type: 'text', message: `Internal Server Error: ${error.message}` }); } } else { res.status(404).json({ status: false, type: 'text', message: 'Command Not Found' }); } }); app.use((req, res) => { res.status(404).json({ status: false, type: 'text', message: 'Endpoint Not Found' }); }); app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); });