About Code Patches
How do code patches work?
As you can probably imagine, the actual Discord source code is composed of many, many files. Each of these files are a module, and webpack bundles them all together into “chunks”. These chunks are then loaded by Discord when it starts up.
Each webpack module comes in the form of a “factory” function. Code patches work by intercepting the webpack loader before the factory function is called. Code patches can then be applied to the module and recompiled with eval, since each module can be compiled independently of each other.
Minified code
Discord’s code is minified, meaning there will only be whitespace where strictly necessary. Variable names are also minified, meaning if you had something like
var nekohaxx = true;it would become something like
var a=!0;when minified. The variable becomes as short as possible to save space, and the true value is replaced with !0 to save even more space.
Code patch structure
Each code patch has two parts: the find string/regex and an array of replacements in replacement.
Each replacement has a match string/regex and a replace string/function. The match string/regex is used to match a specific part of the module’s code, and the replac string/function is used to replace the matched part with something else.
Here’s an example of a code patch in the nekocord Settings plugin:
// ...patches: [ // ... { find: "Messages.ACTIVITY_SETTINGS", replacement: [ { match: /\{header:.{1,20}ACTIVITY_SETTINGS[^[]{1,30}\[(\i)\.WebSetting/, replace: `{header:"nekocord",divider:!0,settings:["NEKOCORD"]},$&` } ] }, // ...],// ...Before the match regex is used, all instances of \i are replaced with [A-Za-z_$][\\w$]* as a shorthand for matching any valid JavaScript identifier. This can be used for matching minified variable names.
Additionally, any instance of $self will be replaced with your plugin’s instance, allowing you to call methods or access properties of your plugin instance from within the code patch.
You’ll want to familiarize yourself with regular expressions if you’re going to be writing code patches, as they’re essential for matching parts of the module’s code.
How code patches are applied
The code of each Discord module is checked if it contains the find string/regex. If it does, each match/replace pair in the replacement array is applied to the module’s code. After all code patches have been applied, the module is re-evaluated with eval and substituted in place of the original module.