uView Plus Ad Bypass (VIP Simulation + Google Ads Blocker)

拦截 uView Plus 文档广告验证请求,模拟 VIP 响应,移除二维码弹窗及 Google 广告组件(AdSense、双击广告等)。

当前为 2025-05-12 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name uView Plus Ad Bypass (VIP Simulation + Google Ads Blocker)
  3. // @namespace https://uiadmin.net/
  4. // @version 1.0.3
  5. // @description Bypass uView Plus documentation ad verification, block QR prompts, and remove Google ads (AdSense, DoubleClick, FundingChoices).
  6. // @description:zh-CN 拦截 uView Plus 文档广告验证请求,模拟 VIP 响应,移除二维码弹窗及 Google 广告组件(AdSense、双击广告等)。
  7. // @author WanliZhong
  8. // @license MIT
  9. // @homepage https://uview-plus.lingyun.net/
  10. // @supportURL https://uview-plus.lingyun.net/cooperation/about.html
  11. // @match https://uiadmin.net/*
  12. // @match https://*.uiadmin.net/*
  13. // @match https://uview-plus.jiangruyi.com/*
  14. // @match https://uview-plus.lingyun.net/*
  15. // @icon https://uview-plus.lingyun.net/favicon.ico
  16. // @run-at document-start
  17. // @grant none
  18. // ==/UserScript==
  19.  
  20. (function () {
  21. 'use strict';
  22.  
  23. const realXHR = window.XMLHttpRequest;
  24.  
  25. class MockXHR {
  26. constructor() {
  27. this._xhr = null;
  28. this._url = '';
  29. this._listeners = {};
  30. }
  31.  
  32. open(method, url) {
  33. this._url = url;
  34. this._intercept = url.includes('/api/v1/wxapp/ad/add');
  35. this._method = method;
  36. }
  37.  
  38. send(body) {
  39. if (this._intercept) {
  40. const id = (() => {
  41. try {
  42. return JSON.parse(body).id || 'fake-id';
  43. } catch {
  44. return 'fake-id';
  45. }
  46. })();
  47.  
  48. const fakeRes = JSON.stringify({ code: 200, data: { isVip: true, id }, msg: '成功', env: 'prod' });
  49. Object.assign(this, {
  50. readyState: 4,
  51. status: 200,
  52. responseText: fakeRes,
  53. response: fakeRes,
  54. responseURL: this._url
  55. });
  56.  
  57. setTimeout(() => {
  58. this.onload?.({ target: this });
  59. this.onreadystatechange?.({ target: this });
  60. (this._listeners.load || []).forEach(cb => cb({ target: this }));
  61. (this._listeners.readystatechange || []).forEach(cb => cb({ target: this }));
  62. }, 10);
  63. } else {
  64. const xhr = this._xhr = new realXHR();
  65. xhr.onreadystatechange = (...args) => {
  66. this._syncFrom(xhr);
  67. this.onreadystatechange?.(...args);
  68. };
  69. xhr.onload = (...args) => {
  70. this._syncFrom(xhr);
  71. this.onload?.(...args);
  72. };
  73. xhr.open(this._method, this._url, true);
  74. xhr.send(body);
  75. }
  76. }
  77.  
  78. _syncFrom(xhr) {
  79. ['readyState', 'status', 'responseText', 'response', 'responseURL'].forEach(k => this[k] = xhr[k]);
  80. }
  81.  
  82. setRequestHeader() { }
  83. getAllResponseHeaders() { return ''; }
  84. getResponseHeader() { return null; }
  85. abort() { }
  86. addEventListener(type, cb) {
  87. (this._listeners[type] ||= []).push(cb);
  88. }
  89. }
  90.  
  91. Object.defineProperty(window, 'XMLHttpRequest', {
  92. configurable: true,
  93. writable: true,
  94. value: MockXHR
  95. });
  96.  
  97.  
  98. // 广告清理函数
  99. function cleanAllAds() {
  100. try {
  101. // 移除广告脚本
  102. document.querySelectorAll('script[src*="googlesyndication"], script[src*="fundingchoicesmessages"]').forEach(e => e.remove());
  103. // 移除广告 iframe
  104. document.querySelectorAll('iframe[src*="googlesyndication"], iframe[src*="doubleclick"]').forEach(e => e.remove());
  105. // 移除常见广告 DOM
  106. document.querySelectorAll('[class*="adsbygoogle"], [id*="adsbygoogle"], .fc-ab-root, .google-auto-placed, .ad-container')
  107. .forEach(e => e.remove());
  108. } catch (err) {
  109. console.warn('[AdBypass] ❌ Error cleaning ads:', err);
  110. }
  111. }
  112.  
  113. // 页面加载后立即清除广告,并延迟几轮再次清除
  114. document.addEventListener('DOMContentLoaded', () => {
  115. cleanAllAds();
  116. setTimeout(cleanAllAds, 1000);
  117. setTimeout(cleanAllAds, 3000);
  118. setTimeout(cleanAllAds, 5000);
  119. });
  120.  
  121. // 观察 DOM 动态插入内容
  122. function observeWhenBodyReady() {
  123. const interval = setInterval(() => {
  124. if (document.body) {
  125. const observer = new MutationObserver(() => cleanAllAds());
  126. observer.observe(document.body, { childList: true, subtree: true });
  127. clearInterval(interval);
  128. }
  129. }, 100);
  130. }
  131.  
  132. observeWhenBodyReady();
  133.  
  134. // 可选:屏蔽 alert 弹窗
  135. window.alert = function (message) {
  136. console.log("Blocked alert:", message);
  137. throw new Error("alert() was blocked to prevent interruption.");
  138. };
  139. })();