MixBukkit is a mixin framework inspired by SpongePowered's Mixin framework using ASM.
Let's say you want to hook something in Skeleton.class
, but obviously you can't just edit spigot source code. Having a custom build just for a plugin is ridiculous. MixBukkit provides an easy to use API that allows you to hook anything in NMS/CraftBukkit/Spigot API/Plugins and even libraries.
In theory, it should work from Java 8 ~ Java latest, Linux & Windows & MacOS, but I only tested it on Linux with Java 17.
Minecraft version is not limited, but it will result in mapping different
(Please check docs/Getting Started.md
for more information)
If you want to make things easy/fast/good/great/simple, you can use this method. Simply skip to next step, you don't need to worry about mapping
Since we get an AutoMapper, you can use it instead, but you can also do this if
you have a custom mapping to load. Doing the following thing will get you a
working vanilla mapping. You can also grab it from %server_root%/mappings.csrg
.
- Run buildtool with this following command:
java -jar BuildTool.jar --rev <version that supports remapping> --remapped
- After that, go to your local maven repository (usually
{user.home}/.m2/repository
), and copyminecraft-server-<version>-maps-spigot-members.csrg
. For example, it's in/home/fan87/.m2/repository/org/spigotmc/minecraft-server/1.18.1-R0.1-SNAPSHOT/
on my computer - Paste that file into the same directory as
plugin.yml
, and name it to anything you want. For example:mapping.csrg
Do not replace %server_root%/mappings.csrg
to load a custom mapping. It
will probably kill all plugins that is using Mixin.
Unless you want to make the mapping globally (let's say you are the user, you can do this).
If you wish to use Spigot's members mapping:
// onEnable()
MixinPlugin mixinPlugin = MixBukkit.registerMixinPlugin(this, AutoMapper.getMappingAsStream());
If you wish to use a custom members mapping:
// onEnable()
MixinPlugin mixinPlugin = MixBukkit.registerMixinPlugin(this, TestMixin.class.getClassLoader().getResourceAsStream("mapping.csrg" /* Type the mapping location here */));
After registering MixinPlugin, you can start registering mixins.
Please check TestMixin/
module for examples!
Also be known as Bytecode Generator. For example: ShellCodeReflectionPluginMethodCall
uses reflection to call plugin methods. Every shellcode should get an annotation: ShellCodeInfo
, which contains information about the shellcode. While implementing your own the shellcode, you should always annotate it with @ShellCodeInfo with required information.
To get a list of ShellCodes, simply type ShellCode
in your IDE and let it auto completes:
MixinAction has ability to modify entire method,
which is the lowest level of mixin. If you want to do something special
other than inserting shellcode (for example: replace it with a super call, trash the method),
you can use this. Same as shellcode, you can do get a list of MixinAction with MAction
and let the IDE list them for you.
Here's an example MixinAction (MActionMethodTrasher), which trashes entire method and replace them with nothing. Note that it doesn't work with variables requires a return value:
HookLocator will return a list of instruction index.
Let's say you want to inject a shellcode into the top of the method,
you would want to use new MActionInsertShellCode(shellCode, new HLocatorTop())
Coming Soon! (JavaDoc also coming soon : D )