11package me .theminecoder .minecraft .nmsproxy .proxy ;
22
3- import com .google .common .base .Joiner ;
43import com .google .common .collect .BiMap ;
54import com .google .common .collect .HashBiMap ;
65import com .google .common .collect .Maps ;
76import me .theminecoder .minecraft .nmsproxy .NMSProxy ;
8- import me .theminecoder .minecraft .nmsproxy .NMSSubclass ;
97import me .theminecoder .minecraft .nmsproxy .annotations .NMSClass ;
10- import net .bytebuddy .ByteBuddy ;
11- import net .bytebuddy .asm .Advice ;
12- import net .bytebuddy .dynamic .DynamicType ;
13- import net .bytebuddy .implementation .FixedValue ;
14- import net .bytebuddy .implementation .MethodCall ;
15- import net .bytebuddy .implementation .bytecode .assign .Assigner ;
16- import net .bytebuddy .pool .TypePool ;
178import org .bukkit .plugin .java .JavaPlugin ;
189
19- import java .io .File ;
20- import java .io .IOException ;
21- import java .lang .reflect .Method ;
22- import java .lang .reflect .Modifier ;
2310import java .lang .reflect .Proxy ;
2411import java .util .Arrays ;
2512import java .util .Map ;
26- import java .util .stream .Collectors ;
2713
2814/**
2915 * @author theminecoder
@@ -33,7 +19,6 @@ public final class NMSProxyProvider {
3319 private static final Map <JavaPlugin , NMSProxyProvider > PLUGIN_INSTANCES = Maps .newHashMap ();
3420
3521 private BiMap <Class , Class > proxyToNMSClassMap = HashBiMap .create ();
36- private static final Map <Class , DynamicType .Loaded > proxyToNMSSubclassMap = Maps .newHashMap (); //Can't have plugins overwriting each other
3722 private NMSProxyInvocationMapper invocationMapper = new NMSProxyInvocationMapper (proxyToNMSClassMap );
3823
3924 private NMSProxyProvider () {
@@ -132,65 +117,6 @@ public <T extends NMSProxy> T constructNMSObject(Class<T> clazz, Object... param
132117 return getNMSObject (clazz , nmsObject );
133118 }
134119
135- /**
136- * Constructs and returns an object that is a subclass of another NMS class.
137- * <p>
138- * Something of note here is that the class you use to define the subclass is not the same class you get back.
139- * This is due to the use of a dynamic class generator to do the backend work with subclassing.
140- *
141- * @param clazz Class implementing another {@link NMSProxy} and {@link NMSSubclass}
142- * @param params Objects to pass to the constructor of the final subclass
143- * @return The constructed object (Note that this is not wrapped in a proxy)
144- * @throws ReflectiveOperationException
145- */
146- public <T extends NMSSubclass > T constructNMSSubclass (Class <T > clazz , Object ... params ) throws ReflectiveOperationException {
147- if (clazz .getInterfaces ().length == 0 || NMSProxy .class .isAssignableFrom (clazz .getInterfaces ()[0 ])) {
148- throw new IllegalArgumentException ("Class does not implement a NMSProxy interface" );
149- }
150-
151- Class <? extends NMSProxy > proxyClass = (Class <? extends NMSProxy >) clazz .getInterfaces ()[0 ];
152- registerNMSClasses (proxyClass );
153-
154- DynamicType .Loaded <Object > dynamicType = proxyToNMSSubclassMap .get (proxyClass );
155- if (dynamicType == null ) {
156- Class nmsClass = proxyToNMSClassMap .get (proxyClass );
157- DynamicType .Builder <Object > builder = new ByteBuddy ().subclass (nmsClass ).name (clazz .getCanonicalName () + "$RuntimeGenerated" ).implement (clazz .getInterfaces ());
158-
159- System .out .println ("[SUBCLASSING][" + nmsClass .getSimpleName () + "->" + clazz .getSimpleName () + "] NMS Class Modifiers: " + Modifier .toString (nmsClass .getModifiers ()));
160- System .out .println ("[SUBCLASSING][" + nmsClass .getSimpleName () + "->" + clazz .getSimpleName () + "] Methods needing to be implemented for \" " + nmsClass .getCanonicalName () + "\" :" );
161- for (Method method : nmsClass .getDeclaredMethods ()) {
162- if (Modifier .isAbstract (method .getModifiers ())) {
163- System .out .println ("[SUBCLASSING][" + nmsClass .getSimpleName () + "->" + clazz .getSimpleName () + "] \t - " + Modifier .toString (method .getModifiers ()) + " " + method .getReturnType ().getSimpleName () + " " + method .getName () + "(" + Joiner .on (", " ).join (Arrays .stream (method .getParameterTypes ()).map (Class ::getSimpleName ).collect (Collectors .toList ())) + ")" );
164- }
165- }
166-
167- System .out .println ("[SUBCLASSING][" + nmsClass .getSimpleName () + "->" + clazz .getSimpleName () + "] Methods being implemented by \" " + clazz .getCanonicalName () + "\" :" );
168- for (Method method : clazz .getDeclaredMethods ()) {
169- System .out .println ("[SUBCLASSING][" + nmsClass .getSimpleName () + "->" + clazz .getSimpleName () + "] \t - " + Modifier .toString (method .getModifiers ()) + " " + method .getReturnType ().getSimpleName () + " " + method .getName () + "(" + Joiner .on (", " ).join (Arrays .stream (method .getParameterTypes ()).map (Class ::getSimpleName ).collect (Collectors .toList ())) + ")" );
170- }
171-
172- for (Method method : clazz .getDeclaredMethods ()) {
173- builder = builder .defineMethod (method .getName (), method .getReturnType (), method .getModifiers ())
174- .withParameters (Arrays .stream (method .getParameterTypes ()).map (type -> {
175- if (NMSProxy .class .isAssignableFrom (type )) {
176- registerNMSClasses ((Class <? extends NMSProxy >) type );
177- type = proxyToNMSClassMap .get (type );
178- }
179-
180- return type ;
181- }).collect (Collectors .toList ()))
182- .intercept (Advice .to (NMSProxySubclassAdvice .class ).wrap (MethodCall .invoke (method )));
183- }
184-
185- builder = builder .defineMethod ("getProxyHandle" , Object .class , Modifier .PUBLIC ).intercept (FixedValue .self ());
186-
187- dynamicType = builder .make (TypePool .ClassLoading .of (clazz .getClassLoader ())).load (clazz .getClassLoader ());
188- proxyToNMSSubclassMap .put (clazz , dynamicType );
189- }
190-
191- return (T ) dynamicType .getLoaded ().getConstructor (Arrays .stream (params ).map (Object ::getClass ).toArray (Class []::new )).newInstance (params );
192- }
193-
194120 Object [] unwrapArguments (Object [] args ) {
195121 if (args == null ) {
196122 return new Object []{};
@@ -211,32 +137,4 @@ Object unwrapArgument(Object arg) {
211137
212138 return arg ;
213139 }
214-
215- /**
216- * @author theminecoder
217- */
218- static class NMSProxySubclassAdvice {
219-
220- @ Advice .OnMethodEnter
221- static void enter (@ Advice .AllArguments (typing = Assigner .Typing .DYNAMIC ) Object [] args ) {
222- //Wrap back to proxy for original method
223- for (int i = 0 ; i < args .length ; i ++) {
224- Object arg = args [i ];
225- if (arg == null ) {
226- continue ;
227- }
228- try {
229- JavaPlugin plugin = JavaPlugin .getProvidingPlugin (args [i ].getClass ());
230- NMSProxyProvider proxyProvider = get (plugin );
231- Class proxyClass = proxyProvider .proxyToNMSClassMap .inverse ().get (args [i ].getClass ());
232- if (proxyClass != null ) {
233- args [i ] = proxyProvider .getNMSObject (proxyClass , arg );
234- }
235- } catch (Exception e ) {
236- }
237- }
238- }
239-
240- }
241-
242140}
0 commit comments