Box annotation - GlowstoneMC/Linkstone GitHub Wiki
Plugins use CraftBukkit by casting instances of Bukkit API interfaces to concrete CraftBukkit implementations. A plugin would for instance cast a Player to a CraftPlayer but that does not work on Glowstone. If you've got a Player instance on Glowstone, then it will not be implemented by CraftPlayer. It's implemented by GlowPlayer.
Linkstone provides NMS/OBC classes that are wrappers/boxes around Glowstone classes.
These wrappers are annotation with a @LBox annotation. When ever a value is casted to one of these annotated classes, the cast gets replaced against wrapping the object into that box.
Here's an example box class:
// The annotation tell the Linkstone framework,
// that this class is a box that wraps GlowPlayers.
@LBox(GlowPlayer.class)
public class CraftPlayer {
// The @LBoxed annotation must be attached to the field that contains the wrapped value.
// The toString, hashCode and equals method are delegated to that field.
@LBoxed
private final GlowPlayer glow;
public CraftPlayer(GlowPlayer glow) {
this.glow = glow;
}
}If a plugin contains a cast to the CraftPlayer class, it will get replaced against wrapping the object into the CraftBukkit box.
Boxes should not be initialized by using the new keyword since all box instances are stored in a global cache. Use the Linkstone.<TypeToBox>box(objectToBox) instead.
Here's an exemplary implementation for the getHandle method in CraftPlayer.
It wraps the GlowPlayer in an EntityPlayer box.
public EntityPlayer getHandle() {
// We could drop the type parameter since the
// java compiler is able to interfere it.
return Linkstone.<EntityPlayer>box(glow);
}