Solved Change Player Name Above Head causes Crash

Discussion in 'Spigot Plugin Development' started by Rexcantor64, Jun 16, 2016.

Thread Status:
Not open for further replies.
  1. Hi,
    I recently added this feature to my plugin and my server crashes every time I break a block with a changed nick.

    Here is my TagUtils.java:

    Code (Text):
    package me.islandcraft.mainhub.utils;

    import java.lang.reflect.Method;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.List;

    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.craftbukkit.v1_8_R3.CraftServer;
    import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
    import org.bukkit.entity.Player;

    import com.mojang.authlib.GameProfile;
    import com.mojang.authlib.HttpAuthenticationService;
    import com.mojang.authlib.minecraft.MinecraftSessionService;
    import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
    import com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService;
    import com.mojang.authlib.yggdrasil.response.MinecraftProfilePropertiesResponse;
    import com.mojang.util.UUIDTypeAdapter;

    import me.islandcraft.gameapi.IGamePlayer;
    import me.islandcraft.mainhub.Main;
    import net.minecraft.server.v1_8_R3.EntityPlayer;
    import net.minecraft.server.v1_8_R3.MinecraftServer;
    import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
    import net.minecraft.server.v1_8_R3.PacketPlayOutNamedEntitySpawn;
    import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo;
    import net.minecraft.server.v1_8_R3.PlayerInteractManager;
    import net.minecraft.server.v1_8_R3.WorldServer;

    public class TagUtils extends EntityPlayer {

        private String name;
        private GameProfile gameProf;

        private TagUtils(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile,
                PlayerInteractManager playerinteractmanager, String name) {
            super(minecraftserver, worldserver, gameprofile, playerinteractmanager);
            this.name = name;
            try {
                this.gameProf = fillProfileProperties(new GameProfile(this.uniqueID, this.name), true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public GameProfile getProfile() {
            return gameProf;
        }

        public static void setName(final Player player, final String newname, final List<Player> players) {
            Bukkit.getScheduler().runTaskAsynchronously(Main.get(), new Runnable() {
                @Override
                public void run() {
                    String name = newname;
                    if (name.length() > 16) {
                        name = name.substring(0, 16);
                    }
                    name = ChatColor.translateAlternateColorCodes('&', name);
                    EntityPlayer entity = ((CraftPlayer) player).getHandle();
                    TagUtils colored = new TagUtils(entity.server, entity.u(), entity.getProfile(),
                            entity.playerInteractManager, name);
                    PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(
                            PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, entity);
                    PacketPlayOutPlayerInfo packetAdd = new PacketPlayOutPlayerInfo(
                            PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, colored);
                    PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(entity.getId());
                    PacketPlayOutNamedEntitySpawn named = new PacketPlayOutNamedEntitySpawn(entity);

                    for (Player online : players) {
                        EntityPlayer cur = ((CraftPlayer) online).getHandle();
                        cur.playerConnection.sendPacket(packet);
                        cur.playerConnection.sendPacket(packetAdd);
                        if (online.equals(player))
                            continue;
                        cur.playerConnection.sendPacket(destroy);
                        cur.playerConnection.sendPacket(named);
                    }
                }
            });

        }

        public static void setName(final Player p, final String name, final java.util.Collection<IGamePlayer> players) {
            setName(p, name, ListUtils.gpListToPlayerList(new ArrayList<>(players)));
        }

        private static GameProfile fillProfileProperties(GameProfile profile, boolean requireSecure) throws Exception {
         

            if (Bukkit.isPrimaryThread())
                throw new IllegalStateException("NMS.fillProfileProperties cannot be invoked from the main thread.");

            MinecraftSessionService sessionService = ((CraftServer) Bukkit.getServer()).getServer().aD();

            YggdrasilAuthenticationService auth = ((YggdrasilMinecraftSessionService) sessionService)
                    .getAuthenticationService();

            URL url = HttpAuthenticationService.constantURL("https://sessionserver.mojang.com/session/minecraft/profile/"
                    + UUIDTypeAdapter.fromUUID(profile.getId()));

            url = HttpAuthenticationService.concatenateURL(url, "unsigned=" + !requireSecure);
            Method MAKE_REQUEST = null;
            try {
                MAKE_REQUEST = YggdrasilAuthenticationService.class.getDeclaredMethod("makeRequest", URL.class,
                        Object.class, Class.class);
                MAKE_REQUEST.setAccessible(true);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            MinecraftProfilePropertiesResponse response = (MinecraftProfilePropertiesResponse) MAKE_REQUEST.invoke(auth,
                    url, null, MinecraftProfilePropertiesResponse.class);
            if (response == null)
                return profile;

            GameProfile result = new GameProfile(profile.getId(), profile.getName());
            result.getProperties().putAll(response.getProperties());
            profile.getProperties().putAll(response.getProperties());

            return result;
        }

    }
     

    Log: http://pastebin.com/d80TSdkR

    Crash-report: http://pastebin.com/7RjKyXEt

    Any ideas to fix the bug?

    Also, when I change the name, the armor temporary disappears from the player (visual bug).
     
    #1 Rexcantor64, Jun 16, 2016
    Last edited: Jun 16, 2016
  2. Sadly, this is a BUMP ;(
     
  3. Does this only happen in all worlds?
     
  4. This happens on every minigame (Every minigame has a different world). I already tested to set it inside and outside the minigame world.
     
  5. An other question:
    How do you unnick the player?
    Don't inherit "EntityPlayer", don't create unnecessarys instances of TagUtils.
    The bug appears in playerInteractManager. This is null.
     
  6. I decided to use Scoreboard to manage nicks. Thanks for that.
     
Thread Status:
Not open for further replies.