java - Bukkit - 更改玩家头顶的名字?

标签 java bukkit

我又回来了。
今天我有一个问题,以前很多人都问过。我再次询问的原因是因为在我所有约 90 分钟的搜索中,我找不到更新的答案。许多答案告诉我使用 iTag/TagAPI,但我在尝试使用它时遇到了一些问题,因此我不想使用 iTag/TagAPI。我正在尝试使用数据包,我找到了一个答案,但它也已过时。

EntityPlayer entityP = ((CraftPlayer) p).getHandle();
entityP.displayName = args[0];


for (Player a: Bukkit.getOnlinePlayers()) {

  if (!p.getUniqueId().equals(a.getUniqueId()))
    ((CraftPlayer) a).getHandle().playerConnection.sendPacket(new PacketPlayOutNamedEntitySpawn(entityP));
}

这是我要讨论的主题:https://bukkit.org/threads/change-player-name-above-head.162356/

感谢任何帮助!

最佳答案

在 1.8 中可以实现这一点。为方便起见,我使用了 ProtocolLib 和 PacketWrapper。

自1.8更新后,NamedEntitySpawn数据包已被修改,不再支持通过修改更改玩家名称。( ref )

但是this post给了一个引用:我们可以使用数据包PlayerInfoData。我做了一些测试,结果如下(针对 1.9.2 测试):

代码如下:

Player theGuyToChangeNameFor = Bukkit.getPlayer("theguy");

PlayerInfoData pid = new PlayerInfoData(WrappedGameProfile.fromPlayer(theGuyToChangeNameFor), 1,
                                        EnumWrappers.NativeGameMode.SURVIVAL,
                                        WrappedChatComponent.fromText("whatever_string"));
WrapperPlayServerPlayerInfo wpspi = new WrapperPlayServerPlayerInfo();
wpspi.setAction(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
wpspi.setData(Collections.singletonList(pid));
for(Player p : Bukkit.getOnlinePlayers())
{
    if(p.equals(theGuyToChangeNameFor))
    {
        continue;
    }
    p.hidePlayer(theGuyToChangeNameFor);
    wpspi.sendPacket(p);
}

ProtocolLibrary.getProtocolManager().addPacketListener(
        new PacketAdapter(this, PacketType.Play.Server.PLAYER_INFO)
        {

            @Override
            public void onPacketSending(PacketEvent event)
            {

                if(event.getPacket().getPlayerInfoAction().read(0) != EnumWrappers.PlayerInfoAction.ADD_PLAYER)
                {
                    return;
                }

                PlayerInfoData pid = event.getPacket().getPlayerInfoDataLists().read(0).get(0);

                if(!pid.getProfile().getName().toLowerCase().equals("theguy")) // Here you can do something to ensure you're changing the name of the correct guy
                {
                    return;
                }

                PlayerInfoData newPid = new PlayerInfoData(pid.getProfile().withName("HEAD_NAME"), pid.getPing(), pid.getGameMode(),
                                                           WrappedChatComponent.fromText("TAB_LIST_NAME"));
                event.getPacket().getPlayerInfoDataLists().write(0, Collections.singletonList(newPid));

            }
        }
);

for(Player p : Bukkit.getOnlinePlayers())
{
    if(p.equals(theGuyToChangeNameFor))
    {
        continue;
    }
    p.showPlayer(theGuyToChangeNameFor);
}

解释:

  • 我们使用 ProtocolLib 修改来自服务器的 PlayerInfoData 数据包,以更改玩家的显示名称。 (你可以看到,name tag 和 tab list name 甚至可以是两个不同的值!)
  • hidePlayershowPlayerREMOVE_PLAYER 用于立即刷新播放器名称(否则需要注销并重新登录)。目前还没找到更好的方法。如果你有,请说出来:)

关于java - Bukkit - 更改玩家头顶的名字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38407593/

相关文章:

java - Minecraft Spigot 插件编码,存在 Player.sendMessage 问题

java - Bukkit - 获取枚举为何不起作用的解释

与 java.time.Instant 对象一起使用时的 Java SE 8 TemporalAccessor.from 问题

java - Tomcat 虚拟主机和通配符 dns 匹配

java - 如何使用 Java 将文件夹内的文件提供给静态字符串?

java - 获取 HashMap 中最常用键的有效方法 - Java

java - bukkit 1.8 取消饮用和发射药水

java - 如何让 Eclipse 将文件导出到与源不同的位置?

java - 从 Bukkit 库存中移除元素

java - System.print.out 如果一个整数是另一个整数的倍数