diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..9116783
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,23 @@
+FROM node:18-bullseye
+
+# Set working directory
+WORKDIR /app
+
+# Copy package info dulu
+COPY package*.json ./
+
+# Install SEMUA dependencies (hapus --production agar lebih aman)
+RUN npm install
+
+# Copy sisa file
+COPY . .
+
+# Set Environment Variable
+ENV PORT=3000
+ENV NODE_ENV=production
+
+# Buka Port
+EXPOSE 3000
+
+# Jalankan server
+CMD ["node", "server.js"]
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..17df815
--- /dev/null
+++ b/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "prometheus-web",
+ "version": "1.0.0",
+ "description": "Obfuscator",
+ "main": "server.js",
+ "scripts": {
+ "start": "node server.js"
+ },
+ "dependencies": {
+ "body-parser": "^1.20.2",
+ "cors": "^2.8.5",
+ "express": "^4.18.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+}
diff --git a/readme.md b/readme.md
index 4040509..c25c01f 100644
--- a/readme.md
+++ b/readme.md
@@ -1,4 +1,4 @@
-# :fire: Prometheus
+# :fire: Prometheus 3
[](https://github.com/prometheus-lua/Prometheus/actions/workflows/Test.yml)
## Description
Prometheus is a Lua obfuscator written in pure Lua.
diff --git a/server.js b/server.js
new file mode 100644
index 0000000..73105cd
--- /dev/null
+++ b/server.js
@@ -0,0 +1,398 @@
+const express = require('express');
+const bodyParser = require('body-parser');
+const cors = require('cors');
+const crypto = require('crypto');
+
+const app = express();
+const PORT = process.env.PORT || 3000;
+
+// Middleware
+app.use(cors());
+app.use(bodyParser.json({ limit: '50mb' }));
+app.use(bodyParser.urlencoded({ extended: true, limit: '50mb' }));
+
+// ==================== HTML UI ====================
+app.get('/', (req, res) => {
+ res.send(`
+
+
+
+
+
+ Prometheus Advanced
+
+
+
+
+
🔐 Prometheus Advanced
+
Self-Hosted Lua Obfuscator
+
+
+
+
+
+
📝 Input Script
+
+
+
+
🔐 Output
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `);
+});
+
+// ==================== OBFUSCATOR LOGIC ====================
+
+class LuaObfuscator {
+ constructor(settings = {}) {
+ this.settings = settings;
+ this.level = settings.level || 3;
+ this.stats = { stringsEncrypted: 0, varsRenamed: 0 };
+ this.encryptionKey = this.generateKey(16);
+ this.varCounter = 0;
+ this.reserved = new Set([
+ 'and','break','do','else','elseif','end','false','for','function','goto',
+ 'if','in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'game','workspace','script','print','warn','error','pcall','loadstring'
+ ]);
+ }
+
+ generateKey(length) {
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+ let result = '';
+ for (let i = 0; i < length; i++) result += chars.charAt(Math.floor(Math.random() * chars.length));
+ return result;
+ }
+
+ randomILVar() {
+ const chars = ['I', 'l', '1'];
+ let result = chars[Math.floor(Math.random() * 2)];
+ let length = 8 + Math.floor(Math.random() * 8);
+ for (let i = 1; i < length; i++) result += chars[Math.floor(Math.random() * chars.length)];
+ return result;
+ }
+
+ randomInt(min = 1000, max = 99999) {
+ return Math.floor(Math.random() * (max - min + 1)) + min;
+ }
+
+ xorEncrypt(str, key) {
+ let result = [];
+ for (let i = 0; i < str.length; i++) {
+ result.push(str.charCodeAt(i) ^ key.charCodeAt(i % key.length));
+ }
+ return result;
+ }
+
+ generateStringDecryptor() {
+ const funcName = this.randomILVar();
+ const keyVar = this.randomILVar();
+ const dataVar = this.randomILVar();
+ const resultVar = this.randomILVar();
+ const indexVar = this.randomILVar();
+
+ return {
+ name: funcName,
+ code: `local ${funcName}=(function(${dataVar},${keyVar})local ${resultVar}="";for ${indexVar}=1,#${dataVar} do ${resultVar}=${resultVar}..string.char(bit32.bxor(${dataVar}[${indexVar}],string.byte(${keyVar},(${indexVar}-1)%#${keyVar}+1)));end;return ${resultVar};end);`
+ };
+ }
+
+ encryptString(str) {
+ if (str.length === 0) return '""';
+ if (str.length > 200) return null;
+ this.stats.stringsEncrypted++;
+ const encrypted = this.xorEncrypt(str, this.encryptionKey);
+ return { data: `{${encrypted.join(',')}}`, key: `"${this.encryptionKey}"` };
+ }
+
+ generateJunkCode(count = 5) {
+ const junk = [];
+ for (let i = 0; i < count; i++) {
+ const v1 = this.randomILVar();
+ const n1 = this.randomInt();
+ junk.push(`local ${v1}=${n1};`);
+ }
+ return junk.join('');
+ }
+
+ generateOpaquePredicate(isTrue = true) {
+ const n1 = this.randomInt(1, 1000);
+ return isTrue ? `(${n1}==${n1})` : `(${n1}~=${n1})`;
+ }
+
+ generateAntiDebug() {
+ const checkVar = this.randomILVar();
+ return `local ${checkVar}=(function()pcall(function()if getgenv and(getgenv().SimpleSpy or getgenv().RemoteSpy)then while true do end end end)return true end)();`;
+ }
+
+ generateEnvWrapper() {
+ const envVar = this.randomILVar();
+ return `local ${envVar}=setmetatable({},{__index=function(s,k)return rawget(s,k)or getfenv()[k]or _G[key]end});setfenv(1,${envVar});`;
+ }
+
+ obfuscate(script) {
+ let result = script;
+ const stringDecryptor = this.generateStringDecryptor();
+ let needsDecryptor = false;
+
+ // 1. String Encryption
+ if (this.settings.strEncrypt !== false) {
+ result = result.replace(/"([^"\\]*(\\.[^"\\]*)*)"/g, (match, content) => {
+ if (content.length === 0 || content.length > 150) return match;
+ const encrypted = this.encryptString(content);
+ if (encrypted) {
+ needsDecryptor = true;
+ return `${stringDecryptor.name}(${encrypted.data},${encrypted.key})`;
+ }
+ return match;
+ });
+ result = result.replace(/'([^'\\]*(\\.[^'\\]*)*)'/g, (match, content) => {
+ if (content.length === 0 || content.length > 150) return match;
+ const encrypted = this.encryptString(content);
+ if (encrypted) {
+ needsDecryptor = true;
+ return `${stringDecryptor.name}(${encrypted.data},${encrypted.key})`;
+ }
+ return match;
+ });
+ }
+
+ // 2. Variable Mangling
+ if (this.settings.varMangle !== false) {
+ const varMap = new Map();
+ const localPattern = /local\s+([a-zA-Z_][a-zA-Z0-9_]*)/g;
+ let match;
+ const tempScript = script;
+
+ while ((match = localPattern.exec(tempScript)) !== null) {
+ const varName = match[1];
+ if (!varMap.has(varName) && !this.reserved.has(varName)) {
+ varMap.set(varName, this.randomILVar());
+ this.stats.varsRenamed++;
+ }
+ }
+ varMap.forEach((newName, oldName) => {
+ const regex = new RegExp(`\\b${oldName}\\b`, 'g');
+ result = result.replace(regex, newName);
+ });
+ }
+
+ // 3. Final Build
+ let output = [];
+
+ // Header (Fixed Newline)
+ output.push(`-- Protected with Prometheus Advanced | ${new Date().toISOString().split('T')[0]}`);
+
+ if (this.settings.vmWrapper !== false) {
+ const vmFunc = this.randomILVar();
+ output.push(`local ${vmFunc}=(function()`);
+
+ if (this.settings.envWrapper !== false) output.push(this.generateEnvWrapper());
+ if (this.settings.antiDebug !== false) output.push(this.generateAntiDebug());
+ if (this.settings.deadCode !== false) output.push(this.generateJunkCode(5));
+ if (needsDecryptor) output.push(stringDecryptor.code);
+
+ if (this.settings.controlFlow !== false) {
+ const condVar = this.randomILVar();
+ output.push(`local ${condVar}=${this.generateOpaquePredicate(true)};`);
+ output.push(`if ${condVar} then`);
+ output.push(result);
+
+ // Watermark INSIDE control flow
+ if (this.settings.watermark) {
+ output.push(`local ${this.randomILVar()}="Protected by Prometheus";`);
+ }
+
+ output.push('end;');
+ } else {
+ output.push(result);
+ // Watermark INSIDE wrapper
+ if (this.settings.watermark) {
+ output.push(`local ${this.randomILVar()}="Protected by Prometheus";`);
+ }
+ }
+
+ output.push(`end);return ${vmFunc}();`);
+ } else {
+ if (needsDecryptor) output.push(stringDecryptor.code);
+ output.push(result);
+ if (this.settings.watermark) {
+ output.push(`local ${this.randomILVar()}="Protected by Prometheus";`);
+ }
+ }
+
+ return output.join('\n');
+ }
+}
+
+// API Route
+app.post('/api/obfuscate', (req, res) => {
+ try {
+ const { script, settings } = req.body;
+ if (!script || typeof script !== 'string') return res.json({ success: false, error: 'No script' });
+
+ const obfuscator = new LuaObfuscator(settings || {});
+ const result = obfuscator.obfuscate(script);
+
+ res.json({ success: true, result: result });
+ } catch (error) {
+ res.json({ success: false, error: error.message });
+ }
+});
+
+// Start Server (BIND TO 0.0.0.0 for Render)
+app.listen(PORT, '0.0.0.0', () => {
+ console.log(`🚀 Prometheus running on port ${PORT}`);
+});