解除網頁限制,恢復默認行爲

阻止網頁的反調試措施並將網頁對部分操作(如:選擇、複製、打開開發者工具)處理重置爲相應的瀏覽器默認行爲。

  1. // ==UserScript==
  2. // @name Remove Restrictions and Restore Default Behavior
  3. // @name:zh-CN 解除网页限制,恢复默认行为
  4. // @name:zh-TW 解除網頁限制,恢復默認行爲
  5. // @name:ja-JP Webページの制限を削除し、デフォルトの動作に戻す
  6. // @name:ko-KR 웹 페이지 제한 제거 및 기본 동작 복원
  7. // @name:en-US Remove Restrictions and Restore Default Behavior
  8. // @name:fr-FR Supprimer les restrictions de page Web et restaurer le comportement par défaut
  9. // @name:de-DE Entfernen von Webseiteneinschränkungen und Wiederherstellen des Standardverhaltens
  10. // @name:it-IT Rimuovi le restrizioni delle pagine Web e ripristina il comportamento predefinito
  11. // @name:pt-BR Remover restrições de página da Web e restaurar o comportamento padrão
  12. // @name:es-ES Levantar las restricciones de la página web y restaurar el comportamiento predeterminado
  13. // @name:ru-RU Снятие ограничений веб-страниц и восстановление поведения по умолчанию
  14. // @namespace http://hl-bo.github.io/namespaces/user-script/remove-limits
  15. // @source https://github.com/HL-Bo/user-script
  16. // @supportURL https://github.com/HL-Bo/user-script/issues
  17. // @version 3.0
  18. // @license AGPLv3
  19. // @description Block the anti-debugging actions of the web page and reset the processing of certain actions (e.g., select, copy, open developer tools) of the web page to the corresponding browser default behavior.
  20. // @description:zh-CN 阻止网页的反调试措施并将网页对部分操作(如:选择、复制、打开开发者工具)处理重置为相应的浏览器默认行为。
  21. // @description:zh-TW 阻止網頁的反調試措施並將網頁對部分操作(如:選擇、複製、打開開發者工具)處理重置爲相應的瀏覽器默認行爲。
  22. // @description:ja-JP Web ページのアンチデバッグ アクションをブロックし、Web ページの特定のアクション (選択、コピー、開発者ツールを開くなど) の処理を対応するブラウザーの既定の動作にリセットします。
  23. // @description:ko-KR 웹 페이지의 디버깅 방지 작업을 차단하고 웹 페이지의 특정 작업(예: 개발자 도구 선택, 복사, 열기)의 처리를 해당 브라우저 기본 동작으로 재설정합니다.
  24. // @description:en-US Block the anti-debugging actions of the web page and reset the processing of certain actions (e.g., select, copy, open developer tools) of the web page to the corresponding browser default behavior.
  25. // @description:fr-FR Bloquez les actions anti-débogage de la page Web et réinitialisez le traitement de certaines actions (par exemple, sélectionner, copier, ouvrir les outils de développement) de la page Web au comportement par défaut du navigateur correspondant.
  26. // @description:de-DE Blockieren Sie die Anti-Debugging-Aktionen der Webseite und setzen Sie die Verarbeitung bestimmter Aktionen (z. B. Auswählen, Kopieren, Öffnen von Entwicklertools) der Webseite auf das entsprechende Standardverhalten des Browsers zurück.
  27. // @description:it-IT Blocca le azioni anti-debug della pagina Web e ripristina l'elaborazione di determinate azioni (ad esempio, seleziona, copia, apri gli strumenti di sviluppo) della pagina Web al comportamento predefinito del browser corrispondente.
  28. // @description:pt-BR Bloqueie as ações antidepuração da página da Web e redefina o processamento de determinadas ações (por exemplo, selecionar, copiar, abrir ferramentas de desenvolvedor) da página da Web para o comportamento padrão do navegador correspondente.
  29. // @description:es-ES Bloquear las medidas de anti - depuración de la página web y restablecer el procesamiento de la página web para algunas operaciones (como: seleccionar, copiar, abrir la herramienta del desarrollador) al comportamiento predeterminado del navegador correspondiente.
  30. // @description:ru-RU Заблокируйте антиотладочные действия веб-страницы и сбросьте обработку определенных действий (например, выбор, копирование, открытие средств разработчика) веб-страницы до соответствующего поведения браузера по умолчанию.
  31. // @author HL-Bo
  32. // @include https://example.com/**
  33. // @exclude https://example.org/**
  34. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAspJREFUWEfVl89PE1EQx7/TdpcabKFAoEKQH22ktEYSqRevXiRijEr8cSDe/DNM9D/xhPFn4oF4MeBZuJi0SiiQikTjD2gLCLS7jNmFLt2mu/uWYtB36G73zWQ+b2bevDeEijE5Od/Q3ut5CNA9gMOVc3bvG7+3MLeYRU9nhxqP9r2WURoPh8ObIvpUKTSbzkww6I6IYqWMAdAVxmCkF8z8zk/KFREIA2BmbilGu7tpZpigRGCqATQdAk3LKI46QRjGZtOZ6wx6KWKwWqYWgCbDzNN+UmwhDID3HxduEuP5UQKIQPx1gDJEnpTRoRqJaQnw/dcqVvPrANf2iST50N/dCSKCVQjMmjyVg3K1GsISILvyFT/X8pYRkXw+nD3TD4/HIwigp+ZUDkUThG0I9MVbeIAq9srW9g7SmSW0t4ZwPjHglEZvf3xZGkkmk6W93bI/qpNQUVVs7xRtPOBFgyzr88yM1PwidoolRE53oS3UbAuhMo8Mx/re2ALMZ5dRWLcuZlrsh2JReL1e3ZiWB5nsMlR118kDII/39v2xy09tAQobm8jrALVjIEsSOtpaTMZKioLVXAHaU/OK1fAAt65duvjMFsBxGXUIMGHswmDkhS2AtpK1wnodZg5UQ8EAWpqDxgchgIXPK8gdEUBzMKAnZ3kIAWgxLCmq9T4U9g1B8nn1gvV/ARx7CI49CYVDfAhBoSR0KkTidglNgUYETza6S0KtrO5VwvqHBhDt6XYH4HQYucHyN8jw7Z8Z+uElUgl1QePHjbkqWao4cvenhACcLiRukNpCTejpOuUuBE5XMmEAAlqaAmhvPTg5hTwgbOAQgv8mQD2NiVsnEPjGcDz6ynQfmPkwFyPJd6jWzA0AEZhLSjx5buCTCUD7M5temGDAdXPqCgB4MhyP3C3rmBrRVColb5H/kdv2XAyAvgH8+ARvP0gkEsZ1+w+ixcUwoQ+80AAAAABJRU5ErkJggg==
  35. // @grant none
  36. // @run-at document-start
  37. // ==/UserScript==
  38.  
  39. (function () {
  40. 'use strict';
  41. console.warn("CAUTION FOR NEGATIVE EFFECTS")
  42.  
  43. let in_frame = false;
  44. if (window.frameElement && window.frameElement.tagName === 'IFRAME' || window !== window.top) { in_frame = true; }
  45. if (!in_frame) {
  46. console.log(
  47. " ____ _ _ _ _ \n" +
  48. " | _ \\ ___ _ __ ___ ___ __ __ ___ | | (_) _ __ ___ (_) | |_ ___ \n" +
  49. " | |_) | / _ \\ | '_ ` _ \\ / _ \\ \\ \\ / / / _ \\ | | | | | '_ ` _ \\ | | | __| / __|\n" +
  50. " | _ < | __/ | | | | | | | (_) | \\ V / | __/ | |___ | | | | | | | | | | | |_ \\__ \\\n" +
  51. " |_| \\_\\ \\___| |_| |_| |_| \\___/ \\_/ \\___| |_____| |_| |_| |_| |_| |_| \\__| |___/\n" +
  52. " \n" +
  53. " By HL-Bo"
  54. );
  55. }
  56. if (in_frame) {
  57. console.debug(`Start the installation of user-script/remove-limits IN_FRAME(${window.location})`);
  58. } else { console.info(`Start the installation of user-script/remove-limits (${window.location})`); }
  59.  
  60. let dangerous_events = ['beforecopy', 'copy', 'beforecut', 'cut', 'beforepaste', 'paste', 'selectstart', 'contextmenu', 'dragstart', 'dragenter', 'dragover', 'dragleave', 'dragend', 'drop', 'keypress', 'keydown', 'keyup', 'visibilitychange', 'mousedown', 'mouseup', 'mousewheel', 'wheel', 'mouseenter', 'mousemove', 'mouseover', 'mouseout', 'mouseleave', 'gotpointercapture', 'lostpointercapture', 'pointerdown', 'pointerrawupdate', 'pointerup', 'pointerenter', 'pointermove', 'pointerover', 'pointerout', 'pointerleave', 'pointercancel', 'focus', 'focusin', 'focusout', 'blur'];
  61. let style_element_inner = '* { user-select: auto !important; -webkit-user-select: auto !important; -moz-user-select: auto !important; -ms-user-select: auto !important; }';
  62. let head_style_element = document.createElement('style');
  63. head_style_element.innerText = style_element_inner;
  64. let body_style_element = document.createElement('style');
  65. body_style_element.innerText = style_element_inner;
  66.  
  67. // 尝试禁用 debugger
  68. // 仅在 eval('debugger') 或 setInterval('debugger', sec) 构造前执行才能阻止
  69. try {
  70. Function.prototype.$rl_constructor = Function.prototype.constructor;
  71. Function.prototype.constructor = function () {
  72. if (arguments && typeof arguments[0] === 'string') {
  73. if ('debugger' === arguments[0]) {
  74. console.debug('Disable an function which may execute debugger');
  75. return;
  76. }
  77. }
  78. return Function.prototype.$rl_constructor.apply(this, arguments);
  79. };
  80. } catch (error) { console.warn(error); } finally { }
  81. // 防止清空控制台
  82. console.$rl_clear = console.clear;
  83. console.clear = function () { };
  84.  
  85. let executeWithInterval = function (func, delay) {
  86. setTimeout(func, 0); // 异步执行,防止阻塞
  87. setInterval(func, delay);
  88. };
  89. let logError = function (error) {
  90. let error_message = error.toString();
  91. if (document && document.body) {
  92. if (document.body.$rl_errors) {
  93. if (!document.body.$rl_errors.includes(error_message)) {
  94. if (in_frame) { console.debug(error_message); } else { console.warn(error_message); }
  95. document.body.$rl_errors.push(error_message);
  96. }
  97. } else { document.body.$rl_errors = new Array(); }
  98. }
  99. };
  100. let injectStyle = function () {
  101. if (document && document.head) {
  102. try { document.head.appendChild(head_style_element); } catch (error) { logError(error); } finally { }
  103. }
  104. if (document && document.body) {
  105. try { document.body.appendChild(head_style_element); } catch (error) { logError(error); } finally { }
  106. }
  107. };
  108. /*
  109. let getSelection = function () {
  110. if (window.getSelection)
  111. return (window.getSelection() || "").toString();
  112. if (document.getSelection)
  113. return (document.getSelection() || "").toString();
  114. if (document.selection)
  115. return document.selection.createRange().text;
  116. return "";
  117. };
  118. */
  119. let setEventListener = function (element, event_name, listener) {
  120. if (!element.$listen_event) {
  121. element.$listen_event = element.addEventListener;
  122. }
  123. element.addEventListener = function (event_name, listener, options) {
  124. if (event_name == dangerous_events) {
  125. element.$listen_event(event_name, (event) => { event.stopPropagation(); });
  126. } else {
  127. element.$listen_event(event_name, listener, options);
  128. }
  129. };
  130. if (!element.$rl_lazy_events) { element.$rl_lazy_events = new Map(); }
  131. if (!element.$rl_events) { element.$rl_events = new Map(); }
  132. if (!element.$rl_lazy_events.has(event_name)) {
  133. element.$rl_lazy_events.set(event_name, listener);
  134. element.$listen_event(event_name, listener);
  135. }
  136. if (!element.$rl_events.has(event_name)) {
  137. element.removeEventListener(event_name, element.$rl_events.get(event_name));
  138. element.$rl_events.set(event_name, listener);
  139. element.$listen_event(event_name, listener);
  140. }
  141. };
  142. let copyEventType = function (old_event) {
  143. /*
  144. Event
  145. +-- ClipboardEvent (cut, copy, paste)
  146. +-- UIEvent
  147. +-- FocusEvent (focus, blur, focusin, focusout, ...)
  148. +-- InputEvent
  149. +-- CompositionEvent (compositionstart, compositionupdate, compositionend, ...)
  150. +-- KeyboardEvent (keydown, keypress, keyup)
  151. +-- TouchEvent
  152. +-- MouseEvent (click, dblclick, mouseup, mousedown, ...)
  153. +-- PointerEvent
  154. +-- WheelEvent
  155. */
  156. let new_event_type = Event;
  157. if (old_event instanceof ClipboardEvent) { new_event_type = ClipboardEvent; }
  158. if (old_event instanceof UIEvent) { new_event_type = UIEvent; }
  159. if (old_event instanceof FocusEvent) { new_event_type = FocusEvent; }
  160. if (old_event instanceof InputEvent) { new_event_type = InputEvent; }
  161. if (old_event instanceof CompositionEvent) { new_event_type = CompositionEvent; }
  162. if (old_event instanceof KeyboardEvent) { new_event_type = KeyboardEvent; }
  163. if (old_event instanceof TouchEvent) { new_event_type = TouchEvent; }
  164. if (old_event instanceof MouseEvent) { new_event_type = MouseEvent; }
  165. if (old_event instanceof PointerEvent) { new_event_type = PointerEvent; }
  166. if (old_event instanceof WheelEvent) { new_event_type = WheelEvent; }
  167. return new_event_type;
  168. };
  169. let copyEventAttr = function (old_event) {
  170. let new_event_init_dict = {};
  171. new_event_init_dict.cancelable = false;
  172. if (old_event.bubbles) { new_event_init_dict.bubbles = old_event.bubbles; } // Event
  173. if (old_event.composed) { new_event_init_dict.composed = old_event.composed; } // Event
  174. if (old_event.detail) { new_event_init_dict.detail = old_event.detail; } // UIEvent
  175. if (old_event.view) { new_event_init_dict.view = old_event.view; } // UIEvent
  176. if (old_event.sourceCapabilities) { new_event_init_dict.sourceCapabilities = old_event.sourceCapabilities; } // UIEvent
  177. if (old_event.relatedTarget) { new_event_init_dict.relatedTarget = old_event.relatedTarget; } // FocusEvent
  178. if (old_event.screenX) { new_event_init_dict.screenX = old_event.screenX; } // MouseEvent
  179. if (old_event.screenY) { new_event_init_dict.screenY = old_event.screenY; } // MouseEvent
  180. if (old_event.clientX) { new_event_init_dict.clientX = old_event.clientX; } // MouseEvent
  181. if (old_event.clientY) { new_event_init_dict.screenX = old_event.clientY; } // MouseEvent
  182. if (old_event.key) { new_event_init_dict.key = old_event.key; } // KeyboardEvent
  183. if (old_event.code) { new_event_init_dict.code = old_event.code; } // KeyboardEvent
  184. if (old_event.location) { new_event_init_dict.location = old_event.location; } // KeyboardEvent
  185. if (old_event.touches) { new_event_init_dict.touches = old_event.touches; } // TouchEvent
  186. if (old_event.targetTouches) { new_event_init_dict.targetTouches = old_event.targetTouches; } // TouchEvent
  187. if (old_event.changedTouches) { new_event_init_dict.changedTouches = old_event.changedTouches; } // TouchEvent
  188. if (old_event.ctrlKey) { new_event_init_dict.ctrlKey = old_event.ctrlKey; } // MouseEvent & KeyboardEvent & TouchEvent
  189. if (old_event.shiftKey) { new_event_init_dict.shiftKey = old_event.shiftKey; } // MouseEvent & KeyboardEvent & TouchEvent
  190. if (old_event.altKey) { new_event_init_dict.altKey = old_event.altKey; } // MouseEvent & KeyboardEvent & TouchEvent
  191. if (old_event.metaKey) { new_event_init_dict.metaKey = old_event.metaKey; } // MouseEvent & KeyboardEvent & TouchEvent
  192. if (old_event.repeat) { new_event_init_dict.repeat = old_event.repeat; } // KeyboardEvent
  193. if (old_event.inputType) { new_event_init_dict.inputType = old_event.inputType; } // InputEvent
  194. if (old_event.isComposing) { new_event_init_dict.isComposing = old_event.isComposing; } // KeyboardEvent & InputEvent
  195. if (old_event.charCode) { new_event_init_dict.charCode = old_event.charCode; } // KeyboardEvent
  196. if (old_event.keyCode) { new_event_init_dict.keyCode = old_event.keyCode; } // KeyboardEvent
  197. if (old_event.which) { new_event_init_dict.which = old_event.which; } // KeyboardEvent
  198. if (old_event.button) { new_event_init_dict.button = old_event.button; } // MouseEvent
  199. if (old_event.buttons) { new_event_init_dict.buttons = old_event.buttons; } // MouseEvent
  200. if (old_event.relatedTarget) { new_event_init_dict.relatedTarget = old_event.relatedTarget; } // MouseEvent
  201. if (old_event.region) { new_event_init_dict.region = old_event.region; } // MouseEvent
  202. if (old_event.deltaX) { new_event_init_dict.deltaX = old_event.deltaX; } // WheelEvent
  203. if (old_event.deltaY) { new_event_init_dict.deltaY = old_event.deltaY; } // WheelEvent
  204. if (old_event.deltaZ) { new_event_init_dict.deltaZ = old_event.deltaZ; } // WheelEvent
  205. if (old_event.deltaMode) { new_event_init_dict.deltaMode = old_event.deltaMode; } // WheelEvent
  206. if (old_event.pointerId) { new_event_init_dict.pointerId = old_event.pointerId; } // PointerEvent
  207. if (old_event.width) { new_event_init_dict.width = old_event.width; } // PointerEvent
  208. if (old_event.height) { new_event_init_dict.height = old_event.height; } // PointerEvent
  209. if (old_event.pressure) { new_event_init_dict.pressure = old_event.pressure; } // PointerEvent
  210. if (old_event.tangentialPressure) { new_event_init_dict.tangentialPressure = old_event.tangentialPressure; } // PointerEvent
  211. if (old_event.tiltX) { new_event_init_dict.tiltX = old_event.tiltX; } // PointerEvent
  212. if (old_event.tiltY) { new_event_init_dict.tiltY = old_event.tiltY; } // PointerEvent
  213. if (old_event.twist) { new_event_init_dict.twist = old_event.twist; } // PointerEvent
  214. if (old_event.pointerType) { new_event_init_dict.pointerType = old_event.pointerType; } // PointerEvent
  215. if (old_event.isPrimary) { new_event_init_dict.isPrimary = old_event.isPrimary; } // PointerEvent
  216. if (old_event.dataTransfer) { new_event_init_dict.dataTransfer = old_event.dataTransfer; } // DragEvent
  217. if (old_event.clipboardData) { new_event_init_dict.clipboardData = old_event.clipboardData; } // ClipboardEvent
  218. if (old_event.dataType) { new_event_init_dict.dataType = old_event.dataType; } // ClipboardEvent
  219. if (old_event.data) { new_event_init_dict.data = old_event.data; } // ClipboardEvent & InputEvent & CompositionEvent
  220. return new_event_init_dict;
  221. };
  222. let copyEvent = function (old_event) {
  223. let event_type = copyEventType(old_event);
  224. let event_init = copyEventAttr(old_event);
  225. let new_event = new event_type(old_event.type, event_init);
  226. return new_event;
  227. };
  228. let returnEventAllowed = function (event) {
  229. if (event.defaultPrevented) {
  230. // 如果调用了 Event.preventDefault() ,则重新构建一个不可取消的事件。
  231. event.stopPropagation(); // 停止原事件冒泡,以防重复新建事件。
  232. let new_event = copyEvent(event);
  233. if (event.target) { event.target.dispatchEvent(new_event); } else { event.currentTarget.dispatchEvent(new_event); }
  234. event = new_event;
  235. }
  236. event.stopImmediatePropagation(); // 防止其它事件处理器被调用
  237. try { event.returnValue = true; } catch (error) { logError(error); } finally { }
  238. if (event.currentTarget === document) { console.debug(`Allow ${event.type}`); }
  239. };
  240. let allowEvent = function (element, event_name) {
  241. setEventListener(element, event_name, function (event) { returnEventAllowed(event); return true; });
  242. };
  243. let onKeyEvents = function (event) {
  244. let keyCode = event.keyCode || event.which || event.charCode;
  245. let ctrlKey = event.ctrlKey || event.metaKey;
  246. let shiftKey = event.shiftKey;
  247. if (ctrlKey && (keyCode == 65 || keyCode == 88 || keyCode == 67 || keyCode == 86 || keyCode == 83 || keyCode == 85)) {
  248. // Ctrl+A (select-all), Ctrl+X (cut), Ctrl+C (copy), Ctrl+V (paste), Ctrl+S (save), Ctrl+U (view-source)
  249. returnEventAllowed(event);
  250. } else if (ctrlKey && shiftKey && (keyCode == 73 || keyCode == 74 || keyCode == 67)) {
  251. // Ctrl+Shift+I (devtools), Ctrl+Shift+J (console), Ctrl+Shift+C (elements)
  252. returnEventAllowed(event);
  253. } else if (keyCode && keyCode == 123) { // F12
  254. returnEventAllowed(event);
  255. }
  256. return true;
  257. };
  258. let allowKeyEvents = function (element, event_name) {
  259. setEventListener(element, event_name, onKeyEvents);
  260. };
  261. let preventEventChecks = function (element) {
  262. for (let i of dangerous_events) {
  263. Object.defineProperty(element, 'on' + i,
  264. {
  265. get: () => { return (event) => false; },
  266. set: (value) => { if (value !== null) { console.debug('Prevent to set property'); } }
  267. }
  268. );
  269. }
  270. };
  271. let allowElement = function (element) {
  272. // 取消通过 JavaScript 实现的禁止复制
  273. try { element.onbeforecopy = null; } catch (error) { logError(error); } finally { allowEvent(element, 'beforecopy'); }
  274. try { element.oncopy = null; } catch (error) { logError(error); } finally { allowEvent(element, 'copy'); }
  275. // 取消通过 JavaScript 实现的禁止剪切实现的禁止复制
  276. try { element.onbeforecut = null; } catch (error) { logError(error); } finally { allowEvent(element, 'beforecut'); }
  277. try { element.oncut = null; } catch (error) { logError(error); } finally { allowEvent(element, 'cut'); }
  278. // 取消通过 JavaScript 实现的禁止粘贴
  279. try { element.onbeforepaste = null; } catch (error) { logError(error); } finally { allowEvent(element, 'beforepaste'); }
  280. try { element.onpaste = null; } catch (error) { logError(error); } finally { allowEvent(element, 'paste'); }
  281. // 取消通过 JavaScript 实现的禁止文字选择
  282. try { element.onselectstart = null; } catch (error) { logError(error); } finally { allowEvent(element, 'selectstart'); }
  283. // 取消通过 JavaScript 实现的禁止右键菜单
  284. try { element.oncontextmenu = null; } catch (error) { logError(error); } finally { allowEvent(element, 'contextmenu'); }
  285. // 取消通过 JavaScript 实现的禁止拖动
  286. try { element.ondragstart = null; } catch (error) { logError(error); } finally { allowEvent(element, 'dragstart'); }
  287. try { element.ondragenter = null; } catch (error) { logError(error); } finally { allowEvent(element, 'dragenter'); }
  288. try { element.ondragover = null; } catch (error) { logError(error); } finally { allowEvent(element, 'dragover'); }
  289. try { element.ondragleave = null; } catch (error) { logError(error); } finally { allowEvent(element, 'dragleave'); }
  290. try { element.ondragend = null; } catch (error) { logError(error); } finally { allowEvent(element, 'dragend'); }
  291. // try { element.ondrop = null; } catch (error) { logError(error); } finally { allowEvent(element, 'drop'); }
  292. // 取消通过 CSS 实现的禁止选中
  293. if (element.style) {
  294. try { element.style.mozUserSelect = 'auto'; } catch (error) { logError(error); } finally { }
  295. try { element.style.webkitUserSelect = 'auto'; } catch (error) { logError(error); } finally { }
  296. try { element.style.msUserSelect = 'auto'; } catch (error) { logError(error); } finally { }
  297. try { element.style.userSelect = 'auto'; } catch (error) { logError(error); } finally { }
  298. }
  299. // 取消通过 JavaScript 实现的禁用快捷键
  300. try { element.onkeypress = null; } catch (error) { logError(error); } finally { allowKeyEvents(element, 'keypress'); }
  301. try { element.onkeydown = null; } catch (error) { logError(error); } finally { allowKeyEvents(element, 'keydown'); }
  302. try { element.onkeyup = null; } catch (error) { logError(error); } finally { allowKeyEvents(element, 'keyup'); }
  303. // 取消通过 JavaScript 实现的页面离开检测
  304. try { element.onvisibilitychange = null; } catch (error) { logError(error); } finally { allowEvent(element, 'visibilitychange'); }
  305. // 取消通过 JavaScript 实现的鼠标离开检测
  306. // try { element.onmousedown = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mousedown'); }
  307. // try { element.onmouseup = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mouseup'); }
  308. // try { element.onmousewheel = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mousewheel'); }
  309. // try { element.onwheel = null; } catch (error) { logError(error); } finally { allowEvent(element, 'wheel'); }
  310. // try { element.onmouseenter = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mouseenter'); }
  311. // try { element.onmousemove = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mousemove'); }
  312. // try { element.onmouseover = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mouseover'); }
  313. try { element.onmouseout = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mouseout'); }
  314. try { element.onmouseleave = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mouseleave'); }
  315. // 取消通过 JavaScript 实现的指针离开检测
  316. // try { element.ongotpointercapture = null; } catch (error) { logError(error); } finally { allowEvent(element, 'gotpointercapture'); }
  317. try { element.onlostpointercapture = null; } catch (error) { logError(error); } finally { allowEvent(element, 'lostpointercapture'); }
  318. // try { element.onpointerdown = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointerdown'); }
  319. // try { element.onpointerrawupdate = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointerrawupdate'); }
  320. try { element.onpointerup = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointerup'); }
  321. // try { element.onpointerenter = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointerenter'); }
  322. // try { element.onpointermove = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointermove'); }
  323. // try { element.onpointerover = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointerover'); }
  324. try { element.onpointerout = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointerout'); }
  325. try { element.onpointerleave = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointerleave'); }
  326. try { element.onpointercancel = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointercancel'); }
  327. // 取消通过 JavaScript 实现的焦点离开检测
  328. try { element.onfocus = null; } catch (error) { logError(error); } finally { allowEvent(element, 'focus'); }
  329. try { element.onfocusin = null; } catch (error) { logError(error); } finally { allowEvent(element, 'focusin'); }
  330. try { element.onfocusout = null; } catch (error) { logError(error); } finally { allowEvent(element, 'focusout'); }
  331. try { element.onblur = null; } catch (error) { logError(error); } finally { allowEvent(element, 'blur'); }
  332. // 取消通过 HTML 实现的表单项禁用/禁止修改
  333. try { if (element instanceof Element && element.hasAttribute('disabled')) { element.removeAttribute('disabled'); } } catch (error) { logError(error); } finally { }
  334. try { if (element instanceof Element && element.hasAttribute('readonly')) { element.removeAttribute('readonly'); } } catch (error) { logError(error); } finally { }
  335. // 防止 JavaScript 事件检测
  336. try { preventEventChecks(element); } catch (error) { logError(error); } finally { allowEvent(element, 'focusout'); }
  337. };
  338. let allowElementRecursion = function (element) {
  339. allowElement(element);
  340. for (let i of element.children) { allowElementRecursion(i); }
  341. };
  342. // let removeAllListeners = function (old_element) {
  343. // let new_element = old_element.cloneNode(true);
  344. // old_element.parentNode.replaceChild(new_element, old_element);
  345. // };
  346. let removeHiddenElements = function (element, recursion) {
  347. if ((element.hidden || element.style.display == 'none' || element.style.visibility == 'hidden' || ((element.style.height <= 0 || element.style.width <= 0) && element.style.overflow == 'hidden') && element.children.length <= 0)) {
  348. console.info(`Remove <${element.tagName} id='${element.id}' class='${element.className}' />`);
  349. element.remove();
  350. } else if (recursion) { for (let i of element.children) { removeHiddenElements(i, recursion); } }
  351. };
  352. let getMainContainerElement = function () {
  353. // 获取正文节点
  354. let main_container_element = null;
  355. if (document) {
  356. if (main_container_element === null) { // 检查 main 标签
  357. let elements = document.getElementsByTagName('main');
  358. if (elements.length > 0) { main_container_element = elements[0]; }
  359. }
  360. if (main_container_element === null) { // 检查 id='main' 的标签
  361. main_container_element = document.getElementById('main');
  362. }
  363. if (main_container_element === null) { // 检查 id='main-content' 的标签
  364. main_container_element = document.getElementById('main-content');
  365. }
  366. if (main_container_element === null) { // 检查 id='main-contents' 的标签
  367. main_container_element = document.getElementById('main-content');
  368. }
  369. if (main_container_element === null) { // 检查 id='content' 的标签
  370. main_container_element = document.getElementById('content');
  371. }
  372. if (main_container_element === null) { // 检查 id='contents' 的标签
  373. main_container_element = document.getElementById('contents');
  374. }
  375. if (main_container_element === null) { // 检查 class='main' 的标签
  376. let elements = document.getElementsByClassName('main');
  377. if (elements.length > 0) { main_container_element = elements[0]; }
  378. }
  379. if (main_container_element === null) { // 检查 class='main-content' 的标签
  380. let elements = document.getElementsByClassName('content');
  381. if (elements.length > 0) { main_container_element = elements[0]; }
  382. }
  383. if (main_container_element === null) { // 检查 class='main-contents' 的标签
  384. let elements = document.getElementsByClassName('content');
  385. if (elements.length > 0) { main_container_element = elements[0]; }
  386. }
  387. if (main_container_element === null) { // 检查 class='content' 的标签
  388. let elements = document.getElementsByClassName('content');
  389. if (elements.length > 0) { main_container_element = elements[0]; }
  390. }
  391. if (main_container_element === null) { // 检查 class='contents' 的标签
  392. let elements = document.getElementsByClassName('contents');
  393. if (elements.length > 0) { main_container_element = elements[0]; }
  394. }
  395. }
  396. return main_container_element;
  397. };
  398.  
  399. // 对抗延迟运行(即在此脚本执行后运行)的禁用程序和循环执行的禁用程序,
  400. executeWithInterval(
  401. (function () {
  402. if (window) {
  403. try { allowElement(window); } catch (error) { logError(error); } finally { }
  404. }
  405. }), 200
  406. );
  407. executeWithInterval(
  408. (function () {
  409. if (document) {
  410. try { allowElement(document); } catch (error) { logError(error); } finally { }
  411. }
  412. }), 200
  413. );
  414. executeWithInterval(
  415. (function () {
  416. if (document && document.body) {
  417. try { allowElement(document.body); } catch (error) { logError(error); } finally { }
  418. }
  419. }), 300
  420. );
  421. executeWithInterval(
  422. (function () {
  423. if (document && document.body) {
  424. try { allowElementRecursion(document.body); } catch (error) { logError(error); } finally { }
  425. }
  426. }), 3000
  427. );
  428. executeWithInterval(
  429. (function () {
  430. let mce = getMainContainerElement();
  431. if (document && mce) {
  432. try { allowElementRecursion(mce); } catch (error) { logError(error); } finally { }
  433. }
  434. }), 2000
  435. );
  436.  
  437. // 对抗延迟运行(即在此脚本执行后运行)的混淆程序和循环执行的混淆程序,
  438. setTimeout(
  439. // 延迟 1.0 秒,有助于动态加载的内容的显示。
  440. function () {
  441. executeWithInterval(
  442. // 每 3.0 秒执行一次。
  443. function () {
  444. if (document) {
  445. // 移除正文中的不可见元素
  446. try {
  447. let mce = getMainContainerElement();
  448. // 移除不可见元素
  449. if (mce) { removeHiddenElements(mce, true); }
  450. } catch (error) { logError(error); } finally { }
  451. }
  452. }, 3000
  453. );
  454. }, 1000
  455. );
  456. executeWithInterval(injectStyle, 500);
  457. /*
  458. // 安装 Service Worker 以过滤请求
  459. if ('serviceWorker' in navigator) {
  460. navigator.serviceWorker
  461. .register(
  462. 'https://cdn.jsdelivr.net/gh/HL-Bo/user-script/remove-limits/service-worker.js',
  463. { scope: window.location.origin + window.location.pathname }
  464. )
  465. .then((registration) => {
  466. if (in_frame) {
  467. console.debug(`Register service worker for ${registration.scope} (IN-FRAME)`);
  468. } else { console.info(`Register service worker for ${registration.scope}`); }
  469. })
  470. .catch((error) => { logError(error); });
  471. }
  472. */
  473. if (in_frame) {
  474. console.debug(`Complete the installation of user-script/remove-limits IN-FRAME(${window.location.href}))`);
  475. } else { console.info(`Complete the installation of user-script/remove-limits (${window.location.href}))`); }
  476. })();// ==UserScript==
  477. // @name Remove Restrictions and Restore Default Behavior
  478. // @name:zh-CN 解除网页限制,恢复默认行为
  479. // @name:zh-TW 解除網頁限制,恢復默認行爲
  480. // @name:ja-JP Webページの制限を削除し、デフォルトの動作に戻す
  481. // @name:ko-KR 웹 페이지 제한 제거 및 기본 동작 복원
  482. // @name:en-US Remove Restrictions and Restore Default Behavior
  483. // @name:fr-FR Supprimer les restrictions de page Web et restaurer le comportement par défaut
  484. // @name:de-DE Entfernen von Webseiteneinschränkungen und Wiederherstellen des Standardverhaltens
  485. // @name:it-IT Rimuovi le restrizioni delle pagine Web e ripristina il comportamento predefinito
  486. // @name:pt-BR Remover restrições de página da Web e restaurar o comportamento padrão
  487. // @name:es-ES Levantar las restricciones de la página web y restaurar el comportamiento predeterminado
  488. // @name:ru-RU Снятие ограничений веб-страниц и восстановление поведения по умолчанию
  489. // @namespace http://hl-bo.github.io/namespaces/user-script/remove-limits
  490. // @source https://github.com/HL-Bo/user-script
  491. // @supportURL https://github.com/HL-Bo/user-script/issues
  492. // @version 3.0
  493. // @license AGPLv3
  494. // @description Block the anti-debugging actions of the web page and reset the processing of certain actions (e.g., select, copy, open developer tools) of the web page to the corresponding browser default behavior.
  495. // @description:zh-CN 阻止网页的反调试措施并将网页对部分操作(如:选择、复制、打开开发者工具)处理重置为相应的浏览器默认行为。
  496. // @description:zh-TW 阻止網頁的反調試措施並將網頁對部分操作(如:選擇、複製、打開開發者工具)處理重置爲相應的瀏覽器默認行爲。
  497. // @description:ja-JP Web ページのアンチデバッグ アクションをブロックし、Web ページの特定のアクション (選択、コピー、開発者ツールを開くなど) の処理を対応するブラウザーの既定の動作にリセットします。
  498. // @description:ko-KR 웹 페이지의 디버깅 방지 작업을 차단하고 웹 페이지의 특정 작업(예: 개발자 도구 선택, 복사, 열기)의 처리를 해당 브라우저 기본 동작으로 재설정합니다.
  499. // @description:en-US Block the anti-debugging actions of the web page and reset the processing of certain actions (e.g., select, copy, open developer tools) of the web page to the corresponding browser default behavior.
  500. // @description:fr-FR Bloquez les actions anti-débogage de la page Web et réinitialisez le traitement de certaines actions (par exemple, sélectionner, copier, ouvrir les outils de développement) de la page Web au comportement par défaut du navigateur correspondant.
  501. // @description:de-DE Blockieren Sie die Anti-Debugging-Aktionen der Webseite und setzen Sie die Verarbeitung bestimmter Aktionen (z. B. Auswählen, Kopieren, Öffnen von Entwicklertools) der Webseite auf das entsprechende Standardverhalten des Browsers zurück.
  502. // @description:it-IT Blocca le azioni anti-debug della pagina Web e ripristina l'elaborazione di determinate azioni (ad esempio, seleziona, copia, apri gli strumenti di sviluppo) della pagina Web al comportamento predefinito del browser corrispondente.
  503. // @description:pt-BR Bloqueie as ações antidepuração da página da Web e redefina o processamento de determinadas ações (por exemplo, selecionar, copiar, abrir ferramentas de desenvolvedor) da página da Web para o comportamento padrão do navegador correspondente.
  504. // @description:es-ES Bloquear las medidas de anti - depuración de la página web y restablecer el procesamiento de la página web para algunas operaciones (como: seleccionar, copiar, abrir la herramienta del desarrollador) al comportamiento predeterminado del navegador correspondiente.
  505. // @description:ru-RU Заблокируйте антиотладочные действия веб-страницы и сбросьте обработку определенных действий (например, выбор, копирование, открытие средств разработчика) веб-страницы до соответствующего поведения браузера по умолчанию.
  506. // @author HL-Bo
  507. // @include https://example.com/**
  508. // @exclude https://example.org/**
  509. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAspJREFUWEfVl89PE1EQx7/TdpcabKFAoEKQH22ktEYSqRevXiRijEr8cSDe/DNM9D/xhPFn4oF4MeBZuJi0SiiQikTjD2gLCLS7jNmFLt2mu/uWYtB36G73zWQ+b2bevDeEijE5Od/Q3ut5CNA9gMOVc3bvG7+3MLeYRU9nhxqP9r2WURoPh8ObIvpUKTSbzkww6I6IYqWMAdAVxmCkF8z8zk/KFREIA2BmbilGu7tpZpigRGCqATQdAk3LKI46QRjGZtOZ6wx6KWKwWqYWgCbDzNN+UmwhDID3HxduEuP5UQKIQPx1gDJEnpTRoRqJaQnw/dcqVvPrANf2iST50N/dCSKCVQjMmjyVg3K1GsISILvyFT/X8pYRkXw+nD3TD4/HIwigp+ZUDkUThG0I9MVbeIAq9srW9g7SmSW0t4ZwPjHglEZvf3xZGkkmk6W93bI/qpNQUVVs7xRtPOBFgyzr88yM1PwidoolRE53oS3UbAuhMo8Mx/re2ALMZ5dRWLcuZlrsh2JReL1e3ZiWB5nsMlR118kDII/39v2xy09tAQobm8jrALVjIEsSOtpaTMZKioLVXAHaU/OK1fAAt65duvjMFsBxGXUIMGHswmDkhS2AtpK1wnodZg5UQ8EAWpqDxgchgIXPK8gdEUBzMKAnZ3kIAWgxLCmq9T4U9g1B8nn1gvV/ARx7CI49CYVDfAhBoSR0KkTidglNgUYETza6S0KtrO5VwvqHBhDt6XYH4HQYucHyN8jw7Z8Z+uElUgl1QePHjbkqWao4cvenhACcLiRukNpCTejpOuUuBE5XMmEAAlqaAmhvPTg5hTwgbOAQgv8mQD2NiVsnEPjGcDz6ynQfmPkwFyPJd6jWzA0AEZhLSjx5buCTCUD7M5temGDAdXPqCgB4MhyP3C3rmBrRVColb5H/kdv2XAyAvgH8+ARvP0gkEsZ1+w+ixcUwoQ+80AAAAABJRU5ErkJggg==
  510. // @grant none
  511. // @run-at document-start
  512. // ==/UserScript==
  513.  
  514. (function () {
  515. 'use strict';
  516. console.warn("CAUTION FOR NEGATIVE EFFECTS")
  517.  
  518. let in_frame = false;
  519. if (window.frameElement && window.frameElement.tagName === 'IFRAME' || window !== window.top) { in_frame = true; }
  520. if (!in_frame) {
  521. console.log(
  522. " ____ _ _ _ _ \n" +
  523. " | _ \\ ___ _ __ ___ ___ __ __ ___ | | (_) _ __ ___ (_) | |_ ___ \n" +
  524. " | |_) | / _ \\ | '_ ` _ \\ / _ \\ \\ \\ / / / _ \\ | | | | | '_ ` _ \\ | | | __| / __|\n" +
  525. " | _ < | __/ | | | | | | | (_) | \\ V / | __/ | |___ | | | | | | | | | | | |_ \\__ \\\n" +
  526. " |_| \\_\\ \\___| |_| |_| |_| \\___/ \\_/ \\___| |_____| |_| |_| |_| |_| |_| \\__| |___/\n" +
  527. " \n" +
  528. " By HL-Bo"
  529. );
  530. }
  531. if (in_frame) {
  532. console.debug(`Start the installation of user-script/remove-limits IN_FRAME(${window.location})`);
  533. } else { console.info(`Start the installation of user-script/remove-limits (${window.location})`); }
  534.  
  535. let dangerous_events = ['beforecopy', 'copy', 'beforecut', 'cut', 'beforepaste', 'paste', 'selectstart', 'contextmenu', 'dragstart', 'dragenter', 'dragover', 'dragleave', 'dragend', 'drop', 'keypress', 'keydown', 'keyup', 'visibilitychange', 'mousedown', 'mouseup', 'mousewheel', 'wheel', 'mouseenter', 'mousemove', 'mouseover', 'mouseout', 'mouseleave', 'gotpointercapture', 'lostpointercapture', 'pointerdown', 'pointerrawupdate', 'pointerup', 'pointerenter', 'pointermove', 'pointerover', 'pointerout', 'pointerleave', 'pointercancel', 'focus', 'focusin', 'focusout', 'blur'];
  536. let style_element_inner = '* { user-select: auto !important; -webkit-user-select: auto !important; -moz-user-select: auto !important; -ms-user-select: auto !important; }';
  537. let head_style_element = document.createElement('style');
  538. head_style_element.innerText = style_element_inner;
  539. let body_style_element = document.createElement('style');
  540. body_style_element.innerText = style_element_inner;
  541.  
  542. // 尝试禁用 debugger
  543. // 仅在 eval('debugger') 或 setInterval('debugger', sec) 构造前执行才能阻止
  544. try {
  545. Function.prototype.$rl_constructor = Function.prototype.constructor;
  546. Function.prototype.constructor = function () {
  547. if (arguments && typeof arguments[0] === 'string') {
  548. if ('debugger' === arguments[0]) {
  549. console.debug('Disable an function which may execute debugger');
  550. return;
  551. }
  552. }
  553. return Function.prototype.$rl_constructor.apply(this, arguments);
  554. };
  555. } catch (error) { console.warn(error); } finally { }
  556. // 防止清空控制台
  557. console.$rl_clear = console.clear;
  558. console.clear = function () { };
  559.  
  560. let executeWithInterval = function (func, delay) {
  561. setTimeout(func, 0); // 异步执行,防止阻塞
  562. setInterval(func, delay);
  563. };
  564. let logError = function (error) {
  565. let error_message = error.toString();
  566. if (document && document.body) {
  567. if (document.body.$rl_errors) {
  568. if (!document.body.$rl_errors.includes(error_message)) {
  569. if (in_frame) { console.debug(error_message); } else { console.warn(error_message); }
  570. document.body.$rl_errors.push(error_message);
  571. }
  572. } else { document.body.$rl_errors = new Array(); }
  573. }
  574. };
  575. let injectStyle = function () {
  576. if (document && document.head) {
  577. try { document.head.appendChild(head_style_element); } catch (error) { logError(error); } finally { }
  578. }
  579. if (document && document.body) {
  580. try { document.body.appendChild(head_style_element); } catch (error) { logError(error); } finally { }
  581. }
  582. };
  583. /*
  584. let getSelection = function () {
  585. if (window.getSelection)
  586. return (window.getSelection() || "").toString();
  587. if (document.getSelection)
  588. return (document.getSelection() || "").toString();
  589. if (document.selection)
  590. return document.selection.createRange().text;
  591. return "";
  592. };
  593. */
  594. let setEventListener = function (element, event_name, listener) {
  595. if (!element.$listen_event) {
  596. element.$listen_event = element.addEventListener;
  597. }
  598. element.addEventListener = function (event_name, listener, options) {
  599. if (event_name == dangerous_events) {
  600. element.$listen_event(event_name, (event) => { event.stopPropagation(); });
  601. } else {
  602. element.$listen_event(event_name, listener, options);
  603. }
  604. };
  605. if (!element.$rl_lazy_events) { element.$rl_lazy_events = new Map(); }
  606. if (!element.$rl_events) { element.$rl_events = new Map(); }
  607. if (!element.$rl_lazy_events.has(event_name)) {
  608. element.$rl_lazy_events.set(event_name, listener);
  609. element.$listen_event(event_name, listener);
  610. }
  611. if (!element.$rl_events.has(event_name)) {
  612. element.removeEventListener(event_name, element.$rl_events.get(event_name));
  613. element.$rl_events.set(event_name, listener);
  614. element.$listen_event(event_name, listener);
  615. }
  616. };
  617. let copyEventType = function (old_event) {
  618. /*
  619. Event
  620. +-- ClipboardEvent (cut, copy, paste)
  621. +-- UIEvent
  622. +-- FocusEvent (focus, blur, focusin, focusout, ...)
  623. +-- InputEvent
  624. +-- CompositionEvent (compositionstart, compositionupdate, compositionend, ...)
  625. +-- KeyboardEvent (keydown, keypress, keyup)
  626. +-- TouchEvent
  627. +-- MouseEvent (click, dblclick, mouseup, mousedown, ...)
  628. +-- PointerEvent
  629. +-- WheelEvent
  630. */
  631. let new_event_type = Event;
  632. if (old_event instanceof ClipboardEvent) { new_event_type = ClipboardEvent; }
  633. if (old_event instanceof UIEvent) { new_event_type = UIEvent; }
  634. if (old_event instanceof FocusEvent) { new_event_type = FocusEvent; }
  635. if (old_event instanceof InputEvent) { new_event_type = InputEvent; }
  636. if (old_event instanceof CompositionEvent) { new_event_type = CompositionEvent; }
  637. if (old_event instanceof KeyboardEvent) { new_event_type = KeyboardEvent; }
  638. if (old_event instanceof TouchEvent) { new_event_type = TouchEvent; }
  639. if (old_event instanceof MouseEvent) { new_event_type = MouseEvent; }
  640. if (old_event instanceof PointerEvent) { new_event_type = PointerEvent; }
  641. if (old_event instanceof WheelEvent) { new_event_type = WheelEvent; }
  642. return new_event_type;
  643. };
  644. let copyEventAttr = function (old_event) {
  645. let new_event_init_dict = {};
  646. new_event_init_dict.cancelable = false;
  647. if (old_event.bubbles) { new_event_init_dict.bubbles = old_event.bubbles; } // Event
  648. if (old_event.composed) { new_event_init_dict.composed = old_event.composed; } // Event
  649. if (old_event.detail) { new_event_init_dict.detail = old_event.detail; } // UIEvent
  650. if (old_event.view) { new_event_init_dict.view = old_event.view; } // UIEvent
  651. if (old_event.sourceCapabilities) { new_event_init_dict.sourceCapabilities = old_event.sourceCapabilities; } // UIEvent
  652. if (old_event.relatedTarget) { new_event_init_dict.relatedTarget = old_event.relatedTarget; } // FocusEvent
  653. if (old_event.screenX) { new_event_init_dict.screenX = old_event.screenX; } // MouseEvent
  654. if (old_event.screenY) { new_event_init_dict.screenY = old_event.screenY; } // MouseEvent
  655. if (old_event.clientX) { new_event_init_dict.clientX = old_event.clientX; } // MouseEvent
  656. if (old_event.clientY) { new_event_init_dict.screenX = old_event.clientY; } // MouseEvent
  657. if (old_event.key) { new_event_init_dict.key = old_event.key; } // KeyboardEvent
  658. if (old_event.code) { new_event_init_dict.code = old_event.code; } // KeyboardEvent
  659. if (old_event.location) { new_event_init_dict.location = old_event.location; } // KeyboardEvent
  660. if (old_event.touches) { new_event_init_dict.touches = old_event.touches; } // TouchEvent
  661. if (old_event.targetTouches) { new_event_init_dict.targetTouches = old_event.targetTouches; } // TouchEvent
  662. if (old_event.changedTouches) { new_event_init_dict.changedTouches = old_event.changedTouches; } // TouchEvent
  663. if (old_event.ctrlKey) { new_event_init_dict.ctrlKey = old_event.ctrlKey; } // MouseEvent & KeyboardEvent & TouchEvent
  664. if (old_event.shiftKey) { new_event_init_dict.shiftKey = old_event.shiftKey; } // MouseEvent & KeyboardEvent & TouchEvent
  665. if (old_event.altKey) { new_event_init_dict.altKey = old_event.altKey; } // MouseEvent & KeyboardEvent & TouchEvent
  666. if (old_event.metaKey) { new_event_init_dict.metaKey = old_event.metaKey; } // MouseEvent & KeyboardEvent & TouchEvent
  667. if (old_event.repeat) { new_event_init_dict.repeat = old_event.repeat; } // KeyboardEvent
  668. if (old_event.inputType) { new_event_init_dict.inputType = old_event.inputType; } // InputEvent
  669. if (old_event.isComposing) { new_event_init_dict.isComposing = old_event.isComposing; } // KeyboardEvent & InputEvent
  670. if (old_event.charCode) { new_event_init_dict.charCode = old_event.charCode; } // KeyboardEvent
  671. if (old_event.keyCode) { new_event_init_dict.keyCode = old_event.keyCode; } // KeyboardEvent
  672. if (old_event.which) { new_event_init_dict.which = old_event.which; } // KeyboardEvent
  673. if (old_event.button) { new_event_init_dict.button = old_event.button; } // MouseEvent
  674. if (old_event.buttons) { new_event_init_dict.buttons = old_event.buttons; } // MouseEvent
  675. if (old_event.relatedTarget) { new_event_init_dict.relatedTarget = old_event.relatedTarget; } // MouseEvent
  676. if (old_event.region) { new_event_init_dict.region = old_event.region; } // MouseEvent
  677. if (old_event.deltaX) { new_event_init_dict.deltaX = old_event.deltaX; } // WheelEvent
  678. if (old_event.deltaY) { new_event_init_dict.deltaY = old_event.deltaY; } // WheelEvent
  679. if (old_event.deltaZ) { new_event_init_dict.deltaZ = old_event.deltaZ; } // WheelEvent
  680. if (old_event.deltaMode) { new_event_init_dict.deltaMode = old_event.deltaMode; } // WheelEvent
  681. if (old_event.pointerId) { new_event_init_dict.pointerId = old_event.pointerId; } // PointerEvent
  682. if (old_event.width) { new_event_init_dict.width = old_event.width; } // PointerEvent
  683. if (old_event.height) { new_event_init_dict.height = old_event.height; } // PointerEvent
  684. if (old_event.pressure) { new_event_init_dict.pressure = old_event.pressure; } // PointerEvent
  685. if (old_event.tangentialPressure) { new_event_init_dict.tangentialPressure = old_event.tangentialPressure; } // PointerEvent
  686. if (old_event.tiltX) { new_event_init_dict.tiltX = old_event.tiltX; } // PointerEvent
  687. if (old_event.tiltY) { new_event_init_dict.tiltY = old_event.tiltY; } // PointerEvent
  688. if (old_event.twist) { new_event_init_dict.twist = old_event.twist; } // PointerEvent
  689. if (old_event.pointerType) { new_event_init_dict.pointerType = old_event.pointerType; } // PointerEvent
  690. if (old_event.isPrimary) { new_event_init_dict.isPrimary = old_event.isPrimary; } // PointerEvent
  691. if (old_event.dataTransfer) { new_event_init_dict.dataTransfer = old_event.dataTransfer; } // DragEvent
  692. if (old_event.clipboardData) { new_event_init_dict.clipboardData = old_event.clipboardData; } // ClipboardEvent
  693. if (old_event.dataType) { new_event_init_dict.dataType = old_event.dataType; } // ClipboardEvent
  694. if (old_event.data) { new_event_init_dict.data = old_event.data; } // ClipboardEvent & InputEvent & CompositionEvent
  695. return new_event_init_dict;
  696. };
  697. let copyEvent = function (old_event) {
  698. let event_type = copyEventType(old_event);
  699. let event_init = copyEventAttr(old_event);
  700. let new_event = new event_type(old_event.type, event_init);
  701. return new_event;
  702. };
  703. let returnEventAllowed = function (event) {
  704. if (event.defaultPrevented) {
  705. // 如果调用了 Event.preventDefault() ,则重新构建一个不可取消的事件。
  706. event.stopPropagation(); // 停止原事件冒泡,以防重复新建事件。
  707. let new_event = copyEvent(event);
  708. if (event.target) { event.target.dispatchEvent(new_event); } else { event.currentTarget.dispatchEvent(new_event); }
  709. event = new_event;
  710. }
  711. event.stopImmediatePropagation(); // 防止其它事件处理器被调用
  712. try { event.returnValue = true; } catch (error) { logError(error); } finally { }
  713. if (event.currentTarget === document) { console.debug(`Allow ${event.type}`); }
  714. };
  715. let allowEvent = function (element, event_name) {
  716. setEventListener(element, event_name, function (event) { returnEventAllowed(event); return true; });
  717. };
  718. let onKeyEvents = function (event) {
  719. let keyCode = event.keyCode || event.which || event.charCode;
  720. let ctrlKey = event.ctrlKey || event.metaKey;
  721. let shiftKey = event.shiftKey;
  722. if (ctrlKey && (keyCode == 65 || keyCode == 88 || keyCode == 67 || keyCode == 86 || keyCode == 83 || keyCode == 85)) {
  723. // Ctrl+A (select-all), Ctrl+X (cut), Ctrl+C (copy), Ctrl+V (paste), Ctrl+S (save), Ctrl+U (view-source)
  724. returnEventAllowed(event);
  725. } else if (ctrlKey && shiftKey && (keyCode == 73 || keyCode == 74 || keyCode == 67)) {
  726. // Ctrl+Shift+I (devtools), Ctrl+Shift+J (console), Ctrl+Shift+C (elements)
  727. returnEventAllowed(event);
  728. } else if (keyCode && keyCode == 123) { // F12
  729. returnEventAllowed(event);
  730. }
  731. return true;
  732. };
  733. let allowKeyEvents = function (element, event_name) {
  734. setEventListener(element, event_name, onKeyEvents);
  735. };
  736. let preventEventChecks = function (element) {
  737. for (let i of dangerous_events) {
  738. Object.defineProperty(element, 'on' + i,
  739. {
  740. get: () => { return (event) => false; },
  741. set: (value) => { if (value !== null) { console.debug('Prevent to set property'); } }
  742. }
  743. );
  744. }
  745. };
  746. let allowElement = function (element) {
  747. // 取消通过 JavaScript 实现的禁止复制
  748. try { element.onbeforecopy = null; } catch (error) { logError(error); } finally { allowEvent(element, 'beforecopy'); }
  749. try { element.oncopy = null; } catch (error) { logError(error); } finally { allowEvent(element, 'copy'); }
  750. // 取消通过 JavaScript 实现的禁止剪切实现的禁止复制
  751. try { element.onbeforecut = null; } catch (error) { logError(error); } finally { allowEvent(element, 'beforecut'); }
  752. try { element.oncut = null; } catch (error) { logError(error); } finally { allowEvent(element, 'cut'); }
  753. // 取消通过 JavaScript 实现的禁止粘贴
  754. try { element.onbeforepaste = null; } catch (error) { logError(error); } finally { allowEvent(element, 'beforepaste'); }
  755. try { element.onpaste = null; } catch (error) { logError(error); } finally { allowEvent(element, 'paste'); }
  756. // 取消通过 JavaScript 实现的禁止文字选择
  757. try { element.onselectstart = null; } catch (error) { logError(error); } finally { allowEvent(element, 'selectstart'); }
  758. // 取消通过 JavaScript 实现的禁止右键菜单
  759. try { element.oncontextmenu = null; } catch (error) { logError(error); } finally { allowEvent(element, 'contextmenu'); }
  760. // 取消通过 JavaScript 实现的禁止拖动
  761. try { element.ondragstart = null; } catch (error) { logError(error); } finally { allowEvent(element, 'dragstart'); }
  762. try { element.ondragenter = null; } catch (error) { logError(error); } finally { allowEvent(element, 'dragenter'); }
  763. try { element.ondragover = null; } catch (error) { logError(error); } finally { allowEvent(element, 'dragover'); }
  764. try { element.ondragleave = null; } catch (error) { logError(error); } finally { allowEvent(element, 'dragleave'); }
  765. try { element.ondragend = null; } catch (error) { logError(error); } finally { allowEvent(element, 'dragend'); }
  766. // try { element.ondrop = null; } catch (error) { logError(error); } finally { allowEvent(element, 'drop'); }
  767. // 取消通过 CSS 实现的禁止选中
  768. if (element.style) {
  769. try { element.style.mozUserSelect = 'auto'; } catch (error) { logError(error); } finally { }
  770. try { element.style.webkitUserSelect = 'auto'; } catch (error) { logError(error); } finally { }
  771. try { element.style.msUserSelect = 'auto'; } catch (error) { logError(error); } finally { }
  772. try { element.style.userSelect = 'auto'; } catch (error) { logError(error); } finally { }
  773. }
  774. // 取消通过 JavaScript 实现的禁用快捷键
  775. try { element.onkeypress = null; } catch (error) { logError(error); } finally { allowKeyEvents(element, 'keypress'); }
  776. try { element.onkeydown = null; } catch (error) { logError(error); } finally { allowKeyEvents(element, 'keydown'); }
  777. try { element.onkeyup = null; } catch (error) { logError(error); } finally { allowKeyEvents(element, 'keyup'); }
  778. // 取消通过 JavaScript 实现的页面离开检测
  779. try { element.onvisibilitychange = null; } catch (error) { logError(error); } finally { allowEvent(element, 'visibilitychange'); }
  780. // 取消通过 JavaScript 实现的鼠标离开检测
  781. // try { element.onmousedown = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mousedown'); }
  782. // try { element.onmouseup = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mouseup'); }
  783. // try { element.onmousewheel = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mousewheel'); }
  784. // try { element.onwheel = null; } catch (error) { logError(error); } finally { allowEvent(element, 'wheel'); }
  785. // try { element.onmouseenter = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mouseenter'); }
  786. // try { element.onmousemove = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mousemove'); }
  787. // try { element.onmouseover = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mouseover'); }
  788. try { element.onmouseout = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mouseout'); }
  789. try { element.onmouseleave = null; } catch (error) { logError(error); } finally { allowEvent(element, 'mouseleave'); }
  790. // 取消通过 JavaScript 实现的指针离开检测
  791. // try { element.ongotpointercapture = null; } catch (error) { logError(error); } finally { allowEvent(element, 'gotpointercapture'); }
  792. try { element.onlostpointercapture = null; } catch (error) { logError(error); } finally { allowEvent(element, 'lostpointercapture'); }
  793. // try { element.onpointerdown = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointerdown'); }
  794. // try { element.onpointerrawupdate = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointerrawupdate'); }
  795. try { element.onpointerup = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointerup'); }
  796. // try { element.onpointerenter = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointerenter'); }
  797. // try { element.onpointermove = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointermove'); }
  798. // try { element.onpointerover = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointerover'); }
  799. try { element.onpointerout = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointerout'); }
  800. try { element.onpointerleave = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointerleave'); }
  801. try { element.onpointercancel = null; } catch (error) { logError(error); } finally { allowEvent(element, 'pointercancel'); }
  802. // 取消通过 JavaScript 实现的焦点离开检测
  803. try { element.onfocus = null; } catch (error) { logError(error); } finally { allowEvent(element, 'focus'); }
  804. try { element.onfocusin = null; } catch (error) { logError(error); } finally { allowEvent(element, 'focusin'); }
  805. try { element.onfocusout = null; } catch (error) { logError(error); } finally { allowEvent(element, 'focusout'); }
  806. try { element.onblur = null; } catch (error) { logError(error); } finally { allowEvent(element, 'blur'); }
  807. // 取消通过 HTML 实现的表单项禁用/禁止修改
  808. try { if (element instanceof Element && element.hasAttribute('disabled')) { element.removeAttribute('disabled'); } } catch (error) { logError(error); } finally { }
  809. try { if (element instanceof Element && element.hasAttribute('readonly')) { element.removeAttribute('readonly'); } } catch (error) { logError(error); } finally { }
  810. // 防止 JavaScript 事件检测
  811. try { preventEventChecks(element); } catch (error) { logError(error); } finally { allowEvent(element, 'focusout'); }
  812. };
  813. let allowElementRecursion = function (element) {
  814. allowElement(element);
  815. for (let i of element.children) { allowElementRecursion(i); }
  816. };
  817. // let removeAllListeners = function (old_element) {
  818. // let new_element = old_element.cloneNode(true);
  819. // old_element.parentNode.replaceChild(new_element, old_element);
  820. // };
  821. let removeHiddenElements = function (element, recursion) {
  822. if ((element.hidden || element.style.display == 'none' || element.style.visibility == 'hidden' || ((element.style.height <= 0 || element.style.width <= 0) && element.style.overflow == 'hidden') && element.children.length <= 0)) {
  823. console.info(`Remove <${element.tagName} id='${element.id}' class='${element.className}' />`);
  824. element.remove();
  825. } else if (recursion) { for (let i of element.children) { removeHiddenElements(i, recursion); } }
  826. };
  827. let getMainContainerElement = function () {
  828. // 获取正文节点
  829. let main_container_element = null;
  830. if (document) {
  831. if (main_container_element === null) { // 检查 main 标签
  832. let elements = document.getElementsByTagName('main');
  833. if (elements.length > 0) { main_container_element = elements[0]; }
  834. }
  835. if (main_container_element === null) { // 检查 id='main' 的标签
  836. main_container_element = document.getElementById('main');
  837. }
  838. if (main_container_element === null) { // 检查 id='main-content' 的标签
  839. main_container_element = document.getElementById('main-content');
  840. }
  841. if (main_container_element === null) { // 检查 id='main-contents' 的标签
  842. main_container_element = document.getElementById('main-content');
  843. }
  844. if (main_container_element === null) { // 检查 id='content' 的标签
  845. main_container_element = document.getElementById('content');
  846. }
  847. if (main_container_element === null) { // 检查 id='contents' 的标签
  848. main_container_element = document.getElementById('contents');
  849. }
  850. if (main_container_element === null) { // 检查 class='main' 的标签
  851. let elements = document.getElementsByClassName('main');
  852. if (elements.length > 0) { main_container_element = elements[0]; }
  853. }
  854. if (main_container_element === null) { // 检查 class='main-content' 的标签
  855. let elements = document.getElementsByClassName('content');
  856. if (elements.length > 0) { main_container_element = elements[0]; }
  857. }
  858. if (main_container_element === null) { // 检查 class='main-contents' 的标签
  859. let elements = document.getElementsByClassName('content');
  860. if (elements.length > 0) { main_container_element = elements[0]; }
  861. }
  862. if (main_container_element === null) { // 检查 class='content' 的标签
  863. let elements = document.getElementsByClassName('content');
  864. if (elements.length > 0) { main_container_element = elements[0]; }
  865. }
  866. if (main_container_element === null) { // 检查 class='contents' 的标签
  867. let elements = document.getElementsByClassName('contents');
  868. if (elements.length > 0) { main_container_element = elements[0]; }
  869. }
  870. }
  871. return main_container_element;
  872. };
  873.  
  874. // 对抗延迟运行(即在此脚本执行后运行)的禁用程序和循环执行的禁用程序,
  875. executeWithInterval(
  876. (function () {
  877. if (window) {
  878. try { allowElement(window); } catch (error) { logError(error); } finally { }
  879. }
  880. }), 200
  881. );
  882. executeWithInterval(
  883. (function () {
  884. if (document) {
  885. try { allowElement(document); } catch (error) { logError(error); } finally { }
  886. }
  887. }), 200
  888. );
  889. executeWithInterval(
  890. (function () {
  891. if (document && document.body) {
  892. try { allowElement(document.body); } catch (error) { logError(error); } finally { }
  893. }
  894. }), 300
  895. );
  896. executeWithInterval(
  897. (function () {
  898. if (document && document.body) {
  899. try { allowElementRecursion(document.body); } catch (error) { logError(error); } finally { }
  900. }
  901. }), 3000
  902. );
  903. executeWithInterval(
  904. (function () {
  905. let mce = getMainContainerElement();
  906. if (document && mce) {
  907. try { allowElementRecursion(mce); } catch (error) { logError(error); } finally { }
  908. }
  909. }), 2000
  910. );
  911.  
  912. // 对抗延迟运行(即在此脚本执行后运行)的混淆程序和循环执行的混淆程序,
  913. setTimeout(
  914. // 延迟 1.0 秒,有助于动态加载的内容的显示。
  915. function () {
  916. executeWithInterval(
  917. // 每 3.0 秒执行一次。
  918. function () {
  919. if (document) {
  920. // 移除正文中的不可见元素
  921. try {
  922. let mce = getMainContainerElement();
  923. // 移除不可见元素
  924. if (mce) { removeHiddenElements(mce, true); }
  925. } catch (error) { logError(error); } finally { }
  926. }
  927. }, 3000
  928. );
  929. }, 1000
  930. );
  931. executeWithInterval(injectStyle, 500);
  932. /*
  933. // 安装 Service Worker 以过滤请求
  934. if ('serviceWorker' in navigator) {
  935. navigator.serviceWorker
  936. .register(
  937. 'https://cdn.jsdelivr.net/gh/HL-Bo/user-script/remove-limits/service-worker.js',
  938. { scope: window.location.origin + window.location.pathname }
  939. )
  940. .then((registration) => {
  941. if (in_frame) {
  942. console.debug(`Register service worker for ${registration.scope} (IN-FRAME)`);
  943. } else { console.info(`Register service worker for ${registration.scope}`); }
  944. })
  945. .catch((error) => { logError(error); });
  946. }
  947. */
  948. if (in_frame) {
  949. console.debug(`Complete the installation of user-script/remove-limits IN-FRAME(${window.location.href}))`);
  950. } else { console.info(`Complete the installation of user-script/remove-limits (${window.location.href}))`); }
  951. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址