使用Field.set设置GameProfile(更改玩家的名字)

时间:2016-07-17 00:04:13

标签: java reflection bukkit

我一直试图找出如何改变玩家的名字(他们头上的标签)。我尝试了很多东西,但最接近的是这段代码:

EntityHuman eh = ((CraftPlayer) p).getHandle();

PacketPlayOutEntityDestroy p29 = new PacketPlayOutEntityDestroy(new int[] {
  p.getEntityId()
});
PacketPlayOutNamedEntitySpawn p20 = new PacketPlayOutNamedEntitySpawn(eh);

try {

  Field profileField = eh.getClass().getSuperclass.getDeclaredField("bH");

  profileField.setAccessible(true);

  profileField.set(eh.getClass().getSuperclass, new GameProfile(p.getUniqueId(), newName));

} catch (Exception e) {

  e.printStackTrace();
  Bukkit.broadcastMessage("Not Work!");
}

我将进入Stack Trace它会打印一下......所以我发现人们使用的旧方法因为一些文件移位而不再工作。在代码中挖掘了一段时间后,我终于找到了我需要找到的内容,即net.minecraft.server.v1_8_R3.EntityHuman中名为“bH”的GameProfile对象。这基本上是需要改变的,以便改变玩家的名字。不要担心数据包,我已经完成了所有工作。

我的问题是,“如何更改EntityPlayer的名称标签?”我意识到我从Bukkit论坛获得的代码已经过时了。 GameProfile不再存储在EntityPlayer中,而是存储在EntityHuman中。那么,我现在的问题是,如何正确更改GameProfile字段“bH”?

我将在net.minecraft.server.v1_8_R3.EntityHuman中向您展示一些代码; private final GameProfile bH;同样,这是需要更改的内容,因为GameProfile接受UUID和String,名称。

所以,对于我得到的错误:

[19:10:23 WARN]: java.lang.IllegalArgumentException: Can not set final com.mojang.authlib.GameProfile field net.minecraft.server.v1_8_R3.EntityHuman.bH to java.lang.Class
[19:10:23 WARN]:        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
[19:10:23 WARN]:        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
[19:10:23 WARN]:        at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(Unknown Source)
[19:10:23 WARN]:        at sun.reflect.UnsafeQualifiedObjectFieldAccessorImpl.set(Unknown Source)
[19:10:23 WARN]:        at java.lang.reflect.Field.set(Unknown Source)
[19:10:23 WARN]:        at yt.Kaelinator.commands.Rename.disguisePlayer(Rename.java:117)
[19:10:23 WARN]:        at yt.Kaelinator.commands.Rename.onCommand(Rename.java:70)
[19:10:23 WARN]:        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44)
[19:10:23 WARN]:        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:140)
[19:10:23 WARN]:        at org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchCommand(CraftServer.java:620)
[19:10:23 WARN]:        at net.minecraft.server.v1_8_R3.PlayerConnection.handleCommand(PlayerConnection.java:1106)
[19:10:23 WARN]:        at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:966)
[19:10:23 WARN]:        at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(SourceFile:37)
[19:10:23 WARN]:        at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(SourceFile:9)
[19:10:23 WARN]:        at net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(SourceFile:13)
[19:10:23 WARN]:        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
[19:10:23 WARN]:        at java.util.concurrent.FutureTask.run(Unknown Source)
[19:10:23 WARN]:        at net.minecraft.server.v1_8_R3.SystemUtils.a(SourceFile:44)
[19:10:23 WARN]:        at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:673)
[19:10:23 WARN]:        at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:335)
[19:10:23 WARN]:        at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:629)
[19:10:23 WARN]:        at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:537)
[19:10:23 WARN]:        at java.lang.Thread.run(Unknown Source)

[19:10:23 WARN]: java.lang.IllegalArgumentException: Can not set final com.mojang.authlib.GameProfile field net.minecraft.server.v1_8_R3.EntityHuman.bH to java.lang.Class特别有趣,但我不太清楚如何阅读它。

我已经做了一些测试,导致这一点的确切行是profileField.set(eh.getClass(), new GameProfile(p.getUniqueId(), newName));,就像我在try / catch中使用此特定行一样,没有错误。我该怎么做才能“解决”这个问题?

注意:我无法使用ProtocolLib / iTag / TagAPI

感谢任何帮助,谢谢!

1 个答案:

答案 0 :(得分:1)

更改
profileField.set(eh.getClass().getSuperclass, new GameProfile(p.getUniqueId(), newName));profileField.set(eh, new GameProfile(p.getUniqueId(), newName));

现在有效:D