如何使用 ProtocolLib 或 Bukkit 修改玩家的姓名标签以实现粗体彩色姓名标签?

问题描述 投票:0回答:1

您好,我正在开发一个我的世界插件,使用 ProtocolLib 来修改玩家的姓名标签,以便当他们使用下界之星时,他们的姓名标签会发生变化。我的目标是暂时将玩家的姓名标签更改为紫色且粗体 2 分钟,然后将其重置回正常状态。但是,我在尝试修改数据包字段时遇到 FieldAccessException 错误。

package me.games.weapon;

import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.comphenix.protocol.wrappers.WrappedGameProfile;


import java.util.Collection;
import java.util.Collections;

public class SuperCharge implements Listener, CommandExecutor {

    private final JavaPlugin plugin;
    private final ProtocolManager protocolManager;

    public SuperCharge(JavaPlugin plugin) {
        this.plugin = plugin;
        this.protocolManager = ProtocolLibrary.getProtocolManager();
    }

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (sender instanceof Player) {
            Player player = (Player) sender;
            // Create a new ItemStack for the Nether Star
            ItemStack supercharge = new ItemStack(Material.NETHER_STAR);
            // Give the player the Nether Star
            player.getInventory().addItem(supercharge);
            return true;
        } else {
            sender.sendMessage("You must be a player to use this command.");
            return false;
        }
    }

    @EventHandler
    public void onPlayerUse(PlayerInteractEvent event) {
        Player player = event.getPlayer();
        ItemStack item = event.getItem();

        if (item != null && item.getType() == Material.NETHER_STAR) {
            // Apply the glowing effect for 2 minutes
            player.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, 2 * 60 * 20, 1));
            // Change the player's name tag to purple and bold for 2 minutes
            changePlayerNameTag(player);

            // Schedule task to reset the player's name tag after 2 minutes (2400 ticks)
            new BukkitRunnable() {
                @Override
                public void run() {
                    resetPlayerNameTag(player);
                }
            }.runTaskLater(plugin, 2 * 60 * 20);

            // Remove the Nether Star from the player's inventory
            player.getInventory().removeItem(new ItemStack(Material.NETHER_STAR, 1));
        }
    }

    private void changePlayerNameTag(Player player) { // Currently isn't working and isn't coloring and bolding
        PacketContainer nameTagPacket = protocolManager.createPacket(PacketType.Play.Server.PLAYER_INFO);
        nameTagPacket.getPlayerInfoAction().write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
        nameTagPacket.getPlayerInfoDataLists().write(0, Collections.singletonList(new PlayerInfoData(
                WrappedGameProfile.fromPlayer(player),
                1,
                EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()),
                WrappedChatComponent.fromText(ChatColor.BOLD + "" + ChatColor.LIGHT_PURPLE + player.getName())
        )));
        try {
            protocolManager.sendServerPacket(player, nameTagPacket);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void resetPlayerNameTag(Player player) {
        PacketContainer nameTagPacket = protocolManager.createPacket(PacketType.Play.Server.PLAYER_INFO);
        nameTagPacket.getPlayerInfoAction().write(0, EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME);
        nameTagPacket.getPlayerInfoDataLists().write(0, Collections.singletonList(new PlayerInfoData(
                WrappedGameProfile.fromPlayer(player),
                1,
                EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()),
                WrappedChatComponent.fromText(player.getName()) // Original name without formatting
        )));
        try {
            protocolManager.sendServerPacket(player, nameTagPacket);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

我尝试为团队使用 Spigot 的 API,但它只用一种颜色为玩家的姓名标签着色,并且不适用于在其顶部加粗等多种颜色。
现在我尝试使用 ProtocolLib 修改玩家的姓名标签,但我在服务器控制台中遇到此错误。我只是希望能够编辑玩家姓名标签并用多种颜色对其进行着色,无论什么方式都是可能的,但这些是我想到和尝试过的唯一方法。

[ERROR]: Could not pass event PlayerInteractEvent to Weapon v1.0-SNAPSHOT
com.comphenix.protocol.reflect.FieldAccessException: Field index 0 is out of bounds for length 0
    at com.comphenix.protocol.reflect.FieldAccessException.fromFormat(FieldAccessException.java:49)
    at com.comphenix.protocol.reflect.StructureModifier.write(StructureModifier.java:315)
    at me.iplaygames.boostweapon.SuperCharge.changePlayerNameTag(SuperCharge.java:80)
    at me.iplaygames.boostweapon.SuperCharge.onPlayerUse(SuperCharge.java:60)
    ...
java minecraft bukkit
1个回答
0
投票

自 Minecraft 1.19.3 起,一些有关玩家信息的数据包发生了变化。

现在,

PlayerInfo
数据包已重命名为
PlayerInfoUpdate
(在ProtocolLib中,出于兼容性原因,它是相同的)。要删除,现在是
PlayerInfoRemove

要添加内容,您应该使用

PlayerInfoUpdate
以及Players actions中描述的一些特定选项。
你应该像这样使用

PlayerInfoData

// create a new player info data PlayerInfoData new_playerinfo = new PlayerInfoData(playerInfo.getProfileId(), playerInfo.getLatency(), playerInfo.isListed(), playerInfo.getGameMode(), playerInfo.getProfile(), new_tab_name, playerInfo.getProfileKeyData()); // write it into packet nameTagPacket.getPlayerInfoDataLists().write(1, Collections.singletonList(new_playerinfo));

	
© www.soinside.com 2019 - 2024. All rights reserved.