    public static void sendSelfDisguise(final Player player) {
        try {
            if (!player.isValid()) {
                return;
            }
            Object world = ReflectionManager.getWorld(player.getWorld());
            Object tracker = world.getClass().getField("tracker").get(world);
            Object trackedEntities = tracker.getClass().getField("trackedEntities").get(tracker);
            Object entityTrackerEntry = trackedEntities.getClass().getMethod("get", int.class)
                    .invoke(trackedEntities, player.getEntityId());
            if (entityTrackerEntry == null) {
                Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() {
                    public void run() {
                        sendSelfDisguise(player);
                    }
                });
                return;
            }
            ((HashSet) entityTrackerEntry.getClass().getField("trackedPlayers").get(entityTrackerEntry)).add(ReflectionManager
                    .getNmsEntity(player));
            ProtocolManager manager = ProtocolLibrary.getProtocolManager();
            manager.sendServerPacket(player, manager.createPacketConstructor(PacketType.Play.Server.NAMED_ENTITY_SPAWN, player)
                    .createPacket(player));
            manager.sendServerPacket(
                    player,
                    manager.createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, player.getEntityId(),
                            WrappedDataWatcher.getEntityWatcher(player), true).createPacket(player.getEntityId(),
                            WrappedDataWatcher.getEntityWatcher(player), true));
            boolean isMoving = false;
            try {
                Field field = ReflectionManager.getNmsClass("EntityTrackerEntry").getDeclaredField("isMoving");
                field.setAccessible(true);
                isMoving = field.getBoolean(entityTrackerEntry);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            if (isMoving) {
                Vector velocity = player.getVelocity();
                manager.sendServerPacket(
                        player,
                        manager.createPacketConstructor(PacketType.Play.Server.ENTITY_VELOCITY, player.getEntityId(),
                                velocity.getX(), velocity.getY(), velocity.getZ()).createPacket(player.getEntityId(),
                                velocity.getX(), velocity.getY(), velocity.getZ()));
            }
            if (player.getVehicle() != null && player.getEntityId() > player.getVehicle().getEntityId()) {
                manager.sendServerPacket(player,
                        manager.createPacketConstructor(PacketType.Play.Server.ATTACH_ENTITY, 0, player, player.getVehicle())
                                .createPacket(0, player, player.getVehicle()));
            } else if (player.getPassenger() != null && player.getEntityId() > player.getPassenger().getEntityId()) {
                manager.sendServerPacket(player,
                        manager.createPacketConstructor(PacketType.Play.Server.ATTACH_ENTITY, 0, player.getPassenger(), player)
                                .createPacket(0, player.getPassenger(), player));
            }
            for (int i = 0; i < 5; i++) {
                ItemStack item;
                if (i == 0) {
                    item = player.getItemInHand();
                } else {
                    item = player.getInventory().getArmorContents()[i - 1];
                }
                if (item != null && item.getType() != Material.AIR) {
                    manager.sendServerPacket(
                            player,
                            manager.createPacketConstructor(PacketType.Play.Server.ENTITY_EQUIPMENT, player.getEntityId(), i,
                                    item).createPacket(player.getEntityId(), i, item));
                }
            }
            Location loc = player.getLocation();
            if (player.isSleeping()) {
                manager.sendServerPacket(
                        player,
                        manager.createPacketConstructor(PacketType.Play.Server.BED, player, loc.getBlockX(), loc.getBlockY(),
                                loc.getBlockZ()).createPacket(player, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
            }
            Iterator iterator = player.getActivePotionEffects().iterator();
            while (iterator.hasNext()) {
                PotionEffect potionEffect = (PotionEffect) iterator.next();
                manager.sendServerPacket(player,
                        manager.createPacketConstructor(PacketType.Play.Server.ENTITY_EFFECT, player.getEntityId(), potionEffect)
                                .createPacket(player.getEntityId(), potionEffect));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void sendSelfDisguise(final Player player) {
        try {
            if (!player.isValid()) {
                return;
            }
            Object world = ReflectionManager.getWorld(player.getWorld());
            Object tracker = world.getClass().getField("tracker").get(world);
            Object trackedEntities = tracker.getClass().getField("trackedEntities").get(tracker);
            Object entityTrackerEntry = trackedEntities.getClass().getMethod("get", int.class)
                    .invoke(trackedEntities, player.getEntityId());
            if (entityTrackerEntry == null) {
                Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() {
                    public void run() {
                        sendSelfDisguise(player);
                    }
                });
                return;
            }
            int fakeId = selfDisguisesIds.get(player.getEntityId());
            ((HashSet) entityTrackerEntry.getClass().getField("trackedPlayers").get(entityTrackerEntry)).add(ReflectionManager
                    .getNmsEntity(player));
            ProtocolManager manager = ProtocolLibrary.getProtocolManager();
            manager.sendServerPacket(player, manager.createPacketConstructor(PacketType.Play.Server.NAMED_ENTITY_SPAWN, player)
                    .createPacket(player));
            manager.sendServerPacket(
                    player,
                    manager.createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, fakeId,
                            WrappedDataWatcher.getEntityWatcher(player), true).createPacket(fakeId,
                            WrappedDataWatcher.getEntityWatcher(player), true));
            boolean isMoving = false;
            try {
                Field field = ReflectionManager.getNmsClass("EntityTrackerEntry").getDeclaredField("isMoving");
                field.setAccessible(true);
                isMoving = field.getBoolean(entityTrackerEntry);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            if (isMoving) {
                Vector velocity = player.getVelocity();
                manager.sendServerPacket(
                        player,
                        manager.createPacketConstructor(PacketType.Play.Server.ENTITY_VELOCITY, fakeId, velocity.getX(),
                                velocity.getY(), velocity.getZ()).createPacket(fakeId, velocity.getX(), velocity.getY(),
                                velocity.getZ()));
            }
            if (player.getVehicle() != null && player.getEntityId() > player.getVehicle().getEntityId()) {
                manager.sendServerPacket(player,
                        manager.createPacketConstructor(PacketType.Play.Server.ATTACH_ENTITY, 0, player, player.getVehicle())
                                .createPacket(0, player, player.getVehicle()));
            } else if (player.getPassenger() != null && player.getEntityId() > player.getPassenger().getEntityId()) {
                manager.sendServerPacket(player,
                        manager.createPacketConstructor(PacketType.Play.Server.ATTACH_ENTITY, 0, player.getPassenger(), player)
                                .createPacket(0, player.getPassenger(), player));
            }
            for (int i = 0; i < 5; i++) {
                ItemStack item;
                if (i == 0) {
                    item = player.getItemInHand();
                } else {
                    item = player.getInventory().getArmorContents()[i - 1];
                }
                if (item != null && item.getType() != Material.AIR) {
                    manager.sendServerPacket(player,
                            manager.createPacketConstructor(PacketType.Play.Server.ENTITY_EQUIPMENT, fakeId, i, item)
                                    .createPacket(fakeId, i, item));
                }
            }
            Location loc = player.getLocation();
            if (player.isSleeping()) {
                manager.sendServerPacket(
                        player,
                        manager.createPacketConstructor(PacketType.Play.Server.BED, player, loc.getBlockX(), loc.getBlockY(),
                                loc.getBlockZ()).createPacket(player, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
            }
            Iterator iterator = player.getActivePotionEffects().iterator();
            while (iterator.hasNext()) {
                PotionEffect potionEffect = (PotionEffect) iterator.next();
                manager.sendServerPacket(
                        player,
                        manager.createPacketConstructor(PacketType.Play.Server.ENTITY_EFFECT, fakeId, potionEffect).createPacket(
                                fakeId, potionEffect));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
