我又回来了。
今天我有一个很多人以前问过的问题。我再次提问的原因是因为在我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/
感谢任何帮助!
答案 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);
}
说明:
PlayerInfoData
数据包以更改播放器的显示名称。 (您可以看到名称标签和选项卡列表名称甚至可以是两个不同的值!)hidePlayer
,showPlayer
和REMOVE_PLAYER
用于立即刷新玩家的名字(否则需要退出并重新登录)。到目前为止还没有找到更好的方法。如果你有,请说:)