您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Modern Medium GUI with multiple bypass services.
当前为
// ==UserScript== // @name Medium Member Bypass // @author UniverseDev // @license GPL-3.0-or-later // @namespace http://tampermonkey.net/ // @version 12.9 // @description Modern Medium GUI with multiple bypass services. // @match *://*.medium.com/* // @match https://freedium.cfd/* // @match https://readmedium.com/* // @match https://md.vern.cc/* // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // ==/UserScript== (() => { 'use strict'; const config = { bypassUrls: { freedium: 'https://freedium.cfd', readmedium: 'https://readmedium.com', libmedium: 'https://md.vern.cc/', }, currentBypass: GM_getValue('currentBypass', 'freedium'), memberOnlyDivSelector: 'p.bf.b.bg.z.bk', autoRedirectDelay: GM_getValue('redirectDelay', 5000), autoRedirectEnabled: GM_getValue('autoRedirect', true), darkModeEnabled: GM_getValue('darkModeEnabled', false), isBypassSession: GM_getValue('isBypassSession', false), }; const injectStyles = () => { const style = document.createElement('style'); style.textContent = ` .medium-settings { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 360px; background-color: var(--background-color, white); box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); border-radius: 16px; font-family: 'Arial', sans-serif; z-index: 10000; padding: 20px; display: none; color: var(--text-color, #333); cursor: grab; } .medium-settings.dark { --background-color: #333; --text-color: white; } .medium-settings-header { font-size: 22px; font-weight: bold; margin-bottom: 20px; text-align: center; } .medium-settings-toggle { margin: 15px 0; display: flex; justify-content: space-between; align-items: center; } .medium-settings-input { margin-left: 10px; width: 70px; padding: 6px; text-align: center; border: 1px solid #ccc; border-radius: 4px; } .medium-settings-button { background-color: var(--button-bg-color, #1a8917); color: var(--button-text-color, white); border: none; padding: 8px 14px; border-radius: 20px; cursor: pointer; font-weight: bold; transition: background-color 0.3s; } .medium-settings-button:hover { background-color: #155c11; } .medium-notification { position: fixed; bottom: 20px; right: 20px; background-color: #1a8917; color: white; padding: 15px; border-radius: 20px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); font-family: 'Arial', sans-serif; z-index: 10000; opacity: 0; transform: translateY(20px); transition: all 0.3s ease; } .medium-notification.show { opacity: 1; transform: translateY(0); } `; document.head.appendChild(style); }; const stealthNotification = (message) => { const notification = document.createElement('div'); notification.className = 'medium-notification'; notification.textContent = message; document.body.appendChild(notification); setTimeout(() => notification.classList.add('show'), 50); setTimeout(() => { notification.classList.remove('show'); setTimeout(() => notification.remove(), 300); }, 3000); }; const showMediumSettings = () => { let existingPanel = document.querySelector('.medium-settings'); if (existingPanel) { existingPanel.style.display = 'block'; return; } const settingsContainer = document.createElement('div'); settingsContainer.className = `medium-settings ${config.darkModeEnabled ? 'dark' : ''}`; settingsContainer.innerHTML = ` <div class="medium-settings-header">Medium Settings</div> <div class="medium-settings-toggle"> <span>Auto-Redirect</span> <button class="medium-settings-button" id="toggleRedirect">${config.autoRedirectEnabled ? 'ON' : 'OFF'}</button> </div> <div class="medium-settings-toggle"> <span>Redirect Delay (ms)</span> <input type="number" class="medium-settings-input" id="redirectDelay" value="${config.autoRedirectDelay}" /> </div> <div class="medium-settings-toggle"> <span>Dark Mode</span> <button class="medium-settings-button" id="toggleDarkMode">${config.darkModeEnabled ? 'ON' : 'OFF'}</button> </div> <div class="medium-settings-toggle"> <span>Bypass Service</span> <select id="bypassSelector" class="medium-settings-input"> ${Object.keys(config.bypassUrls).map((key) => ` <option value="${key}" ${config.currentBypass === key ? 'selected' : ''}>${key}</option> `).join('')} </select> </div> <div class="medium-settings-toggle"> <button class="medium-settings-button" id="bypassNow">Bypass Now</button> </div> <div class="medium-settings-toggle"> <button class="medium-settings-button" id="resetDefaults">Reset to Default</button> </div> <div class="medium-settings-toggle"> <button class="medium-settings-button" id="saveSettings">Save</button> <button class="medium-settings-button" id="closeSettings">Close</button> </div> `; document.body.appendChild(settingsContainer); let isDragging = false; let startX, startY; settingsContainer.addEventListener('mousedown', (e) => { isDragging = true; startX = e.clientX - settingsContainer.offsetLeft; startY = e.clientY - settingsContainer.offsetTop; settingsContainer.style.cursor = 'grabbing'; }); document.addEventListener('mousemove', (e) => { if (!isDragging) return; settingsContainer.style.left = `${e.clientX - startX}px`; settingsContainer.style.top = `${e.clientY - startY}px`; }); document.addEventListener('mouseup', () => { isDragging = false; settingsContainer.style.cursor = 'grab'; }); settingsContainer.querySelector('#toggleRedirect').addEventListener('click', () => { config.autoRedirectEnabled = !config.autoRedirectEnabled; GM_setValue('autoRedirect', config.autoRedirectEnabled); settingsContainer.querySelector('#toggleRedirect').textContent = config.autoRedirectEnabled ? 'ON' : 'OFF'; stealthNotification('Auto-Redirect toggled'); }); settingsContainer.querySelector('#toggleDarkMode').addEventListener('click', () => { config.darkModeEnabled = !config.darkModeEnabled; GM_setValue('darkModeEnabled', config.darkModeEnabled); settingsContainer.classList.toggle('dark', config.darkModeEnabled); settingsContainer.querySelector('#toggleDarkMode').textContent = config.darkModeEnabled ? 'ON' : 'OFF'; stealthNotification('Dark Mode toggled'); }); settingsContainer.querySelector('#bypassSelector').addEventListener('change', (e) => { config.currentBypass = e.target.value; GM_setValue('currentBypass', config.currentBypass); stealthNotification(`Bypass service set to ${config.currentBypass}`); }); settingsContainer.querySelector('#bypassNow').addEventListener('click', () => { window.location.href = config.bypassUrls[config.currentBypass] + window.location.pathname; }); settingsContainer.querySelector('#resetDefaults').addEventListener('click', () => { config.autoRedirectDelay = 5000; config.autoRedirectEnabled = true; config.darkModeEnabled = false; config.currentBypass = 'freedium'; GM_setValue('redirectDelay', config.autoRedirectDelay); GM_setValue('autoRedirect', config.autoRedirectEnabled); GM_setValue('darkModeEnabled', config.darkModeEnabled); GM_setValue('currentBypass', config.currentBypass); settingsContainer.querySelector('#redirectDelay').value = config.autoRedirectDelay; settingsContainer.querySelector('#toggleRedirect').textContent = 'ON'; settingsContainer.querySelector('#toggleDarkMode').textContent = 'OFF'; settingsContainer.querySelector('#bypassSelector').value = 'freedium'; settingsContainer.classList.remove('dark'); stealthNotification('Settings reset to defaults'); }); settingsContainer.querySelector('#saveSettings').addEventListener('click', () => { const newDelay = parseInt(settingsContainer.querySelector('#redirectDelay').value, 10); if (!isNaN(newDelay) && newDelay >= 0) { config.autoRedirectDelay = newDelay; GM_setValue('redirectDelay', newDelay); stealthNotification('Settings saved'); } }); settingsContainer.querySelector('#closeSettings').addEventListener('click', () => { settingsContainer.style.display = 'none'; }); settingsContainer.style.display = 'block'; }; const performAutoRedirect = () => { if (config.isBypassSession) { GM_setValue('isBypassSession', false); return; } if (config.autoRedirectEnabled && document.querySelector(config.memberOnlyDivSelector)) { setTimeout(() => { window.location.href = config.bypassUrls[config.currentBypass] + window.location.pathname; }, config.autoRedirectDelay); stealthNotification('Redirecting to bypass service...'); } }; const initializeScript = () => { injectStyles(); const isBypassPage = Object.values(config.bypassUrls).some((url) => window.location.href.startsWith(url)); if (isBypassPage) { GM_setValue('isBypassSession', true); } else if (window.location.href.startsWith('https://medium.com/')) { GM_registerMenuCommand('Open Medium Settings', showMediumSettings); performAutoRedirect(); } }; initializeScript(); })();