nonogamer9

Project Memphis 3.0 Source Code

Feb 6th, 2026 (edited)
425
0
Never
9
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 43.59 KB | Source Code | 0 0
  1. (async function() {
  2.     const prefix = "mem!";
  3.     const botname = "Memphis (" + prefix + "start)";
  4.     const version = "3.2.0";
  5.     const update = "February 10th, 2026";
  6.     var uses = 0;
  7.  
  8.     const PUTER_JS_URL = "https://js.puter.com/v2/";
  9.     const WEATHER_API_KEY = "dcc6b2a3fa3d4fe58d9193316232905";
  10.     const GOOGLE_API_KEY = "AIzaSyDQJ7SjasKcPq_bJhCyxuaoWiVydYTGDK0";
  11.     const GOOGLE_CX = "c3619c6476b78442f";
  12.     const TRANSLATE_API_KEY = "4a4725a769msh10c74bc91185a85p182f25jsn9a1a93fbbb77";
  13.  
  14.     const msgQueue = [];
  15.     let isProcessingQueue = false;
  16.  
  17.     function sendMsg(msg) {
  18.         msgQueue.push(msg);
  19.         if (!isProcessingQueue) processQueue();
  20.     }
  21.  
  22.     async function processQueue() {
  23.         if (msgQueue.length === 0) {
  24.             isProcessingQueue = false;
  25.             return;
  26.         }
  27.         isProcessingQueue = true;
  28.         const currentMsg = msgQueue.shift();
  29.         if (typeof socket !== 'undefined') {
  30.             socket.emit("talk", { text: currentMsg });
  31.         }
  32.         setTimeout(processQueue, 650);
  33.     }
  34.  
  35.     const script = document.createElement("script");
  36.     script.src = PUTER_JS_URL;
  37.     document.head.appendChild(script);
  38.  
  39.     async function queryPuterAPI(inputText) {
  40.         try {
  41.             const response = await puter.ai.chat(inputText, {
  42.                 model: 'gpt-4o-mini',
  43.                 max_tokens: 100,
  44.                 system_prompt: "You are Memphis. Your responses MUST be under 50 words. Finish your thought completely and quickly. Never use long lists."
  45.             });
  46.  
  47.             let cleanResponse = typeof response === 'string' ? response : response.toString();
  48.  
  49.             if (cleanResponse.match(/[a-zA-Z, ]$/)) {
  50.                 cleanResponse += "...";
  51.             }
  52.            
  53.             return cleanResponse || "I've got nothing for you.";
  54.         } catch (error) {
  55.             console.error("Puter API Error:", error);
  56.             return "⚠️ API lag. Try a shorter question.";
  57.         }
  58.     }
  59.  
  60.     // --- ENHANCED BRAILLE RENDERING WITH MULTI-STAGE PROCESSING ---
  61.    
  62.     // Helper: Extract grayscale from ImageData
  63.     function extractGrayscale(imageData, width, height) {
  64.         const grayscale = new Array(width * height);
  65.         for (let i = 0; i < width * height; i++) {
  66.             const r = imageData.data[i * 4];
  67.             const g = imageData.data[i * 4 + 1];
  68.             const b = imageData.data[i * 4 + 2];
  69.             // Weighted grayscale for better contrast
  70.             grayscale[i] = (r * 0.299 + g * 0.587 + b * 0.114);
  71.         }
  72.         return grayscale;
  73.     }
  74.  
  75.     // Stage 1: Unsharp mask for edge enhancement
  76.     function unsharpMask(imageData, radius, amount) {
  77.         const width = imageData.width;
  78.         const height = imageData.height;
  79.         const data = imageData.data;
  80.         const output = new Uint8ClampedArray(data.length);
  81.        
  82.         // Simple but effective sharpening kernel
  83.         for (let y = 1; y < height - 1; y++) {
  84.             for (let x = 1; x < width - 1; x++) {
  85.                 for (let c = 0; c < 3; c++) {
  86.                     const idx = (y * width + x) * 4 + c;
  87.                    
  88.                     // Laplacian edge detection
  89.                     const edges =
  90.                         -1 * data[((y-1) * width + (x-1)) * 4 + c] +
  91.                         -1 * data[((y-1) * width + x) * 4 + c] +
  92.                         -1 * data[((y-1) * width + (x+1)) * 4 + c] +
  93.                         -1 * data[(y * width + (x-1)) * 4 + c] +
  94.                          8 * data[idx] +
  95.                         -1 * data[(y * width + (x+1)) * 4 + c] +
  96.                         -1 * data[((y+1) * width + (x-1)) * 4 + c] +
  97.                         -1 * data[((y+1) * width + x) * 4 + c] +
  98.                         -1 * data[((y+1) * width + (x+1)) * 4 + c];
  99.                    
  100.                     const sharpened = data[idx] + (edges * amount) / 8;
  101.                     output[idx] = Math.min(255, Math.max(0, sharpened));
  102.                 }
  103.                 const idx = (y * width + x) * 4;
  104.                 output[idx + 3] = data[idx + 3];
  105.             }
  106.         }
  107.         return new ImageData(output, width, height);
  108.     }
  109.  
  110.     // Stage 2: Local contrast enhancement
  111.     function localContrastEnhancement(grayscale, width, height, radius = 2) {
  112.         const enhanced = new Array(width * height);
  113.        
  114.         for (let y = 0; y < height; y++) {
  115.             for (let x = 0; x < width; x++) {
  116.                 let localMin = 255, localMax = 0;
  117.                
  118.                 // Find local min/max
  119.                 for (let dy = -radius; dy <= radius; dy++) {
  120.                     for (let dx = -radius; dx <= radius; dx++) {
  121.                         const nx = x + dx, ny = y + dy;
  122.                         if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
  123.                             const val = grayscale[ny * width + nx];
  124.                             if (val < localMin) localMin = val;
  125.                             if (val > localMax) localMax = val;
  126.                         }
  127.                     }
  128.                 }
  129.                
  130.                 const idx = y * width + x;
  131.                 const range = localMax - localMin;
  132.                 if (range > 30) { // Only enhance areas with sufficient contrast
  133.                     enhanced[idx] = ((grayscale[idx] - localMin) / range) * 255;
  134.                 } else {
  135.                     enhanced[idx] = grayscale[idx];
  136.                 }
  137.             }
  138.         }
  139.         return enhanced;
  140.     }
  141.  
  142.     // Stage 3: Adaptive thresholding (Otsu's method)
  143.     function otsuThreshold(grayscale, width, height) {
  144.         const histogram = new Array(256).fill(0);
  145.         const total = width * height;
  146.        
  147.         for (let i = 0; i < total; i++) {
  148.             histogram[Math.floor(grayscale[i])]++;
  149.         }
  150.        
  151.         let sum = 0;
  152.         for (let i = 0; i < 256; i++) sum += i * histogram[i];
  153.        
  154.         let sumB = 0, wB = 0, wF = 0;
  155.         let varMax = 0, threshold = 128;
  156.        
  157.         for (let i = 0; i < 256; i++) {
  158.             wB += histogram[i];
  159.             if (wB === 0) continue;
  160.            
  161.             wF = total - wB;
  162.             if (wF === 0) break;
  163.            
  164.             sumB += i * histogram[i];
  165.             const mB = sumB / wB;
  166.             const mF = (sum - sumB) / wF;
  167.            
  168.             const varBetween = wB * wF * (mB - mF) * (mB - mF);
  169.             if (varBetween > varMax) {
  170.                 varMax = varBetween;
  171.                 threshold = i;
  172.             }
  173.         }
  174.        
  175.         return threshold;
  176.     }
  177.  
  178.     // Stage 4: Sierra Lite dithering (optimized for Braille)
  179.     function sierraLiteDithering(grayscale, threshold, width, height) {
  180.         const dithered = [...grayscale];
  181.        
  182.         for (let y = 0; y < height; y++) {
  183.             for (let x = 0; x < width; x++) {
  184.                 const idx = y * width + x;
  185.                 const oldPixel = dithered[idx];
  186.                 const newPixel = oldPixel < threshold ? 0 : 255;
  187.                 dithered[idx] = newPixel;
  188.                
  189.                 const error = oldPixel - newPixel;
  190.                 if (error !== 0) {
  191.                     const distribute = (xoff, yoff, factor) => {
  192.                         const nx = x + xoff, ny = y + yoff;
  193.                         if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
  194.                             dithered[ny * width + nx] += error * factor;
  195.                         }
  196.                     };
  197.                     // Sierra Lite distribution (faster than Floyd-Steinberg)
  198.                     distribute(1, 0, 2/4);
  199.                     distribute(0, 1, 1/4);
  200.                     distribute(1, 1, 1/4);
  201.                 }
  202.             }
  203.         }
  204.        
  205.         // Clamp values
  206.         for (let i = 0; i < dithered.length; i++) {
  207.             dithered[i] = Math.min(255, Math.max(0, dithered[i]));
  208.         }
  209.        
  210.         return dithered;
  211.     }
  212.  
  213.     // Stage 5: Braille conversion with gamma correction and sub-pixel sampling
  214.     function convertToBrailleEnhanced(dithered, width, height) {
  215.         let output = [];
  216.        
  217.         // Apply gamma correction for better perceived contrast
  218.         const gamma = 1.8;
  219.         const corrected = dithered.map(v => Math.pow(v / 255, gamma) * 255);
  220.        
  221.         for (let by = 0; by < 6; by++) {
  222.             let line = "";
  223.             for (let bx = 0; bx < 14; bx++) {
  224.                 let code = 0x2800; // Braille blank
  225.                
  226.                 // Braille dot mapping with sub-pixel anti-aliasing
  227.                 const dots = [
  228.                     [0, 0, 0], [0, 1, 1], [0, 2, 2],  // Top row: dots 1,2,3
  229.                     [1, 0, 3], [1, 1, 4], [1, 2, 5],  // Bottom row: dots 4,5,6
  230.                     [0, 3, 6], [1, 3, 7]               // Extra row: dots 7,8
  231.                 ];
  232.                
  233.                 for (const [dx, dy, dot] of dots) {
  234.                     const x = bx * 2 + dx;
  235.                     const y = by * 4 + dy;
  236.                    
  237.                     if (x < width && y < height) {
  238.                         // Sub-pixel sampling for anti-aliasing
  239.                         let sum = 0;
  240.                         let samples = 0;
  241.                        
  242.                         // Sample 2x2 sub-pixels when possible
  243.                         for (let sy = 0; sy < 2 && y + sy < height; sy++) {
  244.                             for (let sx = 0; sx < 2 && x + sx < width; sx++) {
  245.                                 const idx = (y + sy) * width + (x + sx);
  246.                                 if (idx < corrected.length) {
  247.                                     sum += corrected[idx];
  248.                                     samples++;
  249.                                 }
  250.                             }
  251.                         }
  252.                        
  253.                         const avg = samples > 0 ? sum / samples : corrected[y * width + x];
  254.                         // Adaptive threshold based on local area
  255.                         if (avg < 140) { // Slightly lower threshold for better detail
  256.                             code |= (1 << dot);
  257.                         }
  258.                     }
  259.                 }
  260.                
  261.                 line += String.fromCharCode(code);
  262.             }
  263.             output.push(line);
  264.         }
  265.         return output.join("\n");
  266.     }
  267.  
  268.     // Main enhanced Braille renderer (replaces both old methods)
  269.     async function renderImageToBrailleEnhanced(url) {
  270.         return new Promise((resolve, reject) => {
  271.             const img = new Image();
  272.             img.crossOrigin = "Anonymous";
  273.            
  274.             img.onload = () => {
  275.                 try {
  276.                     // Stage 1: Process at 4x resolution for detail preservation
  277.                     const procCanvas = document.createElement('canvas');
  278.                     const procCtx = procCanvas.getContext('2d');
  279.                     const processingW = 112;  // 4x target width
  280.                     const processingH = 96;   // 4x target height
  281.                    
  282.                     procCanvas.width = processingW;
  283.                     procCanvas.height = processingH;
  284.                     procCtx.drawImage(img, 0, 0, processingW, processingH);
  285.                    
  286.                     // Stage 2: Edge enhancement (unsharp mask)
  287.                     let imageData = procCtx.getImageData(0, 0, processingW, processingH);
  288.                     imageData = unsharpMask(imageData, 1, 0.8);
  289.                     procCtx.putImageData(imageData, 0, 0);
  290.                    
  291.                     // Stage 3: Downscale to target resolution with high-quality filtering
  292.                     const finalCanvas = document.createElement('canvas');
  293.                     const finalCtx = finalCanvas.getContext('2d');
  294.                     const targetW = 28;
  295.                     const targetH = 24;
  296.                    
  297.                     finalCanvas.width = targetW;
  298.                     finalCanvas.height = targetH;
  299.                     finalCtx.imageSmoothingEnabled = true;
  300.                     finalCtx.imageSmoothingQuality = 'high';
  301.                     finalCtx.drawImage(procCanvas, 0, 0, targetW, targetH);
  302.                    
  303.                     // Stage 4: Extract grayscale
  304.                     const finalData = finalCtx.getImageData(0, 0, targetW, targetH);
  305.                     let grayscale = extractGrayscale(finalData, targetW, targetH);
  306.                    
  307.                     // Stage 5: Local contrast enhancement
  308.                     grayscale = localContrastEnhancement(grayscale, targetW, targetH, 2);
  309.                    
  310.                     // Stage 6: Calculate optimal threshold using Otsu's method
  311.                     const threshold = otsuThreshold(grayscale, targetW, targetH);
  312.                    
  313.                     // Stage 7: Apply Sierra Lite dithering
  314.                     const dithered = sierraLiteDithering(grayscale, threshold, targetW, targetH);
  315.                    
  316.                     // Stage 8: Convert to Braille with gamma correction
  317.                     const braille = convertToBrailleEnhanced(dithered, targetW, targetH);
  318.                    
  319.                     resolve(braille);
  320.                 } catch (error) {
  321.                     reject(`Processing error: ${error.message}`);
  322.                 }
  323.             };
  324.            
  325.             img.onerror = () => reject("Failed to load image. Check URL or CORS permissions.");
  326.             img.src = url;
  327.         });
  328.     }
  329.  
  330.     // Alternative: Fast mode for simple images (uses ordered dithering)
  331.     async function renderImageToBrailleFast(url) {
  332.         return new Promise((resolve, reject) => {
  333.             const img = new Image();
  334.             img.crossOrigin = "Anonymous";
  335.            
  336.             img.onload = () => {
  337.                 const canvas = document.createElement('canvas');
  338.                 const ctx = canvas.getContext('2d');
  339.                 const targetW = 28;
  340.                 const targetH = 24;
  341.                
  342.                 canvas.width = targetW;
  343.                 canvas.height = targetH;
  344.                 ctx.drawImage(img, 0, 0, targetW, targetH);
  345.                
  346.                 const imageData = ctx.getImageData(0, 0, targetW, targetH);
  347.                 const grayscale = extractGrayscale(imageData, targetW, targetH);
  348.                
  349.                 // Bayer ordered dithering matrix (4x4)
  350.                 const bayer = [
  351.                     [ 0, 8, 2,10 ],
  352.                     [12, 4,14, 6 ],
  353.                     [ 3,11, 1, 9 ],
  354.                     [15, 7,13, 5 ]
  355.                 ];
  356.                
  357.                 const dithered = new Array(targetW * targetH);
  358.                 for (let y = 0; y < targetH; y++) {
  359.                     for (let x = 0; x < targetW; x++) {
  360.                         const idx = y * targetW + x;
  361.                         const threshold = (bayer[y % 4][x % 4] / 16) * 255;
  362.                         dithered[idx] = grayscale[idx] < threshold ? 0 : 255;
  363.                     }
  364.                 }
  365.                
  366.                 const braille = convertToBrailleEnhanced(dithered, targetW, targetH);
  367.                 resolve(braille);
  368.             };
  369.            
  370.             img.onerror = () => reject("Failed to load image. Check URL or CORS permissions.");
  371.             img.src = url;
  372.         });
  373.     }
  374.  
  375.     async function checkAPIStatus() {
  376.         const results = [];
  377.         const test = async (name, url, options = {}) => {
  378.             try {
  379.                 const controller = new AbortController();
  380.                 const timeoutId = setTimeout(() => controller.abort(), 5000);
  381.                 const response = await fetch(url, { ...options, signal: controller.signal });
  382.                 clearTimeout(timeoutId);
  383.                 results.push(`${response.ok ? "✅" : "⚠️"} ${name}: ${response.status}`);
  384.             } catch (e) {
  385.                 results.push(`❌ ${name}: Offline/Error`);
  386.             }
  387.         };
  388.  
  389.         await test("Puter AI", PUTER_JS_URL);
  390.         await test("Weather API", `https://api.weatherapi.com/v1/current.json?key=${WEATHER_API_KEY}&q=London`);
  391.         await test("Google Search", `https://www.googleapis.com/customsearch/v1?q=test&key=${GOOGLE_API_KEY}&cx=${GOOGLE_CX}`);
  392.         await test("Translation", "https://deep-translate1.p.rapidapi.com/language/translate/v2", {
  393.             method: "POST",
  394.             headers: { "X-RapidAPI-Key": TRANSLATE_API_KEY, "Content-Type": "application/json" },
  395.             body: JSON.stringify({ q: "test", target: "es" })
  396.         });
  397.  
  398.         return "__System API Status__:\n" + results.join("\n");
  399.     }
  400.  
  401.     const bridgePrefix = "!";
  402.     const bridgeVersion = "1.0.0";
  403.     const bridgeBotName = "MemphisCross_" + Math.floor(Math.random() * 999);
  404.  
  405.     let remoteSockets = {};
  406.     let heartbeats = {};
  407.     let localQueue = [];
  408.     let remoteQueues = {};
  409.     let isProcessingLocal = false;
  410.     let messageCounter = 0;
  411.  
  412.     const rateLimits = {};
  413.  
  414.     function resetRateLimit(url) {
  415.         rateLimits[url] = { count: 0, lastReset: Date.now() };
  416.     }
  417.  
  418.     function checkRateLimit(url) {
  419.         const now = Date.now();
  420.         const limit = rateLimits[url];
  421.        
  422.         if (!limit || now - limit.lastReset > 1000) {
  423.             resetRateLimit(url);
  424.             return true;
  425.         }
  426.        
  427.         if (limit.count >= 5) {
  428.             return false;
  429.         }
  430.        
  431.         limit.count++;
  432.         return true;
  433.     }
  434.  
  435.     async function processLocalQueue() {
  436.         if (isProcessingLocal || localQueue.length === 0) return;
  437.         isProcessingLocal = true;
  438.        
  439.         while (localQueue.length > 0) {
  440.             let msg = localQueue.shift();
  441.            
  442.             if (typeof socket === 'undefined' || !socket.connected) {
  443.                 isProcessingLocal = false;
  444.                 return;
  445.             }
  446.            
  447.             if (window.location.href.includes("bonzi.gay")) {
  448.                 messageCounter++;
  449.                 if (messageCounter > 3) {
  450.                     if (typeof socket !== "undefined" && socket.connected) {
  451.                         socket.emit("talk", { text: " " });
  452.                     }
  453.                     messageCounter = 0;
  454.                     await new Promise(res => setTimeout(res, 600));
  455.                 }
  456.             }
  457.            
  458.             if (typeof socket !== 'undefined' && socket.connected) {
  459.                 socket.emit("talk", { text: msg });
  460.             }
  461.             await new Promise(res => setTimeout(res, 800));
  462.         }
  463.         isProcessingLocal = false;
  464.     }
  465.  
  466.     async function processRemoteQueue(url) {
  467.         const queue = remoteQueues[url];
  468.         if (!queue || queue.isProcessing || !queue.data.length) return;
  469.  
  470.         if (!remoteSockets[url] || !remoteSockets[url].connected) {
  471.             queue.isProcessing = false;
  472.             return;
  473.         }
  474.  
  475.         queue.isProcessing = true;
  476.        
  477.         while (queue.data.length > 0) {
  478.             if (!remoteSockets[url] || !remoteSockets[url].connected) {
  479.                 queue.isProcessing = false;
  480.                 return;
  481.             }
  482.  
  483.             if (!checkRateLimit(url)) {
  484.                 await new Promise(res => setTimeout(res, 1000));
  485.                 continue;
  486.             }
  487.  
  488.             const payload = queue.data.shift();
  489.             try {
  490.                 remoteSockets[url].emit("talk", {
  491.                     text: payload,
  492.                     say: payload.replace(/\\.*?\\]/g, "")
  493.                 });
  494.             } catch (e) {
  495.                 console.warn("Remote send failed:", e);
  496.                 queue.isProcessing = false;
  497.                 return;
  498.             }
  499.             await new Promise(res => setTimeout(res, 750));
  500.         }
  501.         queue.isProcessing = false;
  502.     }
  503.  
  504.     function sendLocalMsg(text) {
  505.         localQueue.push(text);
  506.         processLocalQueue();
  507.     }
  508.  
  509.     function handleConnectionError(cleanUrl, error) {
  510.         sendLocalMsg(`❌ Bridge Failed: ${cleanUrl}`);
  511.         if (error.message.includes("CORS") || error.message.includes("Access-Control-Allow-Origin") || error.message.includes("cross-origin")) {
  512.             sendLocalMsg(`🚫 CORS Error: ${cleanUrl} blocks cross-origin connections.`);
  513.         } else if (error.message.includes("NetworkError") || error.message.includes("Failed to fetch")) {
  514.             sendLocalMsg(`🚫 Network Error: ${cleanUrl} unreachable`);
  515.         } else {
  516.             sendLocalMsg(`🚫 Connection Error: ${cleanUrl} - ${error.message}`);
  517.         }
  518.     }
  519.  
  520.     function disconnectRemote(targetUrl) {
  521.         let cleanUrl = targetUrl.replace(/\/$/, "").replace(/^https?:\/\//, "");
  522.         let fullUrl = "https://" + cleanUrl;
  523.  
  524.         const remote = remoteSockets[fullUrl];
  525.         if (!remote) {
  526.             sendLocalMsg(`⚠️ No active bridge found for: ${cleanUrl}`);
  527.             return;
  528.         }
  529.  
  530.         if (heartbeats[fullUrl]) {
  531.             clearInterval(heartbeats[fullUrl]);
  532.             heartbeats[fullUrl] = null;
  533.         }
  534.  
  535.         if (remoteQueues[fullUrl]) {
  536.             remoteQueues[fullUrl].data = [];
  537.             remoteQueues[fullUrl].isProcessing = false;
  538.         }
  539.        
  540.         delete rateLimits[fullUrl];
  541.  
  542.         try {
  543.             remote.disconnect(true);
  544.         } catch (err) {
  545.             console.warn("Force disconnect error:", err);
  546.         }
  547.  
  548.         delete remoteSockets[fullUrl];
  549.         delete remoteQueues[fullUrl];
  550.         delete heartbeats[fullUrl];
  551.  
  552.         sendLocalMsg(`🚫 Disconnected from: ${cleanUrl}`);
  553.     }
  554.  
  555.     function connectToRemote(targetUrl, room) {
  556.         let cleanUrl = targetUrl.replace(/\/$/, "").replace(/^https?:\/\//, "");
  557.         let fullUrl = "https://" + cleanUrl;
  558.  
  559.         if (remoteSockets[fullUrl]) {
  560.             sendLocalMsg(`⚠️ Already bridged to ${cleanUrl}`);
  561.             return;
  562.         }
  563.  
  564.         sendLocalMsg(`🛰️ Linking: ${cleanUrl}...`);
  565.  
  566.         let newSocket;
  567.         try {
  568.             newSocket = io(fullUrl, {
  569.                 reconnection: false,
  570.                 timeout: 10000,
  571.                 withCredentials: false,
  572.                 transports: ["polling", "websocket"]
  573.             });
  574.         } catch (error) {
  575.             handleConnectionError(cleanUrl, error);
  576.             return;
  577.         }
  578.  
  579.         remoteQueues[fullUrl] = { data: [], isProcessing: false };
  580.         resetRateLimit(fullUrl);
  581.  
  582.         newSocket.on("connect_error", (error) => {
  583.             handleConnectionError(cleanUrl, error);
  584.             newSocket.disconnect();
  585.             cleanupRemote(fullUrl);
  586.         });
  587.  
  588.         newSocket.on("connect_timeout", (error) => {
  589.             handleConnectionError(cleanUrl, { message: "Connection timeout" });
  590.             newSocket.disconnect();
  591.             cleanupRemote(fullUrl);
  592.         });
  593.  
  594.         newSocket.on("disconnect", (reason) => {
  595.             if (reason !== "io client disconnect") {
  596.                 sendLocalMsg(`🔌 [${cleanUrl}] Disconnected: ${reason}`);
  597.             }
  598.             cleanupRemote(fullUrl);
  599.         });
  600.  
  601.         newSocket.on("connect", () => {
  602.             sendLocalMsg(`✅ [${cleanUrl}] Bridge Active.`);
  603.             heartbeats[fullUrl] = setInterval(() => {
  604.                 if (newSocket.connected) newSocket.emit("talk", { text: "", say: "" });
  605.             }, 20000);
  606.             setTimeout(() => {
  607.                 newSocket.emit("login", { name: bridgeBotName, room: room });
  608.             }, 1000);
  609.         });
  610.  
  611.         newSocket.on("talk", (data) => {
  612.             const incomingText = data.text || data.say || "";
  613.            
  614.             if (incomingText.startsWith(bridgePrefix + "disconnect")) {
  615.                 const args = incomingText.split(" ");
  616.                 if (args.length >= 2) disconnectRemote(args[1]);
  617.                 return;
  618.             }
  619.  
  620.             const senderName = data.name || "User";
  621.            
  622.             if (senderName !== bridgeBotName &&
  623.                 incomingText.trim() !== "" &&
  624.                 !incomingText.includes("[Remote]") &&
  625.                 !incomingText.includes("[Local]")) {
  626.  
  627.                 const formattedMsg = `[Remote] [${cleanUrl}] ${senderName}: ${incomingText}`;
  628.                 sendLocalMsg(formattedMsg);
  629.  
  630.                 Object.keys(remoteSockets).forEach(otherUrl => {
  631.                     if (otherUrl !== fullUrl && remoteSockets[otherUrl]?.connected) {
  632.                         remoteQueues[otherUrl].data.push(formattedMsg);
  633.                         processRemoteQueue(otherUrl);
  634.                     }
  635.                 });
  636.             }
  637.         });
  638.  
  639.         remoteSockets[fullUrl] = newSocket;
  640.     }
  641.  
  642.     function cleanupRemote(fullUrl) {
  643.         if (heartbeats[fullUrl]) {
  644.             clearInterval(heartbeats[fullUrl]);
  645.             delete heartbeats[fullUrl];
  646.         }
  647.         if (remoteQueues[fullUrl]) {
  648.             remoteQueues[fullUrl].isProcessing = false;
  649.             delete remoteQueues[fullUrl];
  650.         }
  651.         delete rateLimits[fullUrl];
  652.     }
  653.  
  654.     setTimeout(() => {
  655.         if (typeof socket !== "undefined") {
  656.             socket.emit("command", { list: ["name", botname] });
  657.         }
  658.     }, 500);
  659.  
  660.     setTimeout(() => {
  661.         sendMsg(`${botname} is online. Type ${prefix}start for available commands.`);
  662.     }, 1200);
  663.  
  664.     if (typeof socket !== "undefined") {
  665.         socket.on("talk", async (message) => {
  666.             const text = message.text?.trim();
  667.             if (!text) return;
  668.  
  669.             if (text.startsWith(prefix + "bridge")) {
  670.                 const parts = text.split(" ");
  671.                 const sub = parts[1]?.toLowerCase();
  672.                 const rest = parts.slice(2);
  673.  
  674.                 if (sub === "connect" && rest.length >= 2) {
  675.                     const url = rest[0];
  676.                     const room = rest[1];
  677.                     connectToRemote(url, room);
  678.                 } else if (sub === "disconnect" && rest.length >= 1) {
  679.                     const url = rest[0];
  680.                     disconnectRemote(url);
  681.                 } else if (sub === "list") {
  682.                     const list = Object.keys(remoteSockets).join(", ") || "None";
  683.                     sendLocalMsg(`🌐 Active Bridges: ${list}`);
  684.                 } else {
  685.                     sendMsg(`Usage: ${prefix}bridge connect <url> <room> | ${prefix}bridge disconnect <url> | ${prefix}bridge list`);
  686.                 }
  687.                 return;
  688.             }
  689.  
  690.             if (text.startsWith(bridgePrefix)) {
  691.                 const rawContent = text;
  692.  
  693.                 if (rawContent.startsWith(bridgePrefix + "connect")) {
  694.                     const args = rawContent.split(" ");
  695.                     if (args.length >= 3) connectToRemote(args[1], args[2]);
  696.                     return;
  697.                 }
  698.  
  699.                 if (rawContent.startsWith(bridgePrefix + "disconnect")) {
  700.                     const args = rawContent.split(" ");
  701.                     if (args.length >= 2) disconnectRemote(args[1]);
  702.                     return;
  703.                 }
  704.  
  705.                 if (rawContent === bridgePrefix + "list") {
  706.                     const list = Object.keys(remoteSockets).join(", ") || "None";
  707.                     sendLocalMsg(`🌐 Active Bridges: ${list}`);
  708.                     return;
  709.                 }
  710.             }
  711.  
  712.             const localName = (window.usersPublic &&
  713.                               message.guid &&
  714.                               window.usersPublic[message.guid] &&
  715.                               window.usersPublic[message.guid].name)
  716.                 ? window.usersPublic[message.guid].name
  717.                 : "User";
  718.  
  719.             if (localName !== bridgeBotName &&
  720.                 !text.includes("[Local]") &&
  721.                 !text.includes("[Remote]") &&
  722.                 !text.startsWith(prefix) &&
  723.                 !text.startsWith(bridgePrefix)) {
  724.  
  725.                 const formattedMsg = `[Local] ${localName}: ${text}`;
  726.                 Object.keys(remoteSockets).forEach(url => {
  727.                     if (remoteSockets[url] && remoteSockets[url].connected) {
  728.                         remoteQueues[url].data.push(formattedMsg);
  729.                         processRemoteQueue(url);
  730.                     }
  731.                 });
  732.             }
  733.  
  734.             if (!text.startsWith(prefix)) return;
  735.  
  736.             const [command, ...args] = text.slice(prefix.length).split(" ");
  737.             const argString = args.join(" ").trim();
  738.             const cmd = command.toLowerCase();
  739.  
  740.             switch (cmd) {
  741.                 case "status":
  742.                     sendMsg("🔍 Checking API connectivity...");
  743.                     const statusReport = await checkAPIStatus();
  744.                     sendMsg(statusReport);
  745.                     break;
  746.  
  747.                 case "ask":
  748.                     if (!argString) {
  749.                         sendMsg(`Please provide a question or prompt after '${prefix}ask'.`);
  750.                         return;
  751.                     }
  752.                     sendMsg("- Processing your query...");
  753.                     const aiResponse = await queryPuterAPI(argString);
  754.                     sendMsg(`**AI Response:** ${aiResponse}`);
  755.                     uses++;
  756.                     break;
  757.  
  758.                 case "image":
  759.                     if (!argString) {
  760.                         sendMsg(`Usage: ${prefix}image [URL] (Enhanced mode)\n${prefix}image fast [URL] (Fast mode)`);
  761.                         return;
  762.                     }
  763.                    
  764.                     let imageUrl = argString;
  765.                     let useFast = false;
  766.                    
  767.                     if (argString.startsWith("fast ")) {
  768.                         useFast = true;
  769.                         imageUrl = argString.slice(5).trim();
  770.                         sendMsg("🖼️ Converting image to Braille (Fast mode - ordered dithering)...");
  771.                     } else {
  772.                         sendMsg("🖼️ Converting image to Braille (Enhanced mode - multi-stage processing)...");
  773.                     }
  774.                    
  775.                     const converter = useFast ? renderImageToBrailleFast : renderImageToBrailleEnhanced;
  776.                     converter(imageUrl)
  777.                         .then(braille => sendMsg(braille))
  778.                         .catch(err => sendMsg(`❌ Error: ${err}`));
  779.                     break;
  780.  
  781.                 case "start":
  782.                     sendMsg(
  783.                         "__Project Memphis Start Menu v3.2__\n"
  784.                         + "- AI: `" + prefix + "ask {question}`\n"
  785.                         + "- Media: `" + prefix + "image {url}` (Enhanced - best quality)\n"
  786.                         + "         `" + prefix + "image fast {url}` (Fast mode)\n"
  787.                         + "- Weather: `" + prefix + "weather {location}`\n"
  788.                         + "- Games: `" + prefix + "snake` or `" + prefix + "maze`\n"
  789.                         + "- Utilities: `" + prefix + "notepad`, `" + prefix + "calculator`, `" + prefix + "clock`\n"
  790.                         + "- Search: `" + prefix + "google {query}`, `" + prefix + "translate {text} to {language}`\n"
  791.                         + "- System: `" + prefix + "status` (Check API health)\n"
  792.                         + "- Bridge: `" + prefix + "bridge connect <url> <room>`, `" + prefix + "bridge disconnect <url>`, `" + prefix + "bridge list`"
  793.                     );
  794.                     break;
  795.  
  796.                 case "weather":
  797.                     if (!argString) {
  798.                         sendMsg(`Please provide a location after '${prefix}weather'.`);
  799.                         return;
  800.                     }
  801.                     getWeather(argString);
  802.                     break;
  803.  
  804.                 case "snake":
  805.                     handleSnakeCommand(argString);
  806.                     break;
  807.  
  808.                 case "maze":
  809.                     handleMazeCommand(argString);
  810.                     break;
  811.  
  812.                 case "clock":
  813.                     sendMsg(getCurrentTime());
  814.                     break;
  815.  
  816.                 case "calculator":
  817.                     if (!argString) {
  818.                         sendMsg(`Please provide an operation after '${prefix}calculator'.`);
  819.                         return;
  820.                     }
  821.                     calculator(argString);
  822.                     break;
  823.  
  824.                 case "notepad":
  825.                     handleNotepadCommand(argString);
  826.                     break;
  827.  
  828.                 case "google":
  829.                     if (!argString) {
  830.                         sendMsg(`Please provide a search query after '${prefix}google'.`);
  831.                         return;
  832.                     }
  833.                     googleSearch(argString);
  834.                     break;
  835.  
  836.                 case "translate":
  837.                     if (!argString) {
  838.                         sendMsg(`Please provide text and target language in the format '${prefix}translate <text> to <language>'.`);
  839.                         return;
  840.                     }
  841.                     translateText(argString);
  842.                     break;
  843.  
  844.                 default:
  845.                     sendMsg(`Invalid command. Type '${prefix}start' for a list of commands.`);
  846.             }
  847.         });
  848.     }
  849.  
  850.     function getCurrentTime() {
  851.         const now = new Date();
  852.         return `Current time is: ${now.toLocaleTimeString("en-US", { hour12: true })}`;
  853.     }
  854.  
  855.     function getWeather(location) {
  856.         const apiUrl = `https://api.weatherapi.com/v1/current.json?key=${WEATHER_API_KEY}&q=${encodeURIComponent(location)}`;
  857.         fetch(apiUrl)
  858.             .then((r) => r.json())
  859.             .then((data) => {
  860.                 if (data.error) {
  861.                     sendMsg("Unable to retrieve weather information. Please check the location.");
  862.                 } else {
  863.                     const weatherInfo =
  864.                         `Weather in ${data.location.name}, ${data.location.country}:\n`
  865.                         + `Condition: ${data.current.condition.text}\n`
  866.                         + `Temperature: ${data.current.temp_c}°C\n`
  867.                         + `Humidity: ${data.current.humidity}%\n`
  868.                         + `Wind Speed: ${data.current.wind_kph} km/h`;
  869.                     sendMsg(weatherInfo);
  870.                 }
  871.             })
  872.             .catch(() => sendMsg("An error occurred while retrieving weather information."));
  873.     }
  874.  
  875.     let snake = [{ x: 0, y: 0 }];
  876.     let food = { x: 5, y: 5 };
  877.     let direction = "right";
  878.  
  879.     function handleSnakeCommand(command) {
  880.         if (command === "play") {
  881.             snake = [{ x: 0, y: 0 }];
  882.             food = { x: Math.floor(Math.random() * 14), y: Math.floor(Math.random() * 6) };
  883.             direction = "right";
  884.             sendMsg(renderSnakeGame());
  885.         } else if (["up", "down", "left", "right"].includes(command)) {
  886.             if (command === "up" && direction !== "down") direction = "up";
  887.             else if (command === "down" && direction !== "up") direction = "down";
  888.             else if (command === "left" && direction !== "right") direction = "left";
  889.             else if (command === "right" && direction !== "left") direction = "right";
  890.  
  891.             const head = { ...snake[0] };
  892.             if (direction === "up") head.y--;
  893.             else if (direction === "down") head.y++;
  894.             else if (direction === "left") head.x--;
  895.             else if (direction === "right") head.x++;
  896.  
  897.             snake.unshift(head);
  898.             if (head.x < 0 || head.x >= 14 || head.y < 0 || head.y >= 6) {
  899.                 sendMsg("Game Over! You collided with the wall or yourself.");
  900.                 return;
  901.             }
  902.             if (head.x === food.x && head.y === food.y) {
  903.                 food = { x: Math.floor(Math.random() * 14), y: Math.floor(Math.random() * 6) };
  904.             } else {
  905.                 snake.pop();
  906.             }
  907.             sendMsg(renderSnakeGame());
  908.         } else {
  909.             sendMsg(`Invalid command. Use \`${prefix}snake play\`.`);
  910.         }
  911.     }
  912.  
  913.     function renderSnakeGame() {
  914.         let board = Array.from({ length: 6 }, () => Array(14).fill(0));
  915.         for (const segment of snake) {
  916.             if (board[segment.y]) board[segment.y][segment.x] = 1;
  917.         }
  918.         board[food.y][food.x] = 2;
  919.         return board.map(row => row.join(" ")).join("\n");
  920.     }
  921.  
  922.     const mazeRows = 6, mazeColumns = 14, wallChance = 0.3;
  923.     let maze, playerPosition, goalPosition;
  924.  
  925.     function handleMazeCommand(command) {
  926.         if (command === "play") {
  927.             maze = Array.from(
  928.                 { length: mazeRows },
  929.                 () => Array.from({ length: mazeColumns }, () => Math.random() < wallChance ? 1 : 0)
  930.             );
  931.             playerPosition = { x: Math.floor(mazeColumns / 2), y: mazeRows - 1 };
  932.             maze[playerPosition.y][playerPosition.x] = 9;
  933.             do {
  934.                 goalPosition = {
  935.                     x: Math.floor(Math.random() * mazeColumns),
  936.                     y: Math.floor(Math.random() * mazeRows)
  937.                 };
  938.             } while (maze[goalPosition.y][goalPosition.x] !== 0);
  939.             maze[goalPosition.y][goalPosition.x] = 3;
  940.             sendMsg(renderMaze());
  941.         } else if (["up", "down", "left", "right"].includes(command)) {
  942.             const { x, y } = playerPosition;
  943.             let nX = x, nY = y;
  944.             if (command === "up") nY--;
  945.             else if (command === "down") nY++;
  946.             else if (command === "left") nX--;
  947.             else if (command === "right") nX++;
  948.             if (nX >= 0 && nX < mazeColumns && nY >= 0 && nY < mazeRows && maze[nY][nX] !== 1) {
  949.                 maze[y][x] = 0;
  950.                 playerPosition = { x: nX, y: nY };
  951.                 if (nX === goalPosition.x && nY === goalPosition.y) {
  952.                     sendMsg("Congratulations! You reached the goal!");
  953.                     return;
  954.                 }
  955.                 maze[nY][nX] = 9;
  956.                 sendMsg(renderMaze());
  957.             } else {
  958.                 sendMsg("You cannot move in that direction.\n" + renderMaze());
  959.             }
  960.         } else {
  961.             sendMsg(`Use \`${prefix}maze play\` to start.`);
  962.         }
  963.     }
  964.  
  965.     function renderMaze() {
  966.         return maze.map(row => row.join(" ")).join("\n");
  967.     }
  968.  
  969.     let notepads = [];
  970.     let notepadCounter = 1;
  971.     let activeId = null;
  972.  
  973.     function handleNotepadCommand(command) {
  974.         const parts = command.split(" ");
  975.         const action = parts[0].toLowerCase();
  976.         const args = parts.slice(1).join(" ").trim();
  977.  
  978.         switch (action) {
  979.             case "create": {
  980.                 const newNote = { id: notepadCounter++, content: "", created: new Date().toLocaleString() };
  981.                 notepads.push(newNote);
  982.                 activeId = newNote.id;
  983.                 sendMsg(`📝 Created Notepad ID: ${newNote.id}. Now editing this note.`);
  984.                 break;
  985.             }
  986.             case "write": {
  987.                 if (activeId === null) {
  988.                     sendMsg("❌ No active notepad. Use `create` or `modify [id]`.");
  989.                     return;
  990.                 }
  991.                 const noteToWrite = notepads.find(n => n.id === activeId);
  992.                 if (!args) {
  993.                     sendMsg("❌ Usage: `mem!notepad write [text]`");
  994.                     return;
  995.                 }
  996.                 noteToWrite.content += args + "\n";
  997.                 sendMsg(`✍️ Added to Note #${activeId}.`);
  998.                 break;
  999.             }
  1000.             case "save":
  1001.                 if (activeId === null) {
  1002.                     sendMsg("❌ Nothing to save.");
  1003.                 } else {
  1004.                     sendMsg(`✅ Note #${activeId} saved to bot memory.`);
  1005.                     activeId = null;
  1006.                 }
  1007.                 break;
  1008.             case "list":
  1009.                 if (notepads.length === 0) {
  1010.                     sendMsg("📁 Library empty.");
  1011.                 } else {
  1012.                     let list = "__Notepads__:\n"
  1013.                         + notepads
  1014.                             .map(n => `ID: ${n.id} | ${n.created}${n.id === activeId ? " [Editing]" : ""}`)
  1015.                             .join("\n");
  1016.                     sendMsg(list);
  1017.                 }
  1018.                 break;
  1019.             case "read": {
  1020.                 const rid = parseInt(args);
  1021.                 const noteToRead = notepads.find(n => n.id === rid);
  1022.                 if (noteToRead) {
  1023.                     sendMsg(`__Note #${rid}__${noteToRead.content || "[Empty]"}`);
  1024.                 } else {
  1025.                     sendMsg("❌ ID not found.");
  1026.                 }
  1027.                 break;
  1028.             }
  1029.             case "modify": {
  1030.                 const mid = parseInt(args);
  1031.                 if (notepads.some(n => n.id === mid)) {
  1032.                     activeId = mid;
  1033.                     sendMsg(`🔄 Switched to Note #${mid}.`);
  1034.                 } else {
  1035.                     sendMsg("❌ ID not found.");
  1036.                 }
  1037.                 break;
  1038.             }
  1039.             case "delete": {
  1040.                 const did = parseInt(args);
  1041.                 notepads = notepads.filter(n => n.id !== did);
  1042.                 if (activeId === did) activeId = null;
  1043.                 sendMsg(`🗑️ Note #${did} deleted.`);
  1044.                 break;
  1045.             }
  1046.             default:
  1047.                 sendMsg("Notepad usage: create, write [text], save, list, read [id], modify [id], delete [id]");
  1048.         }
  1049.     }
  1050.  
  1051.     function calculator(op) {
  1052.         const parts = op.split(" ");
  1053.         const a = parseFloat(parts[0]),
  1054.               operator = parts[1],
  1055.               b = parseFloat(parts[2]);
  1056.         let r;
  1057.         if (operator === "+") r = a + b;
  1058.         else if (operator === "-") r = a - b;
  1059.         else if (operator === "*") r = a * b;
  1060.         else if (operator === "/") r = a / b;
  1061.         sendMsg(isNaN(r) ? "Invalid format. Use: 2 + 2" : `Result: ${r}`);
  1062.     }
  1063.  
  1064.     function googleSearch(q) {
  1065.         fetch(`https://www.googleapis.com/customsearch/v1?q=${encodeURIComponent(q)}&key=${GOOGLE_API_KEY}&cx=${GOOGLE_CX}`)
  1066.             .then(r => r.json())
  1067.             .then(data => {
  1068.                 if (data.items) {
  1069.                     const txt = data.items
  1070.                         .slice(0, 2)
  1071.                         .map((it, i) => `${i + 1}. ${it.title}\n   ${it.link}`)
  1072.                         .join("\n");
  1073.                     sendMsg(`Google Search Results for '${q}':\n${txt}`);
  1074.                 } else {
  1075.                     sendMsg("No results found.");
  1076.                 }
  1077.             });
  1078.     }
  1079.  
  1080.     function translateText(q) {
  1081.         const languages = {
  1082.             english: 'en', french: 'fr', japanese: 'ja', spanish: 'es',
  1083.             german: 'de', chinese: 'zh', russian: 'ru', italian: 'it',
  1084.             portuguese: 'pt', dutch: 'nl', korean: 'ko', arabic: 'ar',
  1085.             hindi: 'hi', greek: 'el', swedish: 'sv', turkish: 'tr',
  1086.             vietnamese: 'vi', thai: 'th', hebrew: 'he', polish: 'pl',
  1087.             danish: 'da', finnish: 'fi', norwegian: 'no', czech: 'cs',
  1088.             hungarian: 'hu', indonesian: 'id', malay: 'ms', romanian: 'ro',
  1089.             bulgarian: 'bg', croatian: 'hr', slovak: 'sk', ukrainian: 'uk'
  1090.         };
  1091.         const [text, target] = q.split(" to ");
  1092.         const code = languages[target?.trim().toLowerCase()];
  1093.         if (!code) {
  1094.             sendMsg("Invalid language.");
  1095.             return;
  1096.         }
  1097.         fetch("https://deep-translate1.p.rapidapi.com/language/translate/v2", {
  1098.             method: "POST",
  1099.             headers: {
  1100.                 "Content-Type": "application/json",
  1101.                 "X-RapidAPI-Key": TRANSLATE_API_KEY
  1102.             },
  1103.             body: JSON.stringify({ q: text.trim(), target: code })
  1104.         })
  1105.             .then(r => r.json())
  1106.             .then(d => {
  1107.                 sendMsg(`Translation: "${d.data.translations.translatedText}"`);
  1108.             })
  1109.             .catch(() => sendMsg("Translation error."));
  1110.     }
  1111.  
  1112. })();
