Solved [Reflection] How would I get the ChatMessage constructor?

Discussion in 'Plugin Development' started by Zombie_Striker, Jan 2, 2017.

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

    Zombie_Striker

    Code:
    Code:
    private static Class<?> CHATMESSAGE = null;
       private static Constructor<?> CHATMESSAGE_CONSTRUCTOR = null;
       private static final String SERVER_VERSION;
    
       static {
         String name = Bukkit.getServer().getClass().getName();
         name = name.substring(name.indexOf("craftbukkit.")
             + "craftbukkit.".length());
         name = name.substring(0, name.indexOf("."));
         SERVER_VERSION = name;
    
         try {
          ......
           ICHATCOMP = Class.forName("net.minecraft.server." + SERVER_VERSION
               + ".IChatBaseComponent");
          .....
          
           CHATMESSAGE = Class.forName("net.minecraft.server."+SERVER_VERSION+".ChatMessage");
           try{
           CHATMESSAGE_CONSTRUCTOR = Optional.of(
               CHATMESSAGE.getConstructor(String.class)).get();
           }catch(NoSuchMethodException e){
             CHATMESSAGE_CONSTRUCTOR = Optional.of(CHATMESSAGE.getDeclaredConstructor(String.class)).get();
           }
    

    Problem:
    .
    I am trying to send the PacketPlayOutChat packet, but it must work on all versions of bukkit/spigot, so I am trying to use reflection. Everything else works right ATM, but it is not finding the ChatMessage class's constructor. It's constructor is (ChatMessage(String, Object... )), but I do not know how to get that constructor (since it can have an unlimited amount of parameters).

    What you can do to recreate the problem:.N/A

    Possible problematic line(s):
    .
    Code:
           CHATMESSAGE = Class.forName("net.minecraft.server."+SERVER_VERSION+".ChatMessage");
           try{
           CHATMESSAGE_CONSTRUCTOR = Optional.of(
               CHATMESSAGE.getConstructor(String.class)).get();
           }catch(NoSuchMethodException e){
             CHATMESSAGE_CONSTRUCTOR = Optional.of(CHATMESSAGE.getDeclaredConstructor(String.class)).get();
           }
    

    The FULL Error log:
    . N/A
     
  2. @Zombie_Striker
    Varargs just get compiled to arrays, so when the code runs, the constructor is really just treated as ChatMessage(String, Object[])
     
  3. Offline

    Zombie_Striker

    @AlvinB
    Although that fixed the issue, I now have a new error message.
    Where line 67 is
    Code:
                Object icb = CHATMESSAGE_CONSTRUCTOR.newInstance(message,null);
    EDIT: Fixed. Changed Null to "new Object[0]"
     
  4. @Zombie_Striker
    I believe it doesn't like null as an array, try creating an empty object array. (new Object[0])
     
  5. Offline

    Zombie_Striker

    @AlvinB
    Just changed it. Everything works now.
     
  6. Offline

    Jakeeeee

    Why not use Class#getConstructor then fill in the parameters which are String.class and Object[].class?
     
    kameronn likes this.
  7. @Zombie_Striker
    Also, something I should mention, is that InvocationTargetException isn't actually an exception telling you that something has gone wrong with the actual reflectioning, it's just a wrapper exception for any exception that happend when executing the actual code of the method. See how it says "caused by NullPointerException" at the bottom of the stacktrace?
     
    Zombie_Striker likes this.
Thread Status:
Not open for further replies.

Share This Page