2017-02-04 7 views
1

Ich versuche, Paket (in Bukkit API) zu machen. Aber ich bekomme eine NoSuchFieldException.Java NoSuchFieldError bei Verwendung von Reflection, BukkitAPI

public class PacketPlayOutPlayerInfo { 
private static final Class<?> packetClass = Reflections.getCraftClass("PacketPlayOutPlayerInfo"); 
private static final Class<?>[] typesClass = new Class<?>[]{ String.class, boolean.class, int.class }; 
private static int type = 0; 

static { 
    try { 
     if (packetClass.getConstructor(typesClass) == null) { 
      type = 1; 
     } 
    } catch (Exception e) { 
     type = 1; 
    } 
} 

public static Object getPacket(String s, boolean b, int i) { 
    try { 
     if (type == 0) { 
      return packetClass.getConstructor(typesClass).newInstance(s, b, i); 
     } 
     else if (type == 1) { 
      Class<?> clazz = Reflections.getCraftClass("PacketPlayOutPlayerInfo"); 
      Object packet = packetClass.getConstructor().newInstance(); 
      Reflections.getPrivateField(clazz, "username").set(packet, s); 
      Reflections.getPrivateField(clazz, "gamemode").set(packet, 1); 
      Reflections.getPrivateField(clazz, "ping").set(packet, i); 
      Reflections.getPrivateField(clazz, "player").set(packet, new OfflineUser(s).getProfile()); 
      if (!b) { 
       Reflections.getPrivateField(clazz, "action").set(packet, 4); 
      } 
      return packet; 
     } 
    } catch (Exception e) { 
     if (FunnyGuilds.exception(e.getCause())) { 
      e.printStackTrace(); 
     } 
    } 
    return null; 
} 

}

Hier `s voller Fehler:

 
[20:25:43] [IndependentThread/WARN]: java.lang.NoSuchFieldException: username 
[20:25:43] [IndependentThread/WARN]: at java.lang.Class.getDeclaredField(Unknown Source) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.reflect.Reflections.getPrivateField(Reflections.java:123) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.reflect.transition.PacketPlayOutPlayerInfo.getPacket(PacketPlayOutPlayerInfo.java:31) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.packets(PlayerListManager.java:88) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.send(PlayerListManager.java:67) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerList.send(PlayerList.java:160) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.updatePlayers(PlayerListManager.java:24) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.Action.execute(Action.java:37) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.IndependentThread.execute(IndependentThread.java:43) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.IndependentThread.run(IndependentThread.java:28) 
[20:25:43] [IndependentThread/WARN]: java.lang.NullPointerException 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.reflect.transition.PacketPlayOutPlayerInfo.getPacket(PacketPlayOutPlayerInfo.java:31) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.packets(PlayerListManager.java:88) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.send(PlayerListManager.java:67) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerList.send(PlayerList.java:160) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.updatePlayers(PlayerListManager.java:24) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.Action.execute(Action.java:37) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.IndependentThread.execute(IndependentThread.java:43) 
[20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.IndependentThread.run(IndependentThread.java:28) 

PS: Sorry für mein schlechtes Englisch.

Antwort

0

Ich denke, dass Sie die Namen der anfordernden Objektvariablen überprüfen sollten (Ihre Variable sollte camel case sein). Denn in einem api-Aufruf müssen Sie mit dem Namen genau in api doc nachfragen.

1

Die Ausnahme scheint angemessen zu sein, da PacketPlayOutPlayerInfo die Felder nicht definiert, auf die Sie zugreifen möchten. Angesichts der Auswahl der Feldnamen versichere ich, dass Sie möglicherweise versuchen, Werte für PacketPlayOutPlayerInfo.PlayerInfoData festzulegen; seine Feldnamen sind jedoch verschleiert und müssen als solche angegeben werden, es sei denn, Sie übergeben die Informationen als Teil des Konstruktors.

Da diese Frage beschäftigt sich mit dem Zugriff auf de-kompilierten proprietären Code, werde ich Sie mit diesen Vorschlägen verlassen:

  • sich mit ProtocolLib vertraut gemacht, wie es funktioniert bereits die meisten der schweren Heben, wenn es um die Verwaltung von und Pakete optimieren.
  • Wenn Sie immer noch Ihre Hände Schmutz und DIY bekommen wollen, protocolLib die Quelle auf GitHub.
  • Wenn Sie die wesentlichen Details über Minecraft Klassen wollen, empfehle ich die Verwendung von Spigot BuildTool, wenn Sie nicht bereits sind. Ein Nebeneffekt des Build-Prozesses sind dekompilierten Minecraft-Klassen (siehe work/decompileXXX/net/minecraft/server Verzeichnis darunter. Diese Informationen werden Ihnen helfen, richtig Reflexion zu implementieren ruft Klassen und modifizierte Felder zu instanziiert.

In older versions of bukkitapi(1.6-1.7) this code works great.

To use ProtocolLib i must edit many of code. Thic exception is caused by this class or other?

PacketPlayOutPlayerInfo wurde in 1,8 geändert und weiter Ich schaute auf die Version 1.8 (am weitesten, die ich zurückgehen konnte) und auf die Version 1.11.2, und es gibt eine Welt der Unterschiede, das ist das Problem mit Klassen zu arbeiten, die nicht Teil einer API sind, sie werden sich nach Belieben ändern und niemandem wird einen Riss vergießen, wenn Code außerhalb von Minecraft bricht

Während ProtocolLib auch brechen kann, kenntnisreich und erfahrene Entwickler werden es schnell beheben. Sie müssen, da viele Plugins es verwenden, böse Überraschungen mit neuen Minecraft Releases zu vermeiden. Wenn ProtocolLib nicht Ihre Tasse Tee ist, dann schlage ich vor, dass Sie BuildTools verwenden, die Dekompilierungsklasse untersuchen und Ihren Code entsprechend anpassen. Minecraft Modern einen Klick entfernt wäre auch eine gute Sache.

+0

In älteren Versionen von Bukkitapi (1.6-1.7) funktioniert dieser Code sehr gut. – PrzemoVi

+0

Um ProtocolLib zu verwenden, muss ich viele Code bearbeiten. Thic Ausnahme wird von dieser Klasse oder anderen verursacht? – PrzemoVi

+0

@PrzemoVi Nicht genug Zeichen, um dies zu einem Kommentar zu machen, ich füge meine Antwort oben hinzu. – Frelling