Skip to content

Commit

Permalink
Add support for Spigot 1.10-1.12
Browse files Browse the repository at this point in the history
Signed-off-by: Christopher White <[email protected]>
  • Loading branch information
cswhite2000 committed Sep 9, 2023
1 parent 09052d0 commit 6742542
Show file tree
Hide file tree
Showing 10 changed files with 883 additions and 684 deletions.
6 changes: 5 additions & 1 deletion core/src/main/java/tc/oc/pgm/wool/WoolMatchModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.util.Vector;
import tc.oc.pgm.api.PGM;
import tc.oc.pgm.api.event.BlockTransformEvent;
Expand Down Expand Up @@ -205,7 +206,10 @@ public void placementCheck(final BlockTransformEvent event) {

@EventHandler
public void handleWoolCrafting(PrepareItemCraftEvent event) {
ItemStack result = event.getRecipe().getResult();
Recipe recipe = event.getRecipe();
if (recipe == null) return;

ItemStack result = recipe.getResult();
InventoryHolder holder = event.getInventory().getHolder();

if (holder instanceof Player) {
Expand Down
78 changes: 50 additions & 28 deletions util/src/main/java/tc/oc/pgm/util/bukkit/Platform.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,29 @@

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Supplier;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import tc.oc.pgm.util.ClassLogger;
import tc.oc.pgm.util.nms.NMSHacksNoOp;
import tc.oc.pgm.util.nms.NMSHacksPlatform;
import tc.oc.pgm.util.nms.v1_10_12.NMSHacks1_10_12;
import tc.oc.pgm.util.nms.v1_8.NMSHacks1_8;
import tc.oc.pgm.util.nms.v1_8.NMSHacksSportPaper;
import tc.oc.pgm.util.nms.v1_9.NMSHacks1_9;
import tc.oc.pgm.util.reflect.ReflectionUtils;

public enum Platform {
UNKNOWN("UNKNOWN", "UNKNOWN", NMSHacksNoOp.class, false),
SPORTPAPER_1_8("SportPaper", "1.8", NMSHacksSportPaper.class, false),
SPIGOT_1_8(
"Spigot",
"1.8", // NMSHacks1_8 causes issues with other versions, get it dynamically
(Class<? extends NMSHacksPlatform>)
ReflectionUtils.getClassFromName("tc.oc.pgm.util.nms.v1_8.NMSHacks1_8"),
false),
PAPER_1_8(
"Paper",
"1.8", // NMSHacks1_8 causes issues with other versions, get it dynamically
(Class<? extends NMSHacksPlatform>)
ReflectionUtils.getClassFromName("tc.oc.pgm.util.nms.v1_8.NMSHacks1_8"),
false),
SPIGOT_1_9("Spigot", "1.9", NMSHacks1_9.class, true),
PAPER_1_9("Paper", "1.9", NMSHacks1_9.class, true);
UNKNOWN("UNKNOWN", "UNKNOWN", "UNKNOWN", () -> NMSHacksNoOp.class, false),
SPORTPAPER_1_8("SportPaper", "1.8", "1.8", () -> NMSHacksSportPaper.class, false),
SPIGOT_1_8("Spigot", "1.8", "1.8", () -> NMSHacks1_8.class, false),
PAPER_1_8("Paper", "1.8", "1.8", () -> NMSHacks1_8.class, false),
SPIGOT_1_9("Spigot", "1.9", "1.9", () -> NMSHacks1_9.class, true),
PAPER_1_9("Paper", "1.9", "1.9", () -> NMSHacks1_9.class, true),
SPIGOT_1_10_12("Spigot", "1.10", "1.12", () -> NMSHacks1_10_12.class, true),
PAPER_1_10_12("Paper", "1.10", "1.12", () -> NMSHacks1_10_12.class, true);

private static ClassLogger logger = ClassLogger.get(Platform.class);;
public static Platform SERVER_PLATFORM = computeServerPlatform();
Expand All @@ -36,30 +33,49 @@ private static Platform computeServerPlatform() {
Server sv = Bukkit.getServer();
String versionString = sv == null ? "" : sv.getVersion();
for (Platform platform : Platform.values()) {
if (versionString.contains(platform.variant)
&& versionString.contains("MC: " + platform.majorVersion)) {
return platform;
for (String supportedMajorVersion : platform.getSupportedMajorVersions()) {
if (versionString.contains(platform.variant)
&& versionString.contains("MC: " + supportedMajorVersion)) {
return platform;
}
}
}
return UNKNOWN;
}

private final String variant;
private final String majorVersion;
private final Class<? extends NMSHacksPlatform> nmsHacksClass;
private final String majorVersionFirst, majorVersionLast;
private final Supplier<Class<? extends NMSHacksPlatform>> nmsHacksSupplier;
private final boolean requiresProtocolLib;

Platform(
String variant,
String majorVersion,
Class<? extends NMSHacksPlatform> nmsHacksClass,
String majorVersionFirst,
String majorVersionLast,
Supplier<Class<? extends NMSHacksPlatform>> nmsHacksSupplier,
boolean requiresProtocolLib) {
this.variant = variant;
this.majorVersion = majorVersion;
this.nmsHacksClass = nmsHacksClass;
this.majorVersionFirst = majorVersionFirst;
this.majorVersionLast = majorVersionLast;
this.nmsHacksSupplier = nmsHacksSupplier;
this.requiresProtocolLib = requiresProtocolLib;
}

private Set<String> getSupportedMajorVersions() {
if (majorVersionFirst.equals(majorVersionLast))
return new HashSet<>(Collections.singleton(majorVersionFirst));

Set<String> versions = new HashSet<>();

int min = Integer.parseInt(majorVersionFirst.split("\\.")[1]);
int max = Integer.parseInt(majorVersionLast.split("\\.")[1]);

for (int i = min; i <= max; i++) {
versions.add("1." + i);
}
return versions;
}

public NMSHacksPlatform getNMSHacks() {
if (this == UNKNOWN) {
Bukkit.getServer().getPluginManager().disablePlugin(BukkitUtils.getPlugin());
Expand All @@ -74,7 +90,8 @@ public NMSHacksPlatform getNMSHacks() {
if (this == SERVER_PLATFORM) {
try {
logger.info("Detected server: " + this.toString());
Constructor<? extends NMSHacksPlatform> constructor = nmsHacksClass.getConstructor();
Constructor<? extends NMSHacksPlatform> constructor =
nmsHacksSupplier.get().getConstructor();
constructor.setAccessible(true);
return constructor.newInstance();
} catch (InvocationTargetException
Expand All @@ -92,6 +109,11 @@ public NMSHacksPlatform getNMSHacks() {

@Override
public String toString() {
return this.variant + " (" + this.majorVersion + ")";
return this.variant
+ " ("
+ (this.majorVersionFirst.equals(this.majorVersionLast)
? this.majorVersionFirst
: this.majorVersionFirst + "-" + this.majorVersionLast)
+ ")";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ static EnumSet<Attribute> findMissingAttributes() {
}
}

return EnumSet.copyOf(missingAttributes);
return missingAttributes.isEmpty()
? EnumSet.noneOf(Attribute.class)
: EnumSet.copyOf(missingAttributes);
}

static org.bukkit.attribute.Attribute convertAttribute(Attribute attribute) {
Expand Down
33 changes: 32 additions & 1 deletion util/src/main/java/tc/oc/pgm/util/nms/reflect/Refl.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package tc.oc.pgm.util.nms.reflect;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
Expand All @@ -22,6 +24,30 @@ public interface Refl {
@Reflect.CB("entity.CraftPlayer.getHandle()")
Object getPlayerHandle(Player player);

@Reflect.CB("entity.CraftEntity.getHandle()")
Object getEntityHandle(Entity entity);

@Reflect.NMS("Entity.getWorld()")
Object getNmsWorldFromEntity(Object handle);

@Reflect.NMS("Entity.getId()")
int getEntityId(Object handle);

@Reflect.NMS("WorldServer.getTracker()")
Object getEntityTracker(Object worldServer);

@Reflect.NMS("EntityTracker.trackedEntities")
Object getTrackedEntities(Object entityTracker);

@Reflect.NMS(value = "IntHashMap.get()", parameters = int.class)
Object getIntHashMapMethod(Object intHashMap, int id);

@Reflect.NMS("EntityTrackerEntry.trackedPlayers")
Set getTrackedPlayers(Object trackerEntry);

@Reflect.NMS("EntityPlayer.getBukkitEntity()")
Player getBukkitPlayer(Object nmsHandle);

@Reflect.NMS("EntityPlayer.ping")
int getPlayerPing(Object handle);

Expand Down Expand Up @@ -71,6 +97,7 @@ interface NBTTagString {
Object build(String string);

@Reflect.Method("a_")
@Reflect.Method("c_")
String getString(Object item);
};

Expand Down Expand Up @@ -157,9 +184,13 @@ interface Block {
Object getBlockData(Object self);

@Reflect.Method("q")
@Reflect.Method(value = "q", parameters = IBlockData.class)
Object getMaterial(Object self);
}

@Reflect.NMS("IBlockData")
interface IBlockData {}
interface IBlockData {
@Reflect.Method("getMaterial")
Object getMaterial(Object self);
}
}
43 changes: 43 additions & 0 deletions util/src/main/java/tc/oc/pgm/util/nms/reflect/Reflect.java
Original file line number Diff line number Diff line change
@@ -1,52 +1,95 @@
package tc.oc.pgm.util.nms.reflect;

import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Reflect {
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(NMS.List.class)
@interface NMS {
String value();

Class<?>[] parameters() default {};

@Retention(RetentionPolicy.RUNTIME)
@interface List {
NMS[] value();
}
}

@Retention(RetentionPolicy.RUNTIME)
@Repeatable(CB.List.class)
@interface CB {
String value();

Class<?>[] parameters() default {};

@Retention(RetentionPolicy.RUNTIME)
@interface List {
CB[] value();
}
}

@Retention(RetentionPolicy.RUNTIME)
@Repeatable(B.List.class)
@interface B {
String value();

Class<?>[] parameters() default {};

@Retention(RetentionPolicy.RUNTIME)
@interface List {
B[] value();
}
}

@Retention(RetentionPolicy.RUNTIME)
@Repeatable(StaticMethod.List.class)
@interface StaticMethod {
String value();

Class<?>[] parameters() default {};

@Retention(RetentionPolicy.RUNTIME)
@interface List {
StaticMethod[] value();
}
}

@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Method.List.class)
@interface Method {
String value();

Class<?>[] parameters() default {};

@Retention(RetentionPolicy.RUNTIME)
@interface List {
Method[] value();
}
}

@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Field.List.class)
@interface Field {
String value();

@Retention(RetentionPolicy.RUNTIME)
@interface List {
Field[] value();
}
}

@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Constructor.List.class)
@interface Constructor {
Class<?>[] value() default {};

@Retention(RetentionPolicy.RUNTIME)
@interface List {
Constructor[] value();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl

@Nullable
private static Function<Object[], Object> processComponent(Method method, Object[] args) {
if (method.isAnnotationPresent(Reflect.NMS.class)) {
if (method.getDeclaredAnnotationsByType(Reflect.NMS.class).length > 0) {
return processNMSComponent(method, args);
} else if (method.isAnnotationPresent(Reflect.CB.class)) {
} else if (method.getDeclaredAnnotationsByType(Reflect.CB.class).length > 0) {
return processCBComponent(method, args);
} else if (method.isAnnotationPresent(Reflect.B.class)) {
} else if (method.getDeclaredAnnotationsByType(Reflect.B.class).length > 0) {
return processBukkitComponent(method, args);
}
throw new RuntimeException("Error processing Method: " + method);
Expand All @@ -58,13 +58,13 @@ private static Function<Object[], Object> processComponent(Method method, Object
@Nullable
private static Function<Object[], Object> processComponent(
Method method, Object[] args, Class<?> parentClass) {
if (method.isAnnotationPresent(Reflect.StaticMethod.class)) {
if (method.getDeclaredAnnotationsByType(Reflect.StaticMethod.class).length > 0) {
return processStaticMethod(method, parentClass);
} else if (method.isAnnotationPresent(Reflect.Method.class)) {
} else if (method.getDeclaredAnnotationsByType(Reflect.Method.class).length > 0) {
return processMethod(method, args, parentClass);
} else if (method.isAnnotationPresent(Reflect.Field.class)) {
} else if (method.getDeclaredAnnotationsByType(Reflect.Field.class).length > 0) {
return processField(method, args, parentClass);
} else if (method.isAnnotationPresent(Reflect.Constructor.class)) {
} else if (method.getDeclaredAnnotationsByType(Reflect.Constructor.class).length > 0) {
return processConstructor(method, parentClass);
}
throw new RuntimeException("Error processing method: " + method);
Expand All @@ -87,11 +87,11 @@ private static Function<Object[], Object> processStaticMethod(

private static Function<Object[], Object> processMethod(
Method method, Object[] args, Class<?> parentClass) {
for (Reflect.Method staticMethod : method.getDeclaredAnnotationsByType(Reflect.Method.class)) {
for (Reflect.Method reflectMethod : method.getDeclaredAnnotationsByType(Reflect.Method.class)) {
try {
Method reflectedMethod =
parentClass.getMethod(
staticMethod.value(), processParameters(staticMethod.parameters()));
reflectMethod.value(), processParameters(reflectMethod.parameters()));
return callMethod(args, reflectedMethod);
} catch (NoSuchMethodException ignored) {
}
Expand Down
Loading

0 comments on commit 6742542

Please sign in to comment.