Skip to content
This repository was archived by the owner on Nov 8, 2021. It is now read-only.

Commit 9e320a9

Browse files
committed
Bunch of updates
- NullReference util to help with nms constructors - No longer required to use @NMSMethod annotation - support for default interface methods in newer jdks - added support to be loaded as a bungee plugin and standalone a jdk lib - @NMSField now defaults to getter - suppressed some warnings because of what this lib does
1 parent ef458e5 commit 9e320a9

File tree

12 files changed

+137
-26
lines changed

12 files changed

+137
-26
lines changed

pom.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.github.theminecoder</groupId>
88
<artifactId>NMSProxy</artifactId>
9-
<version>1.0-SNAPSHOT</version>
9+
<version>1.2-SNAPSHOT</version>
1010
<packaging>jar</packaging>
1111

1212
<name>NMSProxy</name>
@@ -68,12 +68,18 @@
6868
</repository>
6969
</repositories>
7070

71+
<!-- this isnt actually locked to any specific version of spigot or bungee, i just needed some base plugin classes -->
7172
<dependencies>
7273
<dependency>
7374
<groupId>org.spigotmc</groupId>
7475
<artifactId>spigot-api</artifactId>
7576
<version>1.12.2-R0.1-SNAPSHOT</version>
7677
<scope>provided</scope>
7778
</dependency>
79+
<dependency>
80+
<groupId>net.md-5</groupId>
81+
<artifactId>bungeecord-api</artifactId>
82+
<version>1.15-SNAPSHOT</version>
83+
</dependency>
7884
</dependencies>
7985
</project>
Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package me.theminecoder.minecraft.nmsproxy;
22

3-
import org.bukkit.Bukkit;
43
import org.bukkit.plugin.java.JavaPlugin;
54

65
/**
@@ -9,12 +8,4 @@
98
* @author theminecoder
109
*/
1110
public class NMSProxyPlugin extends JavaPlugin {
12-
13-
public static final String NMS_VERSION;
14-
15-
static {
16-
String packageName = Bukkit.getServer().getClass().getPackage().getName();
17-
NMS_VERSION = packageName.substring(packageName.lastIndexOf(".") + 1);
18-
}
19-
2011
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package me.theminecoder.minecraft.nmsproxy;
2+
3+
import net.md_5.bungee.api.plugin.Plugin;
4+
5+
/**
6+
* This is an empty shell because bungee.
7+
*
8+
* @author theminecoder
9+
*/
10+
public class NMSProxyPluginBungee extends Plugin {
11+
}

src/main/java/me/theminecoder/minecraft/nmsproxy/annotations/NMSClass.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
package me.theminecoder.minecraft.nmsproxy.annotations;
22

3-
import me.theminecoder.minecraft.nmsproxy.NMSProxyPlugin;
4-
53
import java.lang.annotation.ElementType;
64
import java.lang.annotation.Retention;
75
import java.lang.annotation.RetentionPolicy;
86
import java.lang.annotation.Target;
97

8+
import static me.theminecoder.minecraft.nmsproxy.proxy.NMSProxyProvider.NMS_VERSION;
9+
1010
/**
1111
* @author theminecoder
1212
*/
1313
@Target(ElementType.TYPE)
1414
@Retention(RetentionPolicy.RUNTIME)
1515
public @interface NMSClass {
1616

17+
public static final String USE_OTHER_VALUE = " ** __USE_OTHER_VALUE__ ** ";
18+
1719
public enum Type {
1820
NMS("net.minecraft.server.%version%."),
1921
CRAFTBUKKIT("org.bukkit.craftbukkit.%version%."),
@@ -30,12 +32,22 @@ public String getPrefix() {
3032
}
3133

3234
public String getClassName(String className) {
33-
return (prefix + className).replaceFirst("%version%", NMSProxyPlugin.NMS_VERSION);
35+
return (prefix + className).replaceFirst("%version%", NMS_VERSION);
3436
}
3537
}
3638

37-
Type type();
39+
/**
40+
* @deprecated Going to remove in 2.0 in favour os just prepending it to the value manually
41+
*/
42+
@Deprecated
43+
Type type() default Type.OTHER;
44+
45+
/**
46+
* @deprecated use value instead
47+
*/
48+
@Deprecated
49+
String className() default USE_OTHER_VALUE;
3850

39-
String className();
51+
String value() default USE_OTHER_VALUE;
4052

4153
}

src/main/java/me/theminecoder/minecraft/nmsproxy/annotations/NMSField.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ public enum Type {
1717
SETTER
1818
}
1919

20-
Type value();
20+
Type value() default Type.GETTER;
2121

22+
//TODO move this into repeatable annotation
2223
NMSVersionName[] versionNames() default {};
2324

2425
}

