Reflectioned class as argument type

Discussion in 'Plugin Development' started by Chlorek, Jun 15, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    Chlorek

    I have no idea how to describe my problem. I need to use reflection (and I'm really dumb with such stuff because Java is my side-language). So I managed to code NMS class getter, and now I want to use it like this:
    Code:java
    1.  
    2. Class<?> nms_EntityHuman = Utils.getNMSClass("EntityHuman");
    3. public void SomeFunction(nms_EntityHuman entity)
    4. {
    5. // ...
    6. }
    7.  

    I googled a lot, I've found how to initialize new instance, get fields and stuff but no solution to this problem.
    Is it possible at all? I really need this!

    Thanks for help, Chlorek.
     
  2. Offline

    garbagemule

    Since Java and reflection aren't your strongest suit, perhaps you would be better off explaining what you are trying to accomplish, instead of assuming you have to do something a certain way.
     
  3. Offline

    Chlorek

  4. Offline

    Smerfa

    so you want use method that need EntityHuman as parameters, but you don't know how to cast object to it?
    You must get this method by reflections, then you can use it using objects without casting.
    like:
    classWithThatMethod.getMethod("thisMethod", getNMSClass("EntityHuman")).invoke(object)
    and object must be that EntityHuman, but it can be used as object like:
    Object object = new String();

    And that is still a string :)

    I hope you understand me :p
     
  5. Offline

    Chlorek

    Smerfa
    Thank you man! I understand almost everything but this: classWithThatMethod. What it shall be?
     
  6. Offline

    mazentheamazin

    Chlorek
    He is referencing to the argument that is given from the method:
    argument.getClass()
     
  7. Offline

    Smerfa

    like you have that:
    Code:
    public void SomeFunction(nms_EntityHuman entity)
    then this classWithThatMethod is this class where you have that method, and...I see small problem :D
    that should be .invoke(objectWithMethod, thisHumanEntity) if method is static then objectWithMethod will be null, but if isn't then if this method is in "MyClass" then 'objectWithMethod' must be instance of "MyClass" where you want use that method :p

    like
    Code:
    public class NMSClass
    {
      public void method(HumanEntity entity)
      {
        // code
      }
    }
    and we have:
    Code:
    Object nmsClassInstance = ...;
    Object entityHumanInstance = ...;
    Class<?> entityHumanClass = entityHumanInstance.getClass();
    Class<?> nmsClassClass = nmsClassInstance.getClass();
    nmsClassClass.getMethod("method", entityHumanClass).invoke(nmsClassInstance, entityHumanInstance);
     
    Chlorek likes this.
  8. Offline

    Chlorek

    mazentheamazin Smerfa
    Ok ok, figured it out.
    And what about fields? Can I do it like this to get inventory?
    Code:
    entity.getClass().getField("inventory").get(null)
    
    Not sure about get() argument...
     
  9. Offline

    Smerfa

    if field isn't static then you must select from what instance you want get that:
    Code:
    entity.getClass().getField("inventory").get(entity)
    
     
    Chlorek likes this.
  10. Offline

    Chlorek

    Smerfa
    I can't understand what is this NMSClass for... Actually I need just entityHumanClass, it's weird for me. I'm confused...

    #Edit
    Do I code it right?
    Code:java
    1. public AnvilContainer(Object entity) throws NoSuchFieldException, IllegalAccessException
    2. {
    3. super(entity.getClass().getField("inventory").get(entity), entity.getClass().getField("world").get(entity), 0, 0, 0, entity);
    4. }

    Just I don't know how to pass entity cuz it does not accept Object.

    #Edit
    I fixed my code a bit but still my IDE throws me arguments are invalid:
    Code:
    super(nms_EntityHuman.getClass().getField("inventory").get(entity), nms_EntityHuman.getClass().getField("world").get(entity), 0, 0, 0, entity);
    
     
  11. Offline

    Smerfa

    that any class from NMS from with you want use that method with HumanEntity as parameter type :)

    If that your own method... then just use Object as parameter type, without any reflections.
     
  12. Offline

    Chlorek

    [​IMG]
    Smerfa
    I'm a little annoying with these questions, I know, but you explain it really well. Help me please :D
     
  13. Offline

    Smerfa

    uuuu
    If you must use "super", that will be harder :D


    I see 4 ways:

    Create interface or abstract class that contains all methods, ale create classes using NMS (without reflections) for every needed version, and then you can creating classes like
    my.package.MyAbstractSometfing s = new my.package.nms.1_7_R3.MyAbstractSometfing()

    Or... try check if you can use null arguments (check in source code that you can use null or that will throw errors) and if yes, then use null arguments, and then using reflections do this same work like in constructor.

    Or... create modules, so when plugin is starting, you checking what version of MC is that, and then enable one of modules.
    In every module you have this same code but for other versions.

    Or... use super advanced byte code in runtime editors :p
     
    Chlorek likes this.
  14. Offline

    Chlorek

    Well ok... I give up for now, first time I am not able to do something... I'll try to do it another time. Nothing is impossible in coding!
    Thanks Smerfa for your help!
     
Thread Status:
Not open for further replies.

Share This Page