我又回来了。
今天我有一个问题,以前很多人都问过。我再次询问的原因是因为在我所有约 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 甚至可以是两个不同的值!) hidePlayer
、showPlayer
和REMOVE_PLAYER
用于立即刷新播放器名称(否则需要注销并重新登录)。目前还没找到更好的方法。如果你有,请说出来:)
关于java - Bukkit - 更改玩家头顶的名字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38407593/