src/main/java/me/theminecoder/minecraft/nmsproxy/annotations/NMSMethod.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@
66
import java.lang.annotation.Target;
77

88
/**
9+
* @deprecated No longer required
910
* @author theminecoder
1011
*/
12+
@SuppressWarnings("DeprecatedIsStillUsed") //Gonna be here for a bit
1113
@Target(ElementType.METHOD)
1214
@Retention(RetentionPolicy.RUNTIME)
15+
@Deprecated
1316
public @interface NMSMethod {
1417

18+
//TODO move this into repeatable annotation
1519
NMSVersionName[] versionNames() default {};
1620

1721
}

src/main/java/me/theminecoder/minecraft/nmsproxy/proxy/NMSProxyInvocationHandler.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
/**
1616
* @author theminecoder
1717
*/
18+
@SuppressWarnings({"rawtypes", "unchecked"})
1819
public class NMSProxyInvocationHandler implements InvocationHandler {
1920

2021
private static Constructor<MethodHandles.Lookup> methodLookupConstructor;
@@ -45,11 +46,21 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
4546

4647
if (method.isDefault()) {
4748
final Class<?> declaringClass = method.getDeclaringClass();
49+
boolean extraClass = false;
4850
if (methodLookupConstructor == null) {
49-
methodLookupConstructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
51+
try {
52+
// idk when they changed this but just in case
53+
//noinspection JavaReflectionMemberAccess
54+
methodLookupConstructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
55+
} catch (NoSuchMethodException e) {
56+
methodLookupConstructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, Class.class, int.class);
57+
extraClass = true;
58+
}
5059
methodLookupConstructor.setAccessible(true);
5160
}
52-
return methodLookupConstructor.newInstance(declaringClass, -1) //Trusted Flag
61+
return (extraClass ?
62+
methodLookupConstructor.newInstance(declaringClass, null, -1) :
63+
methodLookupConstructor.newInstance(declaringClass, -1)) //Trusted Flag
5364
.unreflectSpecial(method, declaringClass)
5465
.bindTo(proxy)
5566
.invokeWithArguments(args);
@@ -59,7 +70,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
5970
throw new IllegalStateException("Proxy method \"" + method + "\" is attempting to call to instance method/field on a static proxy. Please mark the proxy method with @NMSStatic");
6071
}
6172

62-
if (method.getAnnotation(NMSMethod.class) != null || method.getDeclaringClass() == Object.class) {
73+
if (method.getAnnotation(NMSField.class) == null || method.getDeclaringClass() == Object.class) {
6374
NMSMethod nmsMethodAnnotation = method.getAnnotation(NMSMethod.class);
6475

6576
Object[] fixedArgs = proxyProvider.unwrapArguments(args);
@@ -83,7 +94,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
8394
}
8495

8596
return returnObject;
86-
} else if (method.getAnnotation(NMSField.class) != null) {
97+
} else {
8798
NMSField fieldAnnotation = method.getAnnotation(NMSField.class);
8899

89100
Field field = invocationMapper.findNMSField((Class<? extends NMSProxy>) proxy.getClass().getInterfaces()[0], method, fieldAnnotation);
@@ -107,9 +118,6 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
107118
field.set(invokerObject, proxyProvider.unwrapArgument(args[0]));
108119
return null;
109120
}
110-
} else {
111-
System.out.println("method @'s = " + Arrays.toString(method.getAnnotations()));
112-
throw new IllegalStateException("Proxy method \"" + method + "\" must have a annotation of either @NMSMethod or @NMSField");
113121
}
114122
}
115123
}

src/main/java/me/theminecoder/minecraft/nmsproxy/proxy/NMSProxyInvocationMapper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616
import java.util.Map;
1717
import java.util.concurrent.atomic.AtomicReference;
1818

19-
import static me.theminecoder.minecraft.nmsproxy.NMSProxyPlugin.NMS_VERSION;
19+
import static me.theminecoder.minecraft.nmsproxy.proxy.NMSProxyProvider.NMS_VERSION;
2020
import static me.theminecoder.minecraft.nmsproxy.util.ClassUtil.forEachClassPossibility;
2121

