/MixBukkit

A Mixin framework for Spigot/Bukkit that allows you to hook custom event anywhere. Start coding your advanced plugins today!

Primary LanguageJava

MixBukkit MixBukkit is a mixin framework inspired by SpongePowered's Mixin framework using ASM.

When will you need it

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.

Environment

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

Basic Usage

(Please check docs/Getting Started.md for more information)

Mapping

Method 1. Use Spigot's Members Mapping

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

Method 2. Use custom 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.

  1. Run buildtool with this following command: java -jar BuildTool.jar --rev <version that supports remapping> --remapped
  2. After that, go to your local maven repository (usually {user.home}/.m2/repository), and copy minecraft-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
  3. Paste that file into the same directory as plugin.yml, and name it to anything you want. For example: mapping.csrg

Bad way of loading a custom members mapping

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).

Register MixinPlugin

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!

Project Keywords/Tips and tricks

ShellCode

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 (MAction)

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 (HLocator)

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())

Advanced Usage

Coming Soon! (JavaDoc also coming soon : D )

Gallery