This commit is contained in:
Jiiks 2018-03-15 13:39:09 -03:00
parent 6d1dbfad1e
commit bd5ded7333
1 changed files with 51 additions and 47 deletions

View File

@ -13,25 +13,25 @@ import { ClientLogger as Logger } from 'common';
export default class Patcher {
static get patches() { return this._patches || (this._patches = {}) }
static resolveModule(mn) {
if (mn instanceof Function || (mn instanceof Object && !(mn instanceof Array))) return mn;
if ('string' === typeof mn) return WebpackModules.getModuleByName(mn);
if (mn instanceof Array) return WebpackModules.getModuleByProps(mn);
static resolveModule(module) {
if (module instanceof Function || (module instanceof Object && !(module instanceof Array))) return module;
if ('string' === typeof module) return WebpackModules.getModuleByName(module);
if (module instanceof Array) return WebpackModules.getModuleByProps(module);
return null;
}
static overrideFn(patch) {
return function () {
for (const s of patch.supers) {
for (const superPatch of patch.supers) {
try {
s.fn.apply(this, arguments);
superPatch.callback.apply(this, arguments);
} catch (err) {
Logger.err('Patcher', err);
}
}
const retVal = patch.ofn.apply(this, arguments);
for (const s of patch.slaves) {
const retVal = patch.originalFunction.apply(this, arguments);
for (const slavePatch of patch.slaves) {
try {
s.fn.apply(this, [arguments, { patch, retVal }]);
slavePatch.callback.apply(this, [arguments, { patch, retVal }]);
} catch (err) {
Logger.err('Patcher', err);
}
@ -40,59 +40,63 @@ export default class Patcher {
}
}
static rePatch(po) {
po.patch = po.module[po.fnn] = this.overrideFn(po);
static rePatch(patch) {
patch.proxyFunction = patch.module[patch.functionName] = this.overrideFn(patch);
}
static pushPatch(id, module, fnn) {
static pushPatch(id, module, functionName) {
const patch = {
module,
fnn,
ofn: module[fnn],
functionName,
originalFunction: module[functionName],
proxyFunction: null,
revert: () => {
patch.module[patch.fnn] = patch.ofn;
patch.patch = null;
patch.module[patch.functionName] = patch.originalFunction;
patch.proxyFunction = null;
patch.slaves = patch.supers = [];
},
supers: [],
slaves: [],
patch: null
slaves: []
};
patch.patch = module[fnn] = this.overrideFn(patch);
patch.proxyFunction = module[functionName] = this.overrideFn(patch);
return this.patches[id] = patch;
}
static superpatch(mn, fnn, cb, dn) {
const module = this.resolveModule(mn);
if (!module || !module[fnn] || !(module[fnn] instanceof Function)) return null;
const displayName = 'string' === typeof mn ? mn : dn || module.displayName || module.name || module.constructor.displayName || module.constructor.name;
const patchId = `${displayName}:${fnn}`;
const patchObject = this.patches[patchId] || this.pushPatch(patchId, module, fnn);
if (!patchObject.patch) this.rePatch(patchObject);
const id = patchObject.supers.length + 1;
const patch = {
id,
fn: cb,
unpatch: () => patchObject.supers.splice(patchObject.supers.findIndex(slave => slave.id === id), 1)
static superpatch(unresolveModule, functionName, callback, displayName) {
const module = this.resolveModule(unresolveModule);
if (!module || !module[functionName] || !(module[functionName] instanceof Function)) return null;
displayName = 'string' === typeof unresolveModule ? unresolveModule : displayName || module.displayName || module.name || module.constructor.displayName || module.constructor.name;
const patchId = `${displayName}:${functionName}`;
const patch = this.patches[patchId] || this.pushPatch(patchId, module, functionName);
if (!patch.proxyFunction) this.rePatch(patch);
const superPatch = {
id: patch.supers.length + 1,
callback,
unpactch: () => patch.slaves.splice(patch.slaves.findIndex(slave => slave.id === id), 1) // This doesn't actually work correctly not, fix in a moment
};
patchObject.supers.push(patch);
return patch;
patch.supers.push(superPatch);
return superPatch;
}
static slavepatch(mn, fnn, cb, dn) {
const module = this.resolveModule(mn);
if (!module || !module[fnn] || !(module[fnn] instanceof Function)) return null;
const displayName = 'string' === typeof mn ? mn : dn || module.displayName || module.name || module.constructor.displayName || module.constructor.name;
const patchId = `${displayName}:${fnn}`;
const patchObject = this.patches[patchId] || this.pushPatch(patchId, module, fnn);
if (!patchObject.patch) this.rePatch(patchObject);
const id = patchObject.slaves.length + 1;
const patch = {
id,
fn: cb,
unpatch: () => patchObject.slaves.splice(patchObject.slaves.findIndex(slave => slave.id === id), 1)
static slavepatch(unresolveModule, functionName, callback, displayName) {
const module = this.resolveModule(unresolveModule);
if (!module || !module[functionName] || !(module[functionName] instanceof Function)) return null;
displayName = 'string' === typeof unresolveModule ? unresolveModule : displayName || module.displayName || module.name || module.constructor.displayName || module.constructor.name;
const patchId = `${displayName}:${functionName}`;
const patch = this.patches[patchId] || this.pushPatch(patchId, module, functionName);
if (!patch.proxyFunction) this.rePatch(patch);
const slavePatch = {
id: patch.slaves.length + 1,
callback,
unpactch: () => patch.slaves.splice(patch.slaves.findIndex(slave => slave.id === id), 1) // This doesn't actually work correctly not, fix in a moment
};
patchObject.slaves.push(patch);
return patch;
patch.slaves.push(slavePatch);
return slavePatch;
}
}