Skip to content

Instantly share code, notes, and snippets.

@brzys
Created July 23, 2022 10:15
Show Gist options
  • Save brzys/edfd753880acfc768e655a220067a481 to your computer and use it in GitHub Desktop.
Save brzys/edfd753880acfc768e655a220067a481 to your computer and use it in GitHub Desktop.
class CrashDebug {
constructor() {
this.definitions = [];
this.ignoreList = [
'mp.game.system.vdist',
'mp.game.waitAsync',
'mp.game.controls.disableControlAction',
'mp.game.joaat',
'mp.game.entity.createModelHide',
'mp.game.pad.disableControlAction'
];
this.searchIgnoreList = ['draw', 'Text', 'Sprite', 'Frame', 'getCoord', 'toArray', 'at', 'atRemoteId', 'exists', 'execute'];
this.lookupObject(mp.game, 'mp.game', 'mp.game');
this.lookupObject(mp.__pools, 'mp.__pools', 'mp.__pools');
this.definitions.push({ func: mp.events.fire, sourceObject: mp.events, fullName: 'mp.events.fire', funcName: 'fire', sourceObjectName: 'mp.events' });
this.hook();
}
lookupObject(obj, objName, fullName) {
for (const key in obj) {
const value = obj[key];
if (typeof value === 'object') {
this.lookupObject(obj[key], key, `${fullName}.${key}`);
} else if (typeof value === 'function') {
const finalName = `${fullName}.${key}`;
if (!this.ignoreList.find((r) => r === finalName) && !this.searchIgnoreList.find((r) => finalName.search(r) !== -1)) {
const definition = {
func: value,
sourceObject: obj,
fullName: finalName,
funcName: key,
sourceObjectName: objName
};
this.definitions.push(definition);
}
}
}
}
hook() {
const self = this;
for (const definition of this.definitions) {
if (!(/^\s*class\s+/.test(definition.func.toString()))) { /* ES6 classes are not supported */
/* disable read-only property for function */
Object.defineProperty(definition.sourceObject, definition.funcName, { writable: true, configurable: true });
/* override function in mp object */
definition.sourceObject[definition.funcName] = function() {
/* handle mp.events.add callbacks */
if (definition.fullName === 'mp.events.fire') {
const eventName = arguments[0];
const eventCallback = arguments[1];
return self.tracker(definition, this, arguments, {
eventName,
eventCallback
});
}
return self.tracker(definition, this, arguments);
};
}
}
}
tracker(definition, thisContext, args, e) {
const logArguments = Array.prototype.slice.call(args).map((value) => (typeof value === 'function' ? '[ Function ]' : String(value)));
mp.console.logInfo(`${e ? e.eventName : definition.fullName}${e ? '' : `(${logArguments})`}\n`, true, false);
const sourceFunction = definition.func;
const result = sourceFunction.apply(thisContext, args);
return result;
}
}
new CrashDebug();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment