Skip to content

Structure Explanation

mastercoms edited this page Jan 16, 2021 · 1 revision

The Linkstone plugin takes the compiled classes from linkstone-shim and processes them according to their annotations. For more details see The Magic Behind.

The code for the transformation utilized Objectweb ASM and is therefore independent of Maven. This code is located in the linkstone-maven-plugin directory. There is only one single class in the whole project that depends on Maven. It triggers these patches during the maven build process.

Since I was not able to find some kind of class processor that allows to transform classfiles after compilation, the plugin runs after the compilation of the whole project finished. It reads all compiled classes from the output directory, processes them and writes them back.

Note that you must have the classfiles of all dependencies of the linkstone-shim project available to run the transformations. To generate the glue code for the @LDelegate annotation, all methods of the delegated interfaces must be known.

Here you can see that the classes from all dependencies and the classes from the linkstone-shim source directory (templates/) are put into one store that is later used for lookup.

Linkstone does not add the obc/nms classes/interfaces to the internal glowstone classes that implement the Bukkit interfaces.

  • This would require to transform the bytecode of the whole glowstone server on bootstrap, so it cannot be a plugin
  • The internal structure of Glowstone is not a 1 to 1 copy of CraftBukkit, therefore it might not always be possible to find a Glowstone class that is "equivalent" to a CraftBukkit class and can inherit the obc/nms interfaces/classes.
  • Fields in Glowstone classes may store data different than in CraftBukkit and are therefore impossible to implement. (e.g. CraftBukkit may store a value in a field of type Set, while Glowstone uses an int[])
  • Inner Glowstone can implement obc/nms interfaces, but they cannot implement nms/obc classes. If we have e.g. GlowPlayer extends GlowEntity, we cannot let the class GlowPlayer also extend CraftPlayer, since java allows each class to have only superclass.

This approach is therefore not implementable, especially due to the last two points, so another way was chosen that allows it to work like a plugin. Linkstone implements own classes with the names of the obc/nms classes/interfaces. These classes are actually wrappers/boxes around Glowstone instances and provide the nms/obc methods/fields/.... Therefore even methods/classes that have no equivalent in Glowstone can be implemented by Linkstone. Instead of creating Fields that exist in obc/nms classes, we define getter and setter methods that get invoked instead if the field is read/written.

Since this is all additional code that does not modify the internals of Glowstone, Linkstone can run as a plugin, but there is one issue: All this requires to transform the bytecode of Bukkit plugins that use nms/obc classes. The code that does the transformations is contained in the linkstone-runtime.