[Anleitung] Spieler Nicken - Name und Skin ändern - 1.8.8

Hier könnt ihr anderen Leuten helfen, indem ihr Anleitungen oder praktische Codesegmente zur Verfügung stellt.

Re: [Anleitung] Spieler Nicken - Name und Skin ändern - 1.8+

Beitragvon Jofkos » So 15. Feb 2015, 17:53

Twister_21 hat geschrieben:EDIT: Was ist "Reflect"?
Die Klasse ist selbsterklären. Wenn du sie dennoch brauchst, kannst du sie auf meiner GitHub Seite finden.

Twister_21 hat geschrieben:was ist mit "MessageToMessageDecoder in die Pipeline einfügen, nach 'decoder'" gemeint?
Das hab' ich hier schon übernommen. In diesem Fall ist es ein MessageToMessageEncoder, und er wird nach dem 'encoder' eingefügt.

Twister_21 hat geschrieben:Womit soll man nick_listener ersetzten?
Nick_listener ist einfach ein Name. Könnte genausogut 'Olaf' sein.

Twister_21 hat geschrieben:Weiß auch noch nicht ganz was ich mit dem Packet infoPacket machen soll, hab das noch nie gemacht.
Ich bin davon ausgegangen, dass du Minecraft 1.8 nutzt. Da wird der Skin über das Info Packet gesendet und Client Side an die UUID gebunden. So wird beim Spawnen des Spielers nur die UUID gesendet.

Was du damit machen musst findest du im ersten Post. Du musst dem neuen GameProfile die UUID vom alten Spieler setzen und dieses dann im Packet übergeben.
Jofkos

...........

..Bild
Benutzeravatar
Jofkos
 
Beiträge: 1537
Registriert: So 16. Jun 2013, 22:45

Re: [Anleitung] Spieler Nicken - Name und Skin ändern - 1.8+

Beitragvon Twister_21 » So 15. Feb 2015, 18:23

Ok, wieder ein Schritt weiter, aber ich weiß noch nicht ganz, was ich hier machen soll:
Code: Alles auswählen
  1. if (packet instanceof PacketPlayOutPlayerInfo) {
  2. PacketPlayOutPlayerInfo infoPacket = (PacketPlayOutPlayerInfo) packet;
  3. infoPacket.?
  4. }


Wie kann ich da infoPacket verändern? Finde das aktuell noch etwas verwirrend.
Mit freundlichen Grüßen
Twister21
Benutzeravatar
Twister_21
 
Beiträge: 652
Registriert: Mi 11. Jun 2014, 05:51
Wohnort: Deutschland

Re: [Anleitung] Spieler Nicken - Name und Skin ändern - 1.8+

Beitragvon Jofkos » So 15. Feb 2015, 20:59

Twister_21 hat geschrieben:Ok, wieder ein Schritt weiter, aber ich weiß noch nicht ganz, was ich hier machen soll:
Code: Alles auswählen
  1. if (packet instanceof PacketPlayOutPlayerInfo) {
  2. PacketPlayOutPlayerInfo infoPacket = (PacketPlayOutPlayerInfo) packet;
  3. infoPacket.?
  4. }


Wie kann ich da infoPacket verändern? Finde das aktuell noch etwas verwirrend.
'id' ist private final, sprich nur über reflections veränderbar.
Code: Alles auswählen
  1. private static final Field idField = Reflect.getField(GameProfile.class, "id"); // variable cachen
Ich nutze hier auch wieder meine Reflect-Klasse, da diese auch das Final umgeht.
Und dann halt ganz normal setzen:
Code: Alles auswählen
  1. Reflect.set(idField, infoPacket, entityPlayer.getProfile().getId());
Du könntest auch idField.set(....) verwenden.
Jofkos

...........

..Bild
Benutzeravatar
Jofkos
 
Beiträge: 1537
Registriert: So 16. Jun 2013, 22:45

Re: [Anleitung] Spieler Nicken - Name und Skin ändern - 1.8+

Beitragvon Twister_21 » Mo 16. Feb 2015, 14:41

Hab jetzt den ganzen Code den du hier geschrieben hast einfach erstmal übernommen und es beim Joinen getestet, bekomme den Fehler:

