您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Hook most functions on runtime via the function name
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/469993/1214452/FunctionHookerjs.js
- // ==UserScript==
- // @name FunctionHooker.js
- // @namespace http://tampermonkey.net/
- // @version 0.1
- // @description Hook most functions on runtime via the function name
- // @author You
- // @match *://*.*
- // @grant none
- // ==/UserScript==
- class FunctionHooker {
- constructor() {
- this.hooks = new Map();
- this.originalName = "";
- }
- getOriginal(functionName) {
- return this.hooks.get(functionName);
- }
- hook(targetFunction, hookFunction) {
- const isString = typeof targetFunction == "string";
- // TODO: isString is used to eventually distinct a target function passed as a direct reference
- // to a function from the user passing a function name as a string
- // problem is there is no way to go from a function reference to a proper function name string
- const isFullyQualifiedName = targetFunction.indexOf('.') != -1;
- this.originalName = targetFunction;
- if (isFullyQualifiedName) { this.hookFullyQualified(targetFunction, hookFunction); return; }
- const originalFunction = window[targetFunction];
- if (originalFunction) {
- this.hooks.set(targetFunction, originalFunction);
- window[targetFunction] = hookFunction;
- } else {
- throw new Error(`Function '${targetFunction}' does not exist in the 'window' object.`);
- }
- }
- unhook(functionName) {
- const isFullyQualifiedName = functionName.indexOf('.') != -1;
- if (isFullyQualifiedName) { this.unhookFullyQualified(functionName); return; }
- const originalFunction = this.hooks.get(functionName);
- if (originalFunction) {
- window[functionName] = originalFunction;
- this.hooks.delete(functionName);
- } else {
- throw new Error(`Function '${functionName}' is not hooked.`);
- }
- }
- resolveFullyQualifiedFunctionName(functionName) {
- const functionNames = functionName.split('.');
- let resolvedFunction = window;
- for (const name of functionNames) {
- resolvedFunction = resolvedFunction[name];
- if (!resolvedFunction) {
- throw new Error(`Function '${functionName}' does not exist.`);
- }
- }
- return resolvedFunction;
- }
- hookFullyQualified(functionName, hookFunction) {
- const resolvedFunction = this.resolveFullyQualifiedFunctionName(functionName);
- const originalFunction = resolvedFunction;
- this.hooks.set(functionName, originalFunction);
- const parentObject = functionName
- .split('.')
- .slice(0, -1)
- .reduce((obj, prop) => (obj[prop] ? obj[prop] : obj), window);
- const functionNameLeaf = functionName.split('.').pop();
- if (typeof parentObject[functionNameLeaf] != 'function') { debugger; throw new Error(`Function '${this.originalName}' is not hooked.`); }
- parentObject[functionNameLeaf] = hookFunction;
- }
- unhookFullyQualified(functionName) {
- const resolvedFunction = this.resolveFullyQualifiedFunctionName(functionName);
- const originalFunction = this.hooks.get(functionName);
- if (originalFunction) {
- const parentObject = functionName
- .split('.')
- .slice(0, -1)
- .reduce((obj, prop) => (obj[prop] ? obj[prop] : obj), window);
- const functionNameLeaf = functionName.split('.').pop();
- parentObject[functionNameLeaf] = originalFunction;
- this.hooks.delete(functionName);
- } else {
- throw new Error(`Function '${functionName}' is not hooked.`);
- }
- }
- }