您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
阻止 多领国 网站在学习过程中因错误减少用户的血量,通过拦截并阻止相关的“remove-heart”请求。
当前为
// ==UserScript== // @name 多领国阻止血量减少 // @name:en DuoLingo Prevent Remove Heart // @namespace https://space.bilibili.com/1569275826 // @match *://*.duolingo.com/* // @match *://*.duolingo.cn/* // @version 0.0.5 // @description 阻止 多领国 网站在学习过程中因错误减少用户的血量,通过拦截并阻止相关的“remove-heart”请求。 // @description:en Prevent the Duolingo website from reducing the number of hearts for users during the learning process by intercepting and blocking related "remove-heart" request. // @author 深海云霁 // @license MIT // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant none // ==/UserScript== (function () { "use strict"; // 获取用户 UUID function getUUID() { const match = document.cookie.match( new RegExp("(^| )logged_out_uuid=([^;]+)") ); return match ? match[2] : null; } // 获取用户血量 (后端) async function getUserHeartFromBackend() { const uuid = getUUID(); const url = `/2017-06-30/users/${uuid}?fields=health&_=${Date.now()}`; const response = await fetch(url, { method: "GET", credentials: "include", }); return response.json(); } // 获取用户血量 (前端) function getUserHeartFromFrontend() { const spanElement = document.querySelector(".xb7v_") || document.querySelector("._1ceMn"); return spanElement?.textContent ? +spanElement.textContent : undefined; } // 检查血量是否一致 async function checkHeartConsistency() { const backendHearts = await getUserHeartFromBackend(); const frontendHearts = getUserHeartFromFrontend(); if ( frontendHearts !== undefined && backendHearts?.health?.hearts !== frontendHearts && window.confirm("检测到血量不一致,是否刷新页面?") ) { window.location.reload(); } } // 阻止 remove-heart 请求 function blockRemoveHeart() { const originalFetch = window.fetch; window.fetch = function (...args) { const [url] = args; if (typeof url === "string" && url.includes("remove-heart")) { return Promise.resolve(new Response(null, { status: 200 })); } return originalFetch.apply(this, args); }; } // 监听 pathname 变化 function watchPathname() { const originalPushState = history.pushState; let isLearning = false; history.pushState = function (state, title, url) { originalPushState.apply(history, arguments); if (url.startsWith("/lesson")) { isLearning = true; } else if (isLearning) { isLearning = false; checkHeartConsistency(); } }; } // 初始化 function init() { blockRemoveHeart(); watchPathname(); } init(); })();