Uhmegle Fixes 2

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

  1. // ==UserScript==
  2. // @name Uhmegle Fixes 2
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1
  5. // @description Bypass face detection in Uhmegle, removes afk timeouts, with improved notifications
  6. // @author Fizi
  7. // @match https://uhmegle.com/video*
  8. // @license MIT
  9. // @grant none
  10. // @run-at document-start
  11. // ==/UserScript==
  12.  
  13. (() => {
  14. const CONFIG = {
  15. imageURL: 'https://i.imgur.com/ghjBrek.png',
  16. canvasSize: { width: 1280, height: 720 }
  17. };
  18. const injectWebSocketOverride = () => {
  19. const OriginalWebSocket = window.WebSocket;
  20. let reportPending = false;
  21.  
  22. window.WebSocket = function (url, protocols) {
  23. const socket = new OriginalWebSocket(url, protocols);
  24. const frame = VideoFrameManager.getFrame();
  25.  
  26. socket.send = function (data) {
  27. if (typeof data === 'string' && data.includes('image')) {
  28. const imageData = frame.toDataURL('image/jpeg').split(';base64,')[1];
  29. OriginalWebSocket.prototype.send.call(this, JSON.stringify({
  30. event: 'image',
  31. image: imageData
  32. }));
  33.  
  34. NotificationManager.notify({
  35. title: 'Success',
  36. description: reportPending ? 'Report bypassed' : 'Camera check bypassed',
  37. type: 'success',
  38. duration: 3000
  39. });
  40. reportPending = false;
  41. return;
  42. }
  43. OriginalWebSocket.prototype.send.call(this, data);
  44. };
  45.  
  46. socket.addEventListener('message', event => {
  47. if (event.data.includes('rimage')) {
  48. reportPending = true;
  49. NotificationManager.notify({
  50. title: 'Warning',
  51. description: 'Report detected - disconnecting',
  52. type: 'warning',
  53. duration: 5000
  54. });
  55. document.querySelector('.bottomButton.outlined.skipButton.noSelect.stop')?.click();
  56. }
  57. });
  58.  
  59. return socket;
  60. };
  61. };
  62. injectWebSocketOverride();
  63.  
  64. class NotificationManager {
  65. static #container = null;
  66. static #typeConfig = {
  67. info: { color: '#2196F3', icon: 'ℹ️' },
  68. success: { color: '#4CAF50', icon: '✅' },
  69. warning: { color: '#FF9800', icon: '⚠️' },
  70. error: { color: '#F44336', icon: '❌' }
  71. };
  72.  
  73. static createContainer() {
  74. if (!this.#container) {
  75. this.#container = document.createElement('div');
  76. this.#container.id = 'notification-container';
  77. 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;';
  78. document.body.appendChild(this.#container);
  79. }
  80. return this.#container;
  81. }
  82.  
  83. static notify({ title = 'Notification', description = '', type = 'info', duration = 5000 }) {
  84. const container = this.createContainer();
  85. const notification = document.createElement('div');
  86. const config = this.#typeConfig[type];
  87.  
  88. notification.style.cssText = `
  89. background-color:${config.color};color:white;border-radius:8px;padding:15px;
  90. margin:10px;box-shadow:0 4px 6px rgba(0,0,0,0.1);display:flex;align-items:center;
  91. gap:10px;position:relative;overflow:hidden;animation:slideIn 0.5s ease forwards;
  92. `;
  93.  
  94. notification.innerHTML = `
  95. <div>${config.icon}</div>
  96. <div>
  97. <strong>${title}</strong>
  98. <div style="font-size:14px;margin-top:5px">${description}</div>
  99. </div>
  100. <div style="position:absolute;bottom:0;left:0;height:4px;background:rgba(255,255,255,0.5);
  101. width:100%;transform-origin:left;animation:progressBar ${duration}ms linear forwards;">
  102. </div>
  103. `;
  104.  
  105. container.appendChild(notification);
  106. setTimeout(() => {
  107. notification.style.animation = 'slideOut 0.5s forwards';
  108. setTimeout(() => {
  109. notification.remove();
  110. if (!container.children.length) container.remove();
  111. }, 500);
  112. }, duration);
  113. }
  114. }
  115.  
  116. class VideoFrameManager {
  117. static #canvas = null;
  118. static #fallbackCanvas = null;
  119.  
  120. static async initialize() {
  121. try {
  122. this.#canvas = await this.#loadImage(CONFIG.imageURL);
  123. } catch (err) {
  124. console.error('Failed to load image:', err);
  125. NotificationManager.notify({
  126. title: 'Error',
  127. description: 'Failed to load image - using fallback frame',
  128. type: 'error',
  129. duration: 5000
  130. });
  131. this.#canvas = this.#createFallbackFrame();
  132. }
  133. this.#fallbackCanvas = this.#createFallbackFrame();
  134. }
  135.  
  136. static #loadImage(url) {
  137. return new Promise((resolve, reject) => {
  138. const canvas = document.createElement('canvas');
  139. Object.assign(canvas, CONFIG.canvasSize);
  140. const ctx = canvas.getContext('2d');
  141.  
  142. const img = new Image();
  143. img.crossOrigin = 'anonymous';
  144. img.onload = () => {
  145. ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
  146. resolve(canvas);
  147. };
  148. img.onerror = reject;
  149. img.src = url;
  150. });
  151. }
  152.  
  153. static #createFallbackFrame() {
  154. const canvas = document.createElement('canvas');
  155. Object.assign(canvas, CONFIG.canvasSize);
  156. canvas.getContext('2d').fillRect(0, 0, canvas.width, canvas.height);
  157. return canvas;
  158. }
  159.  
  160. static getFrame() {
  161. return this.#canvas || this.#fallbackCanvas;
  162. }
  163. }
  164.  
  165.  
  166.  
  167. const initialize = async () => {
  168. await VideoFrameManager.initialize();
  169.  
  170. window.calculateVariance = () => 1000;
  171. Object.defineProperties(window, {
  172. isModerator: { get: () => true, set: () => { } },
  173. blockNext: { get: () => false, set: () => { } },
  174. captureLocalVideoFrames: { value: () => VideoFrameManager.getFrame() }
  175. });
  176.  
  177. window.setAfkTimer = () => { };
  178. clearTimeout(window.afkTimer);
  179.  
  180. const style = document.createElement('style');
  181. style.textContent = `
  182. @keyframes slideIn { from{transform:translateX(100%);opacity:0} to{transform:translateX(0);opacity:1} }
  183. @keyframes slideOut { from{transform:translateX(0);opacity:1} to{transform:translateX(100%);opacity:0} }
  184. @keyframes progressBar { from{transform:scaleX(1)} to{transform:scaleX(0)} }
  185. `;
  186. document.head.appendChild(style);
  187.  
  188. NotificationManager.notify({
  189. title: 'Uhmegle Fixes 2',
  190. description: 'Loaded successfully',
  191. type: 'success',
  192. duration: 5000
  193. });
  194. };
  195.  
  196. initialize().catch(console.error);
  197. })();