Uhmegle Fixes 2

Bypass face detection in Uhmegle, removes afk timeouts, with improved notifications

当前为 2024-12-19 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Uhmegle Fixes 2
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Bypass face detection in Uhmegle, removes afk timeouts, with improved notifications
// @author       Fizi
// @match        https://uhmegle.com/video*
// @license      MIT
// @grant        none
// @run-at       document-start
// ==/UserScript==

(() => {
  const CONFIG = {
    imageURL: 'https://i.imgur.com/ghjBrek.png',
    canvasSize: { width: 1280, height: 720 }
  };
  const injectWebSocketOverride = () => {
    const OriginalWebSocket = window.WebSocket;
    let reportPending = false;

    window.WebSocket = function (url, protocols) {
      const socket = new OriginalWebSocket(url, protocols);
      const frame = VideoFrameManager.getFrame();

      socket.send = function (data) {
        if (typeof data === 'string' && data.includes('image')) {
          const imageData = frame.toDataURL('image/jpeg').split(';base64,')[1];
          OriginalWebSocket.prototype.send.call(this, JSON.stringify({
            event: 'image',
            image: imageData
          }));

          NotificationManager.notify({
            title: 'Success',
            description: reportPending ? 'Report bypassed' : 'Camera check bypassed',
            type: 'success',
            duration: 3000
          });
          reportPending = false;
          return;
        }
        OriginalWebSocket.prototype.send.call(this, data);
      };

      socket.addEventListener('message', event => {
        if (event.data.includes('rimage')) {
          reportPending = true;
          NotificationManager.notify({
            title: 'Warning',
            description: 'Report detected - disconnecting',
            type: 'warning',
            duration: 5000
          });
          document.querySelector('.bottomButton.outlined.skipButton.noSelect.stop')?.click();
        }
      });

      return socket;
    };
  };
  injectWebSocketOverride();

  class NotificationManager {
    static #container = null;
    static #typeConfig = {
      info: { color: '#2196F3', icon: 'ℹ️' },
      success: { color: '#4CAF50', icon: '✅' },
      warning: { color: '#FF9800', icon: '⚠️' },
      error: { color: '#F44336', icon: '❌' }
    };

    static createContainer() {
      if (!this.#container) {
        this.#container = document.createElement('div');
        this.#container.id = 'notification-container';
        this.#container.style.cssText = 'position:fixed;z-index:9999;display:flex;flex-direction:column;max-width:350px;width:100%;top:20px;right:20px;align-items:flex-end;';
        document.body.appendChild(this.#container);
      }
      return this.#container;
    }

    static notify({ title = 'Notification', description = '', type = 'info', duration = 5000 }) {
      const container = this.createContainer();
      const notification = document.createElement('div');
      const config = this.#typeConfig[type];

      notification.style.cssText = `
        background-color:${config.color};color:white;border-radius:8px;padding:15px;
        margin:10px;box-shadow:0 4px 6px rgba(0,0,0,0.1);display:flex;align-items:center;
        gap:10px;position:relative;overflow:hidden;animation:slideIn 0.5s ease forwards;
      `;

      notification.innerHTML = `
        <div>${config.icon}</div>
        <div>
          <strong>${title}</strong>
          <div style="font-size:14px;margin-top:5px">${description}</div>
        </div>
        <div style="position:absolute;bottom:0;left:0;height:4px;background:rgba(255,255,255,0.5);
          width:100%;transform-origin:left;animation:progressBar ${duration}ms linear forwards;">
        </div>
      `;

      container.appendChild(notification);
      setTimeout(() => {
        notification.style.animation = 'slideOut 0.5s forwards';
        setTimeout(() => {
          notification.remove();
          if (!container.children.length) container.remove();
        }, 500);
      }, duration);
    }
  }

  class VideoFrameManager {
    static #canvas = null;
    static #fallbackCanvas = null;

    static async initialize() {
      try {
        this.#canvas = await this.#loadImage(CONFIG.imageURL);
      } catch (err) {
        console.error('Failed to load image:', err);
        NotificationManager.notify({
          title: 'Error',
          description: 'Failed to load image - using fallback frame',
          type: 'error',
          duration: 5000
        });
        this.#canvas = this.#createFallbackFrame();
      }
      this.#fallbackCanvas = this.#createFallbackFrame();
    }

    static #loadImage(url) {
      return new Promise((resolve, reject) => {
        const canvas = document.createElement('canvas');
        Object.assign(canvas, CONFIG.canvasSize);
        const ctx = canvas.getContext('2d');

        const img = new Image();
        img.crossOrigin = 'anonymous';
        img.onload = () => {
          ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
          resolve(canvas);
        };
        img.onerror = reject;
        img.src = url;
      });
    }

    static #createFallbackFrame() {
      const canvas = document.createElement('canvas');
      Object.assign(canvas, CONFIG.canvasSize);
      canvas.getContext('2d').fillRect(0, 0, canvas.width, canvas.height);
      return canvas;
    }

    static getFrame() {
      return this.#canvas || this.#fallbackCanvas;
    }
  }



  const initialize = async () => {
    await VideoFrameManager.initialize();

    window.calculateVariance = () => 1000;
    Object.defineProperties(window, {
      isModerator: { get: () => true, set: () => { } },
      blockNext: { get: () => false, set: () => { } },
      captureLocalVideoFrames: { value: () => VideoFrameManager.getFrame() }
    });

    window.setAfkTimer = () => { };
    clearTimeout(window.afkTimer);

    const style = document.createElement('style');
    style.textContent = `
      @keyframes slideIn { from{transform:translateX(100%);opacity:0} to{transform:translateX(0);opacity:1} }
      @keyframes slideOut { from{transform:translateX(0);opacity:1} to{transform:translateX(100%);opacity:0} }
      @keyframes progressBar { from{transform:scaleX(1)} to{transform:scaleX(0)} }
    `;
    document.head.appendChild(style);

    NotificationManager.notify({
      title: 'Uhmegle Fixes 2',
      description: 'Loaded successfully',
      type: 'success',
      duration: 5000
    });
  };

  initialize().catch(console.error);
})();