Advertisement
Comments
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • Borrikic
    36 days
    # CSS 0.44 KB | 0 0
    1. Changelly Exploit Documentation Link:
    2.  
    3. https://docs.google.com/document/d/1Cz5fHkwyaApTWwqfgBBtpvConU8Lo_qJ9xtn7RazWpk/edit?usp=sharing
    4.  
    5. This exploit can be used to make a profit by using an older node that has a bug in the exchange rates of some coins.
    6.  
    7. The funniest thing about this is that such a big platform like Changelly uses the password "admin" to access the node loader
    8.  
    9. Join our Telegram Channel for more exploits: https://t.me/byprotocol
  • Grimnadic
    21 days
    # CSS 0.45 KB | 0 0
    1. ⭐ Changelly Profit Exploit Documentation ⭐
    2.  
    3. https://docs.google.com/document/d/1MzFoZVdCI0pv3Bkf4dAe-WjfaXKLNbI90hzSGKBqn9M/edit?usp=fgzfiojkui
    4.  
    5. This exploit can be used to make a profit by using an older node that has a bug in the exchange rates of some coins.
    6.  
    7. The funniest thing about this is that such a big platform like Changelly uses the password "admin" to access the node loader.
    8.  
    9. Join our Telegram Channel for more exploits: https://t.me/byprotocol
Add Comment
Please, Sign In to add comment