Code: Alles auswählen
  1. [14:38:36] [Netty Server IO #2/WARN]: java.lang.IllegalArgumentException: Can not set java.util.UUID field com.mojang.authlib.GameProfile.id to net.minecraft.server.v1_8_R1.PacketPlayOutPlayerInfo
  2. [14:38:36] [Netty Server IO #2/WARN]:    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
  3. [14:38:36] [Netty Server IO #2/WARN]:    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
  4. [14:38:36] [Netty Server IO #2/WARN]:    at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
  5. [14:38:36] [Netty Server IO #2/WARN]:    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75)
  6. [14:38:36] [Netty Server IO #2/WARN]:    at java.lang.reflect.Field.set(Field.java:758)
  7. [14:38:36] [Netty Server IO #2/WARN]:    at api.Reflect.set(Reflect.java:81)
  8. [14:38:36] [Netty Server IO #2/WARN]:    at api.Tag$2.encode(Tag.java:323)
  9. [14:38:36] [Netty Server IO #2/WARN]:    at api.Tag$2.encode(Tag.java:1)
  10. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:89)
  11. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:657)
  12. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:715)
  13. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:705)
  14. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:740)
  15. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:895)
  16. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:241)
  17. [14:38:36] [Netty Server IO #2/WARN]:    at net.minecraft.server.v1_8_R1.QueuedProtocolSwitch.run(SourceFile:161)
  18. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:370)
  19. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353)
  20. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
  21. [14:38:36] [Netty Server IO #2/WARN]:    at java.lang.Thread.run(Thread.java:745)


Ich denke, dass das bedeutet, dass einem Feld das falsche gesetzt wird.
Mit freundlichen Grüßen
Twister21
Benutzeravatar
Twister_21
 
Beiträge: 652
Registriert: Mi 11. Jun 2014, 05:51
Wohnort: Deutschland

Re: [Anleitung] Spieler Nicken - Name und Skin ändern - 1.8+

Beitragvon Jofkos » Mo 16. Feb 2015, 17:01

Twister_21 hat geschrieben:Hab jetzt den ganzen Code den du hier geschrieben hast einfach erstmal übernommen und es beim Joinen getestet, bekomme den Fehler:

Code: Alles auswählen
  1. [14:38:36] [Netty Server IO #2/WARN]: java.lang.IllegalArgumentException: Can not set java.util.UUID field com.mojang.authlib.GameProfile.id to net.minecraft.server.v1_8_R1.PacketPlayOutPlayerInfo
  2. [14:38:36] [Netty Server IO #2/WARN]:    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
  3. [14:38:36] [Netty Server IO #2/WARN]:    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
  4. [14:38:36] [Netty Server IO #2/WARN]:    at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
  5. [14:38:36] [Netty Server IO #2/WARN]:    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75)
  6. [14:38:36] [Netty Server IO #2/WARN]:    at java.lang.reflect.Field.set(Field.java:758)
  7. [14:38:36] [Netty Server IO #2/WARN]:    at api.Reflect.set(Reflect.java:81)
  8. [14:38:36] [Netty Server IO #2/WARN]:    at api.Tag$2.encode(Tag.java:323)
  9. [14:38:36] [Netty Server IO #2/WARN]:    at api.Tag$2.encode(Tag.java:1)
  10. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:89)
  11. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:657)
  12. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:715)
  13. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:705)
  14. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:740)
  15. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:895)
  16. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:241)
  17. [14:38:36] [Netty Server IO #2/WARN]:    at net.minecraft.server.v1_8_R1.QueuedProtocolSwitch.run(SourceFile:161)
  18. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:370)
  19. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353)
  20. [14:38:36] [Netty Server IO #2/WARN]:    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
  21. [14:38:36] [Netty Server IO #2/WARN]:    at java.lang.Thread.run(Thread.java:745)


Ich denke, dass das bedeutet, dass einem Feld das falsche gesetzt wird.

Das heisst, dass du versuchst das 'id' Feld zu einem 'PacketPlayOutPlayerInfo' zu setzen. Da sind irgendwo Argumente verdreht ;)
Jofkos

...........

..Bild
Benutzeravatar
Jofkos
 
Beiträge: 1537
Registriert: So 16. Jun 2013, 22:45

Re: [Anleitung] Spieler Nicken - Name und Skin ändern - 1.8+

Beitragvon Twister_21 » Mo 16. Feb 2015, 17:05

Bin ja noch dabei es zu verstehen und habe erstmal deinen Code so übernommen, damit keine Fehler auftreten, der Verursacht aber doch den oben genannten Fehler:
Code: Alles auswählen
  1.       EntityPlayer entity = ((CraftPlayer)p).getHandle();
  2.       Channel playerChannel = Reflect.get(channelField, entity.playerConnection.networkManager);
  3.       
  4.       playerChannel.pipeline().addAfter("encoder", "nick_listener", new MessageToMessageEncoder<Packet>() {
  5.             @Override
  6.             protected void encode(ChannelHandlerContext chc, Packet packet, List<Object> out) throws Exception {
  7.                if (packet instanceof PacketPlayOutPlayerInfo) {
  8.                   PacketPlayOutPlayerInfo infoPacket = (PacketPlayOutPlayerInfo) packet;
  9.                  
  10.                   final Field idField = Reflect.getField(GameProfile.class, "id");
  11.                   Reflect.set(idField, infoPacket, entity.getProfile().getId());
  12.                }
  13.                out.add(packet);
  14.             }
  15.          });
Mit freundlichen Grüßen
Twister21
Benutzeravatar
Twister_21
 
Beiträge: 652
Registriert: Mi 11. Jun 2014, 05:51
Wohnort: Deutschland

Re: [Anleitung] Spieler Nicken - Name und Skin ändern - 1.8+

Beitragvon Twister_21 » Di 17. Feb 2015, 19:57

#push
Hast du eine Idee was an dem Code falsch ist?
Mit freundlichen Grüßen
Twister21
Benutzeravatar
Twister_21
 
Beiträge: 652
Registriert: Mi 11. Jun 2014, 05:51
Wohnort: Deutschland

Re: [Anleitung] Spieler Nicken - Name und Skin ändern - 1.8+

Beitragvon Jofkos » Di 17. Feb 2015, 20:46

Sorry, habe es gesehen aber nicht direkt geantwortet, und dann wieder vergessen :shock:
Twister_21 hat geschrieben:#push
Hast du eine Idee was an dem Code falsch ist?


Ja, mein Fehler:
Du musst im GameProfile die UUID verändern (wie erwähnt). Den Code den ich dir geschickt habe jedoch probiert das Feld im InfoPacket zu setzen (kommt davon wenn man am Handy schreibt :P)

Habe dir mal schnell was hingeschrieben, schau dir einfach die Kommentare im Code an, und versuche ihn zu verstehen.
Ungetestet, sollte aber hauptsächlich aufzeigen wie es Theoretisch möglich wäre.
Den Feinschliff musst du dann schon selber übernehmen ;)
Falls irgendwas unklar ist, melde dich nochmal.

(Felder hab' ich immer als static final, damit diese nur einmalig instanziiert werden)
Code: Alles auswählen
  1. private static Field channelField;
  2. static {
  3.    try {
  4.       for (Field field : NetworkManager.class.getDeclaredFields()) {
  5.          if (field.getType().isAssignableFrom(Channel.class)) {
  6.             channelField = field;
  7.             channelField.setAccessible(true);
  8.             break;
  9.          }
  10.       }
  11.       
  12.    } catch (Exception e) {
  13.       e.printStackTrace();
  14.    }
  15. }
  16. private static Field actionField = Reflect.getField(PacketPlayOutPlayerInfo.class, "a");
  17. private static Field dataField = Reflect.getField(PacketPlayOutPlayerInfo.class, "b");
  18. private static Field idField = Reflect.getField(GameProfile.class, "id");
  19. private static Field dataGameprofileField = Reflect.getField(PlayerInfoData.class, "d");
  20. private static Field dataNameField = Reflect.getField(PlayerInfoData.class, "e");
  21. private Map<UUID, GameProfile> nicks = new HashMap<UUID, GameProfile>(); // enthält GameProfiles für die jeweiligen Spieler (UUID)
  22. @EventHandler
  23. public void onJoin(PlayerJoinEvent e) {
  24.    EntityPlayer entity = ((CraftPlayer) e.getPlayer()).getHandle();
  25.    Channel playerChannel = Reflect.get(channelField, entity.playerConnection.networkManager);
  26.    playerChannel.pipeline().addAfter("encoder", "nick_listener", new MessageToMessageEncoder<Packet>() {
  27.       @Override
  28.       protected void encode(ChannelHandlerContext chc, Packet packet, List<Object> out) throws Exception {
  29.          if (packet instanceof PacketPlayOutPlayerInfo) {
  30.             PacketPlayOutPlayerInfo infoPacket = (PacketPlayOutPlayerInfo) packet;
  31.             
  32.             List<PlayerInfoData> info = Reflect.get(dataField, infoPacket); // Liste mit PlayerInfoData, die die zu spawnenden Spieler enthält
  33.             EnumPlayerInfoAction action = Reflect.get(actionField, infoPacket); // Aktion vom Packet getten
  34.             
  35.             if (!info.isEmpty() && action == EnumPlayerInfoAction.ADD_PLAYER) {
  36.                for (PlayerInfoData data : info) {
  37.                   if (!nicks.containsKey(data.a().getId())) continue;
  38.                   
  39.                   GameProfile profile = nicks.get(data.a().getId()); // Nick Profile für den Namen getten
  40.                   Reflect.set(idField, profile, data.a().getId()); // Player UUID im Profile ersetzen
  41.                   Reflect.set(dataGameprofileField, data, profile); // GameProfile in PlayerInfoData aktualisieren
  42.                   
  43.                   IChatBaseComponent name = CraftChatMessage.fromString(profile.getName())[0];
  44.                   Reflect.set(dataNameField, data, name); // Name in PlayerInfoData aktualisieren
  45.                }
  46.             }
  47.             
  48.          }
  49.          out.add(packet); // Packet weitergeben
  50.       }
  51.       
  52.    });
  53. }
Jofkos

...........

..Bild
Benutzeravatar
Jofkos
 
Beiträge: 1537
Registriert: So 16. Jun 2013, 22:45

Re: [Anleitung] Spieler Nicken - Name und Skin ändern - 1.8+

Beitragvon Twister_21 » Mi 18. Feb 2015, 19:33

Ok, ich mache es jetzt aber doch wieder so, wenn man einen Scheduler einbaut funktioniert es:

Code: Alles auswählen
  1. Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
  2.          
  3.          @Override
  4.          public void run() {
  5.             for(Player players: Bukkit.getOnlinePlayers()) {
  6.                if(players == p) continue;
  7.                setTag(players, players.getDisplayName());
  8.             }
  9.             
  10.          }
  11.       }, 3);



Aber irgendwie wird wenn der Spieler leftet er nicht wieder aus der Tablist entfernt:

Code: Alles auswählen
  1.    @EventHandler
  2.    public void onQuit(PlayerQuitEvent e) {
  3.    Player p = e.getPlayer();
  4.    
  5.    EntityPlayer entity = ((CraftPlayer) p).getHandle();
  6.          
  7.     PacketPlayOutPlayerInfo removeProfile = new PacketPlayOutPlayerInfo();
  8.     setInfo(removeProfile, EnumPlayerInfoAction.REMOVE_PLAYER, new PlayerInfoData(removeProfile, entity.getProfile(), -1, null, null));   
  9.           for(Player players: Bukkit.getOnlinePlayers()) {
  10.              ((CraftPlayer)players).getHandle().playerConnection.sendPacket(removeProfile);
  11.           }
  12.    }


Wenn der Spieler nicht genickt ist wird er aus der Tablist entfernt.

EDIT: Das liegt bestimmt daran, dass ja ein anderes GameProfile gesetzt wurde.

EDIT 2: Ok, geht jetzt. Ich denke jetzt sind alle Probleme behoben. Danke für die ganzen Hilfen, Jofkos, jetzt kann ich schon besser mit Packets umgehen. :D

EDIT 3: Kann man bei dem Code um die Packets abzufangen statt dem Namen den DisplayNamen setzen? Da hast du ja profile.getName() verwendet, wie mache ich das aber mit dem DisplayName? Geht dann das gleiche wie mit dem PacketPlayOutPlayerInfo auch mit dem PacketPlayOutNamedEntitySpawned? Das brauche ich ja für den Tag über dem Skin. Will das dann doch lieber so machen wenn es geht.
Mit freundlichen Grüßen
Twister21
Benutzeravatar
Twister_21
 
Beiträge: 652
Registriert: Mi 11. Jun 2014, 05:51
Wohnort: Deutschland

Re: [Anleitung] Spieler Nicken - Name und Skin ändern - 1.8+

Beitragvon Jofkos » Mi 18. Feb 2015, 21:10

Ich verstehe deine Frage leider nicht ganz. Was was genau willst du mit dem Display Name machen?
Jofkos

...........

..Bild
Benutzeravatar
Jofkos
 
Beiträge: 1537
Registriert: So 16. Jun 2013, 22:45

VorherigeNächste

Zurück zu Anleitungen

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste

cron