Skip to content

Commit

Permalink
Add Minecraft 1.16 support
Browse files Browse the repository at this point in the history
  • Loading branch information
rutgerkok committed Jun 27, 2020
1 parent 0c5581d commit 81df566
Show file tree
Hide file tree
Showing 4 changed files with 326 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
import nl.rutgerkok.blocklocker.impl.group.TownyGroupSystem;
import nl.rutgerkok.blocklocker.impl.group.mcMMOGroupSystem;
import nl.rutgerkok.blocklocker.impl.location.TownyLocationChecker;
import nl.rutgerkok.blocklocker.impl.nms.CNAccessor;
import nl.rutgerkok.blocklocker.impl.nms.OldNMSAccessor;
import nl.rutgerkok.blocklocker.impl.nms.NMSAccessor;
import nl.rutgerkok.blocklocker.impl.nms.ServerSpecific;
import nl.rutgerkok.blocklocker.impl.profile.ProfileFactoryImpl;
Expand Down Expand Up @@ -235,8 +235,8 @@ private Translator loadTranslations(String fileName) {
public void onEnable() {
// NMS checks
try {
nms = new CNAccessor();
} catch (ClassNotFoundException e) {
nms = new OldNMSAccessor();
} catch (Exception e) {
try {
nms = new NMSAccessor();
} catch (Throwable t) {
Expand Down
59 changes: 0 additions & 59 deletions src/main/java/nl/rutgerkok/blocklocker/impl/nms/CNAccessor.java

This file was deleted.

56 changes: 37 additions & 19 deletions src/main/java/nl/rutgerkok/blocklocker/impl/nms/NMSAccessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Optional;

import org.bukkit.Bukkit;
Expand All @@ -15,7 +16,7 @@

/**
* Implementation of methods required by
* nl.rutgerkok.chestsignprotect.impl.NMSAccessor for Minecraft 1.7.8 and 1.7.9.
* nl.rutgerkok.chestsignprotect.impl.NMSAccessor for Minecraft 1.16 and newer.
*
*/
public final class NMSAccessor implements ServerSpecific {
Expand All @@ -27,16 +28,7 @@ static Object call(Object on, Method method, Object... parameters) {
throw new RuntimeException(e);
}
}

static Object enumField(Class<Enum<?>> enumClass, String name) {
try {
Method valueOf = getMethod(Enum.class, "valueOf", Class.class, String.class);
return invokeStatic(valueOf, enumClass, name);
} catch (Exception e) {
throw new RuntimeException(e);
}
}


static Constructor<?> getConstructor(Class<?> clazz, Class<?>... paramTypes) {
try {
return clazz.getConstructor(paramTypes);
Expand All @@ -52,6 +44,30 @@ static Field getField(Class<?> clazz, String name) {
throw new RuntimeException(e);
}
}

static Object getStaticFieldValue(Class<?> clazz, String name) {
try {
return getField(clazz, name).get(null);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}

static Object getStaticFieldValue(Class<?> clazz, Class<?> typeOfField) {
for (Field field: clazz.getDeclaredFields()) {
try {
field.setAccessible(true);
if ((field.getModifiers() & Modifier.STATIC) == Modifier.STATIC && typeOfField.isAssignableFrom(field.getType())) {
return field.get(null);
}
} catch (SecurityException | IllegalAccessException e) {
// Ignore, if we're only looking for public fields we can safely ignore errors on accessing private fields.
// If we're accessing a private field, we'll get an error at the end of the method.
}

}
throw new RuntimeException("No accessible static field found on " + clazz + " of type " + typeOfField);
}

static Method getMethod(Class<?> clazz, String name, Class<?>... parameterTypes) {
try {
Expand Down Expand Up @@ -96,7 +112,6 @@ static Object retrieve(Object on, Field field) {
}

private final String nmsPrefix;

private final String obcPrefix;

final Class<?> BlockPosition;
Expand All @@ -108,12 +123,15 @@ static Object retrieve(Object on, Field field) {
final Constructor<?> ChatHoverable_new;
final Class<?> ChatModifier;
final Method ChatModifier_getGetHoverEvent;
final Constructor<?> ChatModifier_new;
final Object ChatModifier_defaultModifier;
final Class<?> CraftChatMessage;
final Method CraftChatMessage_fromComponent;
final Class<?> CraftWorld;
final Method CraftWorld_getHandle;
final Class<Enum<?>> EnumHoverAction;
/**
* Since Minecraft 1.16, this is not actually an enum anymore. Spigot didn't update the name, however.
*/
final Class<?> EnumHoverAction;
final Object EnumHoverAction_SHOW_TEXT;
final Class<?> IChatBaseComponent;
final Method IChatBaseComponent_getChatModifier;
Expand All @@ -135,7 +153,7 @@ public NMSAccessor() {
ChatModifier = getNMSClass("ChatModifier");
ChatHoverable = getNMSClass("ChatHoverable");
IChatBaseComponent = getNMSClass("IChatBaseComponent");
EnumHoverAction = getAnyNMSEnum("EnumHoverAction", "ChatHoverable$EnumHoverAction");
EnumHoverAction = getNMSClass("ChatHoverable$EnumHoverAction");
TileEntitySign = getNMSClass("TileEntitySign");
ChatComponentText = getNMSClass("ChatComponentText");

Expand All @@ -152,12 +170,12 @@ public NMSAccessor() {

ChatComponentText_new = getConstructor(ChatComponentText, String.class);
BlockPosition_new = getConstructor(BlockPosition, int.class, int.class, int.class);
ChatModifier_new = getConstructor(ChatModifier);
ChatHoverable_new = getConstructor(ChatHoverable, EnumHoverAction, IChatBaseComponent);
ChatHoverable_new = getConstructor(ChatHoverable, EnumHoverAction, Object.class);

ChatModifier_defaultModifier = getStaticFieldValue(ChatModifier, ChatModifier);
TileEntitySign_lines = getField(TileEntitySign, "lines");

EnumHoverAction_SHOW_TEXT = enumField(EnumHoverAction, "SHOW_TEXT");
EnumHoverAction_SHOW_TEXT = getStaticFieldValue(EnumHoverAction, "SHOW_TEXT");
}

private String chatComponentToString(Object chatComponent) {
Expand Down Expand Up @@ -265,7 +283,7 @@ private void setSecretData(Object tileEntitySign, String data) {
Object line = ((Object[]) retrieve(tileEntitySign, TileEntitySign_lines))[0];
Object modifier = call(line, IChatBaseComponent_getChatModifier);
if (modifier == null) {
modifier = newInstance(ChatModifier_new);
modifier = ChatModifier_defaultModifier;
}
Object chatComponentText = newInstance(ChatComponentText_new, data);
Object hoverable = newInstance(ChatHoverable_new, EnumHoverAction_SHOW_TEXT, chatComponentText);
Expand Down
Loading

0 comments on commit 81df566

Please sign in to comment.