Bukkit - 将玩家的名字改为头顶?

时间:2016-07-16 04:02:00

标签: 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 个答案:

答案 0 :(得分:2)

有可能在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数据包以更改播放器的显示名称。 (您可以看到名称标签和选项卡列表名称甚至可以是两个不同的值!)
  • hidePlayershowPlayerREMOVE_PLAYER用于立即刷新玩家的名字(否则需要退出并重新登录)。到目前为止还没有找到更好的方法。如果你有,请说:)