// ==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);
})();