Sleazy Fork is available in English.
锁定 edge23-sea 节点以解决因 CDN 自动分配导致的视频 404 错误或播放卡顿问题,并提供一键切换开关。
// ==UserScript==
// @name Chaturbate CDN Switcher
// @namespace mmcdn-edge-switcher
// @version 2.5
// @description 锁定 edge23-sea 节点以解决因 CDN 自动分配导致的视频 404 错误或播放卡顿问题,并提供一键切换开关。
// @author RYUJO
// @license MIT
// @match https://chaturbate.com/*
// @match https://*.chaturbate.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=chaturbate.com
// @run-at document-start
// @grant none
// ==/UserScript==
(function () {
'use strict';
const TARGET = 'edge23-sea.live.mmcdn.com';
const REGEX = /([a-z0-9-]+)\.live\.mmcdn\.com/gi;
// 状态管理:锁定 edge23-sea 节点解决 404 错误
if (localStorage.getItem('mmcdn_force_mode') === null) localStorage.setItem('mmcdn_force_mode', 'true');
let isEnabled = localStorage.getItem('mmcdn_force_mode') === 'true';
// === 1. RYUJO 水印 (仅保留在控制台) ===
const RYUJO_ART = `
██████╗ ██╗ ██╗██╗ ██╗ ██╗ ██████╗
██╔══██╗╚██╗ ██╔╝██║ ██║ ██║██╔═══██╗
██████╔╝ ╚████╔╝ ██║ ██║ ██║██║ ██║
██╔══██╗ ╚██╔╝ ██║ ██║██ ██║██║ ██║
██║ ██║ ██║ ╚██████╔╝╚█████╔╝╚██████╔╝
╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚════╝ ╚═════╝ `;
console.log(`%c${RYUJO_ART}`, 'color: #06b6d4; font-weight: bold; font-family: monospace;');
console.log(
`%c RYUJO %c CDN Switcher %c ${isEnabled ? 'ACTIVE' : 'DISABLED'} `,
'background:#0891b2; color:white; padding:3px 5px; border-radius:3px 0 0 3px; font-weight:bold;',
'background:#334155; color:white; padding:3px 5px;',
`background:${isEnabled ? '#10b981' : '#ef4444'}; color:white; padding:3px 5px; border-radius:0 3px 3px 0; font-weight:bold;`
);
// === 2. 核心拦截逻辑 (解决 404 问题) ===
function fixUrl(str) {
if (!isEnabled || typeof str !== 'string') return str;
// 仅拦截视频流相关请求,不干扰图片加载
const isStream = /\.m3u8($|\?)/i.test(str) || /\.ts($|\?)/i.test(str);
if (isStream && str.indexOf('.live.mmcdn.com') !== -1 && str.indexOf(TARGET) === -1) {
const newUrl = str.replace(REGEX, TARGET);
console.groupCollapsed(`%c ⚡ RYUJO HIJACK %c Stream Redirected `, 'background:#06b6d4;color:white;padding:1px 4px;border-radius:3px;', 'color:#06b6d4;font-weight:bold;');
console.log('%cOriginal:%c ' + str, 'color:#94a3b8;', 'color:#ef4444;text-decoration:line-through;');
console.log('%cTarget: %c ' + newUrl, 'color:#94a3b8;', 'color:#10b981;font-weight:bold;');
console.groupEnd();
return newUrl;
}
return str;
}
// --- A. Hls.js Hook ---
Object.defineProperty(window, 'Hls', {
configurable: true, enumerable: true,
get: function() { return this._ryujo_hls; },
set: function(val) {
this._ryujo_hls = val;
if (val && val.prototype && !val.prototype._patched) {
const oldLoad = val.prototype.loadSource;
val.prototype.loadSource = function(url) { return oldLoad.call(this, fixUrl(url)); };
val.prototype._patched = true;
}
}
});
// --- B. 网络层 Hooks ---
const _fetch = window.fetch;
window.fetch = function (i, n) {
if (typeof i === 'string') i = fixUrl(i);
else if (i instanceof Request) i = new Request(fixUrl(i.url), i);
return _fetch.call(this, i, n);
};
const _open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function (m, u, ...a) {
return _open.apply(this, [m, fixUrl(u), ...a]);
};
// === 3. 极简指示灯 UI (提供一键切换开关) ===
function injectUI() {
if (document.getElementById('ryujo-dot')) return;
const dot = document.createElement('div');
dot.id = 'ryujo-dot';
dot.style.cssText = `
position: fixed; top: 12px; right: 12px; z-index: 2147483647;
width: 10px; height: 10px; border-radius: 50%;
background: ${isEnabled ? '#06b6d4' : '#475569'};
cursor: pointer; border: 2px solid #fff;
box-shadow: 0 0 8px ${isEnabled ? '#06b6d4' : 'transparent'};
transition: 0.3s;
`;
dot.title = `Chaturbate CDN Switcher: ${isEnabled ? 'ON' : 'OFF'}`;
dot.onclick = () => {
localStorage.setItem('mmcdn_force_mode', !isEnabled);
location.reload();
};
(document.body || document.documentElement).appendChild(dot);
}
if (document.readyState === 'loading') window.addEventListener('DOMContentLoaded', injectUI);
else injectUI();
setInterval(injectUI, 3000);
})();