make patcher more robust + fix collisions
This commit is contained in:
parent
42957dbb16
commit
a081a8fdf9
|
@ -13,14 +13,15 @@ import { ClientLogger as Logger } from 'common';
|
||||||
|
|
||||||
export class Patcher {
|
export class Patcher {
|
||||||
|
|
||||||
static get patches() { return this._patches || (this._patches = {}) }
|
static get patches() { return this._patches || (this._patches = []) }
|
||||||
|
|
||||||
static getPatchesByCaller(id) {
|
static getPatchesByCaller(id) {
|
||||||
|
if (!id) return [];
|
||||||
const patches = [];
|
const patches = [];
|
||||||
for (const patch in this.patches) {
|
for (const patch of this.patches) {
|
||||||
if (this.patches.hasOwnProperty(patch)) {
|
for (const childPatch of patch.children) {
|
||||||
if (this.patches[patch].caller === id) patches.push(this.patches[patch]);
|
if (childPatch.caller === id) patches.push(childPatch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return patches;
|
return patches;
|
||||||
}
|
}
|
||||||
|
@ -30,9 +31,7 @@ export class Patcher {
|
||||||
patches = this.getPatchesByCaller(patches);
|
patches = this.getPatchesByCaller(patches);
|
||||||
|
|
||||||
for (const patch of patches) {
|
for (const patch of patches) {
|
||||||
for (const child of patch.children) {
|
patch.unpatch();
|
||||||
child.unpatch();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +44,7 @@ export class Patcher {
|
||||||
static overrideFn(patch) {
|
static overrideFn(patch) {
|
||||||
return function () {
|
return function () {
|
||||||
let retVal = undefined;
|
let retVal = undefined;
|
||||||
if (!patch.children) return patch.originalFunction.apply(this, arguments);
|
if (!patch.children || !patch.children.length) return patch.originalFunction.apply(this, arguments);
|
||||||
for (const superPatch of patch.children.filter(c => c.type === 'before')) {
|
for (const superPatch of patch.children.filter(c => c.type === 'before')) {
|
||||||
try {
|
try {
|
||||||
superPatch.callback(this, arguments);
|
superPatch.callback(this, arguments);
|
||||||
|
@ -60,7 +59,8 @@ export class Patcher {
|
||||||
} else {
|
} else {
|
||||||
for (const insteadPatch of insteads) {
|
for (const insteadPatch of insteads) {
|
||||||
try {
|
try {
|
||||||
retVal = insteadPatch.callback(this, arguments);
|
const tempReturn = insteadPatch.callback(this, arguments, patch.originalFunction.bind(this));
|
||||||
|
if (typeof(tempReturn) !== "undefined") retVal = tempReturn;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.err(`Patcher:${patch.id}`, err);
|
Logger.err(`Patcher:${patch.id}`, err);
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,8 @@ export class Patcher {
|
||||||
|
|
||||||
for (const slavePatch of patch.children.filter(c => c.type === 'after')) {
|
for (const slavePatch of patch.children.filter(c => c.type === 'after')) {
|
||||||
try {
|
try {
|
||||||
slavePatch.callback(this, arguments, retVal, r => retVal = r);
|
const tempReturn = slavePatch.callback(this, arguments, retVal, r => retVal = r);
|
||||||
|
if (typeof(tempReturn) !== "undefined") retVal = tempReturn;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.err(`Patcher:${patch.id}`, err);
|
Logger.err(`Patcher:${patch.id}`, err);
|
||||||
}
|
}
|
||||||
|
@ -95,13 +96,13 @@ export class Patcher {
|
||||||
revert: () => { // Calling revert will destroy any patches added to the same module after this
|
revert: () => { // Calling revert will destroy any patches added to the same module after this
|
||||||
patch.module[patch.functionName] = patch.originalFunction;
|
patch.module[patch.functionName] = patch.originalFunction;
|
||||||
patch.proxyFunction = null;
|
patch.proxyFunction = null;
|
||||||
patch.slaves = patch.supers = [];
|
patch.children = [];
|
||||||
},
|
},
|
||||||
counter: 0,
|
counter: 0,
|
||||||
children: []
|
children: []
|
||||||
};
|
};
|
||||||
patch.proxyFunction = module[functionName] = this.overrideFn(patch);
|
patch.proxyFunction = module[functionName] = this.overrideFn(patch);
|
||||||
return this.patches[id] = patch;
|
return this.patches.push(patch), patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
static before() { return this.pushChildPatch(...arguments, 'before') }
|
static before() { return this.pushChildPatch(...arguments, 'before') }
|
||||||
|
@ -115,7 +116,7 @@ export class Patcher {
|
||||||
displayName || module.displayName || module.name || module.constructor.displayName || module.constructor.name;
|
displayName || module.displayName || module.name || module.constructor.displayName || module.constructor.name;
|
||||||
const patchId = `${displayName}:${functionName}:${caller}`;
|
const patchId = `${displayName}:${functionName}:${caller}`;
|
||||||
|
|
||||||
const patch = this.patches[patchId] || this.pushPatch(caller, patchId, module, functionName);
|
const patch = this.patches.find(p => p.module == module && p.functionName == functionName) || this.pushPatch(caller, patchId, module, functionName);
|
||||||
if (!patch.proxyFunction) this.rePatch(patch);
|
if (!patch.proxyFunction) this.rePatch(patch);
|
||||||
const child = {
|
const child = {
|
||||||
caller,
|
caller,
|
||||||
|
@ -124,7 +125,11 @@ export class Patcher {
|
||||||
callback,
|
callback,
|
||||||
unpatch: () => {
|
unpatch: () => {
|
||||||
patch.children.splice(patch.children.findIndex(cpatch => cpatch.id === child.id && cpatch.type === type), 1);
|
patch.children.splice(patch.children.findIndex(cpatch => cpatch.id === child.id && cpatch.type === type), 1);
|
||||||
if (patch.children.length <= 0) delete this.patches[patchId];
|
if (patch.children.length <= 0) {
|
||||||
|
let patchNum = this.patches.findIndex(p => p.module == module && p.functionName == functionName);
|
||||||
|
this.patches[patchNum].revert();
|
||||||
|
this.patches.splice(patchNum, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
patch.children.push(child);
|
patch.children.push(child);
|
||||||
|
|
Loading…
Reference in New Issue