2222
/**
2323
* @author theminecoder
2424
*/
25+
@SuppressWarnings({"rawtypes", "unchecked"})
2526
public class NMSProxyInvocationMapper {
2627

2728
private final BiMap<Class, Class> proxyToNMSClassMap;

src/main/java/me/theminecoder/minecraft/nmsproxy/proxy/NMSProxyProvider.java

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import com.google.common.collect.Maps;
66
import me.theminecoder.minecraft.nmsproxy.NMSProxy;
77
import me.theminecoder.minecraft.nmsproxy.annotations.NMSClass;
8+
import me.theminecoder.minecraft.nmsproxy.util.NullReference;
9+
import org.bukkit.Bukkit;
810
import org.bukkit.plugin.java.JavaPlugin;
911

1012
import java.lang.reflect.Proxy;
@@ -14,8 +16,23 @@
1416
/**
1517
* @author theminecoder
1618
*/
19+
@SuppressWarnings({"rawtypes", "unchecked"})
1720
public final class NMSProxyProvider {
1821

22+
public static final String NMS_VERSION;
23+
24+
static {
25+
String LOADED_VERSION;
26+
try {
27+
String packageName = Bukkit.getServer().getClass().getPackage().getName();
28+
LOADED_VERSION = packageName.substring(packageName.lastIndexOf(".") + 1);
29+
} catch (LinkageError e) {
30+
//Not loaded in bukkit context
31+
LOADED_VERSION = "";
32+
}
33+
NMS_VERSION = LOADED_VERSION;
34+
}
35+
1936
private static final Map<JavaPlugin, NMSProxyProvider> PLUGIN_INSTANCES = Maps.newHashMap();
2037

2138
private BiMap<Class, Class> proxyToNMSClassMap = HashBiMap.create();
@@ -43,9 +60,23 @@ private void registerNMSClasses(Class<? extends NMSProxy> clazz) {
4360
throw new IllegalStateException("NMSProxy interfaces must have a valid @NMSClass annotation");
4461
}
4562

63+
// this is by design
64+
//noinspection StringEquality
65+
if(nmsClassAnnotation.value() == NMSClass.USE_OTHER_VALUE && nmsClassAnnotation.className() == NMSClass.USE_OTHER_VALUE) {
66+
throw new IllegalStateException("Please set the value property in the @NMSClass annotation of "+clazz);
67+
}
68+
69+
String className;
70+
//noinspection StringEquality
71+
if(nmsClassAnnotation.value() != NMSClass.USE_OTHER_VALUE) {
72+
className = nmsClassAnnotation.value();
73+
} else {
74+
className = nmsClassAnnotation.className();
75+
}
76+
4677
Class nmsClass;
4778
try {
48-
nmsClass = Class.forName(nmsClassAnnotation.type().getClassName(nmsClassAnnotation.className()));
79+
nmsClass = Class.forName(nmsClassAnnotation.type().getClassName(className)); //TODO Move %version% replacement here
4980
} catch (ClassNotFoundException e) {
5081
throw new IllegalStateException("Class " + nmsClassAnnotation.className() + " (" + nmsClassAnnotation.type() + ") was not found!");
5182
}
@@ -109,9 +140,26 @@ public <T extends NMSProxy> T getNMSObject(Class<T> clazz, Object object) {
109140
public <T extends NMSProxy> T constructNMSObject(Class<T> clazz, Object... params) throws ReflectiveOperationException {
110141
registerNMSClasses(clazz);
111142

143+
NullReference[] nullReferences = new NullReference[params.length];
112144
Object[] fixedArgs = unwrapArguments(params);
145+
146+
//pull out null references and swap them to null
147+
for (int i = 0; i < fixedArgs.length; i++) {
148+
if(fixedArgs[i] instanceof NullReference) {
149+
nullReferences[i] = (NullReference) fixedArgs[i];
150+
fixedArgs[i] = null;
151+
}
152+
}
153+
113154
Class[] fixedArgTypes = Arrays.stream(fixedArgs).map(Object::getClass).toArray(Class[]::new);
114155

156+
//swap type search with null reference types
157+
for (int i = 0; i < nullReferences.length; i++) {
158+
if(nullReferences[i] != null) {
159+
fixedArgTypes[i] = nullReferences[i].getType();
160+
}
161+
}
162+
115163
Object nmsObject = invocationMapper.findNMSConstructor(clazz, fixedArgTypes).newInstance(fixedArgs);
116164

117165
return getNMSObject(clazz, nmsObject);

src/main/java/me/theminecoder/minecraft/nmsproxy/util/ClassUtil.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
/**
1212
* @author theminecoder
1313
*/
14-
public class ClassUtil {
14+
@SuppressWarnings("rawtypes")
15+
public final class ClassUtil {
1516

1617
private static final BiMap<Class, Class> PRIMITIVE_TO_CHECK_CLASS_MAP = HashBiMap.create();
1718

@@ -51,6 +52,7 @@ public static void forEachClassPossibility(Class[] types, Predicate<Class[]> con
5152
});
5253

5354
int solutions = 1;
55+
//noinspection StatementWithEmptyBody
5456
for (int i = 0; i < classPossibilities.size(); solutions *= classPossibilities.get(i).size(), i++) ;
5557
for (int i = 0; i < solutions; i++) {
5658
int j = 1;

0 commit comments

Comments
 (0)