Java 16 support, some dodgy code hmm. Has errors with "class loaded by another plugin" which needs to be resolved
This commit is contained in:
		@@ -67,6 +67,8 @@ public class LibsDisguises extends JavaPlugin {
 | 
			
		||||
 | 
			
		||||
            instance = this;
 | 
			
		||||
 | 
			
		||||
            WatcherSanitizer.init();
 | 
			
		||||
 | 
			
		||||
            Plugin plugin = Bukkit.getPluginManager().getPlugin("ProtocolLib");
 | 
			
		||||
 | 
			
		||||
            if (plugin == null || DisguiseUtilities.isOlderThan(DisguiseUtilities.getProtocolLibRequiredVersion(), plugin.getDescription().getVersion())) {
 | 
			
		||||
@@ -105,8 +107,6 @@ public class LibsDisguises extends JavaPlugin {
 | 
			
		||||
            if (!reloaded) {
 | 
			
		||||
                commandConfig.load();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            WatcherSanitizer.init();
 | 
			
		||||
        } catch (Throwable throwable) {
 | 
			
		||||
            getUpdateChecker().doUpdate();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@ import com.comphenix.protocol.PacketType;
 | 
			
		||||
import com.comphenix.protocol.PacketType.Play.Server;
 | 
			
		||||
import com.comphenix.protocol.ProtocolLibrary;
 | 
			
		||||
import com.comphenix.protocol.events.PacketContainer;
 | 
			
		||||
import com.comphenix.protocol.reflect.StructureModifier;
 | 
			
		||||
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
 | 
			
		||||
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
 | 
			
		||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
 | 
			
		||||
@@ -16,7 +15,10 @@ import me.libraryaddict.disguise.DisguiseAPI;
 | 
			
		||||
import me.libraryaddict.disguise.DisguiseConfig;
 | 
			
		||||
import me.libraryaddict.disguise.LibsDisguises;
 | 
			
		||||
import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType;
 | 
			
		||||
import me.libraryaddict.disguise.disguisetypes.watchers.*;
 | 
			
		||||
import me.libraryaddict.disguise.disguisetypes.watchers.AbstractHorseWatcher;
 | 
			
		||||
import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher;
 | 
			
		||||
import me.libraryaddict.disguise.disguisetypes.watchers.BoatWatcher;
 | 
			
		||||
import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher;
 | 
			
		||||
import me.libraryaddict.disguise.events.DisguiseEvent;
 | 
			
		||||
import me.libraryaddict.disguise.events.UndisguiseEvent;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
 | 
			
		||||
@@ -29,7 +31,6 @@ import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.translations.LibsMsg;
 | 
			
		||||
import net.md_5.bungee.api.ChatMessageType;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.NamespacedKey;
 | 
			
		||||
import org.bukkit.boss.BarColor;
 | 
			
		||||
import org.bukkit.boss.BarStyle;
 | 
			
		||||
@@ -38,7 +39,6 @@ import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.entity.*;
 | 
			
		||||
import org.bukkit.metadata.FixedMetadataValue;
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
import org.bukkit.util.Vector;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.InvocationTargetException;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
@@ -71,7 +71,7 @@ public abstract class Disguise {
 | 
			
		||||
    /**
 | 
			
		||||
     * If set, how long before disguise expires
 | 
			
		||||
     */
 | 
			
		||||
    private long disguiseExpires;
 | 
			
		||||
    protected long disguiseExpires;
 | 
			
		||||
    /**
 | 
			
		||||
     * For when plugins may want to assign custom data to a disguise, such as who owns it
 | 
			
		||||
     */
 | 
			
		||||
@@ -370,7 +370,7 @@ public abstract class Disguise {
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void doActionBar() {
 | 
			
		||||
    protected void doActionBar() {
 | 
			
		||||
        if (getNotifyBar() == DisguiseConfig.NotifyBar.ACTION_BAR && getEntity() instanceof Player && !getEntity().hasPermission("libsdisguises.noactionbar") &&
 | 
			
		||||
                DisguiseAPI.getDisguise(getEntity()) == Disguise.this) {
 | 
			
		||||
            ((Player) getEntity()).spigot().sendMessage(ChatMessageType.ACTION_BAR, LibsMsg.ACTION_BAR_MESSAGE.getChat(getDisguiseName()));
 | 
			
		||||
@@ -394,227 +394,18 @@ public abstract class Disguise {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void createRunnable() {
 | 
			
		||||
        if (runnable != null) {
 | 
			
		||||
        if (runnable != null && !runnable.isCancelled()) {
 | 
			
		||||
            runnable.cancel();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final boolean alwaysSendVelocity;
 | 
			
		||||
 | 
			
		||||
        switch (getType()) {
 | 
			
		||||
            case EXPERIENCE_ORB:
 | 
			
		||||
            case WITHER_SKULL:
 | 
			
		||||
            case FIREWORK:
 | 
			
		||||
                alwaysSendVelocity = true;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                alwaysSendVelocity = false;
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final Double vectorY;
 | 
			
		||||
 | 
			
		||||
        switch (getType()) {
 | 
			
		||||
            case FIREWORK:
 | 
			
		||||
            case WITHER_SKULL:
 | 
			
		||||
                vectorY = 0.000001D;
 | 
			
		||||
                break;
 | 
			
		||||
            case EXPERIENCE_ORB:
 | 
			
		||||
                vectorY = 0.0221;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                vectorY = null;
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final TargetedDisguise disguise = (TargetedDisguise) this;
 | 
			
		||||
 | 
			
		||||
        // A scheduler to clean up any unused disguises.
 | 
			
		||||
        runnable = new BukkitRunnable() {
 | 
			
		||||
            private int blockX, blockY, blockZ, facing;
 | 
			
		||||
            private int deadTicks = 0;
 | 
			
		||||
            private int actionBarTicks = -1;
 | 
			
		||||
            private long lastRefreshed = System.currentTimeMillis();
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                if (!isDisguiseInUse() || getEntity() == null) {
 | 
			
		||||
                    cancel();
 | 
			
		||||
                    runnable = null;
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (++actionBarTicks % 15 == 0) {
 | 
			
		||||
                    actionBarTicks = 0;
 | 
			
		||||
 | 
			
		||||
                    doActionBar();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // If entity is no longer valid. Remove it.
 | 
			
		||||
                if (getEntity() instanceof Player && !((Player) getEntity()).isOnline()) {
 | 
			
		||||
                    removeDisguise();
 | 
			
		||||
                } else if (disguiseExpires > 0 &&
 | 
			
		||||
                        (DisguiseConfig.isDynamicExpiry() ? disguiseExpires-- == 1 : disguiseExpires < System.currentTimeMillis())) { // If disguise expired
 | 
			
		||||
                    removeDisguise();
 | 
			
		||||
 | 
			
		||||
                    if (getEntity() instanceof Player) {
 | 
			
		||||
                        LibsMsg.EXPIRED_DISGUISE.send(getEntity());
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return;
 | 
			
		||||
                } else if (!getEntity().isValid()) {
 | 
			
		||||
                    // If it has been dead for 30+ ticks
 | 
			
		||||
                    // This is to ensure that this disguise isn't removed while clients think its the real entity
 | 
			
		||||
                    // The delay is because if it sends the destroy entity packets straight away, then it means no
 | 
			
		||||
                    // death animation
 | 
			
		||||
                    // This is probably still a problem for wither and enderdragon deaths.
 | 
			
		||||
                    if (deadTicks++ > (getType() == DisguiseType.ENDER_DRAGON ? 200 : 20)) {
 | 
			
		||||
                        if (isRemoveDisguiseOnDeath()) {
 | 
			
		||||
                            removeDisguise();
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                deadTicks = 0;
 | 
			
		||||
 | 
			
		||||
                // If the disguise type is tnt, we need to resend the entity packet else it will turn invisible
 | 
			
		||||
                if (getType() == DisguiseType.FIREWORK || getType() == DisguiseType.EVOKER_FANGS) {
 | 
			
		||||
                    if (lastRefreshed + ((getType() == DisguiseType.FIREWORK ? 40 : 23) * 50) < System.currentTimeMillis()) {
 | 
			
		||||
                        lastRefreshed = System.currentTimeMillis();
 | 
			
		||||
 | 
			
		||||
                        DisguiseUtilities.refreshTrackers(disguise);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (isModifyBoundingBox()) {
 | 
			
		||||
                    DisguiseUtilities.doBoundingBox(disguise);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (getType() == DisguiseType.BAT && !((BatWatcher) getWatcher()).isHanging()) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                doVelocity(vectorY, alwaysSendVelocity);
 | 
			
		||||
 | 
			
		||||
                if (getType() == DisguiseType.EXPERIENCE_ORB) {
 | 
			
		||||
                    PacketContainer packet = new PacketContainer(Server.REL_ENTITY_MOVE);
 | 
			
		||||
 | 
			
		||||
                    packet.getIntegers().write(0, getEntity().getEntityId());
 | 
			
		||||
 | 
			
		||||
                    try {
 | 
			
		||||
                        for (Player player : DisguiseUtilities.getPerverts(disguise)) {
 | 
			
		||||
                            if (getEntity() != player) {
 | 
			
		||||
                                ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
 | 
			
		||||
                                continue;
 | 
			
		||||
                            } else if (!isSelfDisguiseVisible() || !(getEntity() instanceof Player)) {
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            PacketContainer selfPacket = packet.shallowClone();
 | 
			
		||||
 | 
			
		||||
                            selfPacket.getModifier().write(0, DisguiseAPI.getSelfDisguiseId());
 | 
			
		||||
 | 
			
		||||
                            try {
 | 
			
		||||
                                ProtocolLibrary.getProtocolManager().sendServerPacket((Player) getEntity(), selfPacket, false);
 | 
			
		||||
                            } catch (InvocationTargetException e) {
 | 
			
		||||
                                e.printStackTrace();
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    } catch (InvocationTargetException e) {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        runnable = new DisguiseRunnable(this);
 | 
			
		||||
 | 
			
		||||
        runnable.runTaskTimer(LibsDisguises.getInstance(), 1, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void doVelocity(Double vectorY, boolean alwaysSendVelocity) {
 | 
			
		||||
        // If the vectorY isn't 0. Cos if it is. Then it doesn't want to send any vectors.
 | 
			
		||||
        // If this disguise has velocity sending enabled and the entity is flying.
 | 
			
		||||
        if (isVelocitySent() && vectorY != null && (alwaysSendVelocity || !getEntity().isOnGround())) {
 | 
			
		||||
            Vector vector = getEntity().getVelocity();
 | 
			
		||||
 | 
			
		||||
            // If the entity doesn't have velocity changes already - You know. I really can't wrap my
 | 
			
		||||
            // head about the
 | 
			
		||||
            // if statement.
 | 
			
		||||
            // But it doesn't seem to do anything wrong..
 | 
			
		||||
            if (vector.getY() != 0 && !(vector.getY() < 0 && alwaysSendVelocity && getEntity().isOnGround())) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // If disguise isn't a experience orb, or the entity isn't standing on the ground
 | 
			
		||||
            if (getType() != DisguiseType.EXPERIENCE_ORB || !getEntity().isOnGround()) {
 | 
			
		||||
                PacketContainer lookPacket = null;
 | 
			
		||||
 | 
			
		||||
                if (getType() == DisguiseType.WITHER_SKULL && DisguiseConfig.isWitherSkullPacketsEnabled()) {
 | 
			
		||||
                    lookPacket = new PacketContainer(Server.ENTITY_LOOK);
 | 
			
		||||
 | 
			
		||||
                    StructureModifier<Object> mods = lookPacket.getModifier();
 | 
			
		||||
                    lookPacket.getIntegers().write(0, getEntity().getEntityId());
 | 
			
		||||
                    Location loc = getEntity().getLocation();
 | 
			
		||||
 | 
			
		||||
                    mods.write(4, DisguiseUtilities.getYaw(getType(), getEntity().getType(), (byte) Math.floor(loc.getYaw() * 256.0F / 360.0F)));
 | 
			
		||||
                    mods.write(5, DisguiseUtilities.getPitch(getType(), getEntity().getType(), (byte) Math.floor(loc.getPitch() * 256.0F / 360.0F)));
 | 
			
		||||
 | 
			
		||||
                    if (isSelfDisguiseVisible() && getEntity() instanceof Player) {
 | 
			
		||||
                        PacketContainer selfLookPacket = lookPacket.shallowClone();
 | 
			
		||||
 | 
			
		||||
                        selfLookPacket.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId());
 | 
			
		||||
 | 
			
		||||
                        try {
 | 
			
		||||
                            ProtocolLibrary.getProtocolManager().sendServerPacket((Player) getEntity(), selfLookPacket, false);
 | 
			
		||||
                        } catch (InvocationTargetException e) {
 | 
			
		||||
                            e.printStackTrace();
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                try {
 | 
			
		||||
                    PacketContainer velocityPacket = new PacketContainer(Server.ENTITY_VELOCITY);
 | 
			
		||||
 | 
			
		||||
                    StructureModifier<Integer> mods = velocityPacket.getIntegers();
 | 
			
		||||
 | 
			
		||||
                    // Write entity ID
 | 
			
		||||
                    mods.write(0, getEntity().getEntityId());
 | 
			
		||||
                    mods.write(1, (int) (vector.getX() * 8000));
 | 
			
		||||
                    mods.write(3, (int) (vector.getZ() * 8000));
 | 
			
		||||
 | 
			
		||||
                    for (Player player : DisguiseUtilities.getPerverts(this)) {
 | 
			
		||||
                        PacketContainer tempVelocityPacket = velocityPacket.shallowClone();
 | 
			
		||||
                        mods = tempVelocityPacket.getIntegers();
 | 
			
		||||
 | 
			
		||||
                        // If the viewing player is the disguised player
 | 
			
		||||
                        if (getEntity() == player) {
 | 
			
		||||
                            // If not using self disguise, continue
 | 
			
		||||
                            if (!isSelfDisguiseVisible()) {
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            // Write self disguise ID
 | 
			
		||||
                            mods.write(0, DisguiseAPI.getSelfDisguiseId());
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        mods.write(2, (int) (8000D * (vectorY * ReflectionManager.getPing(player)) * 0.069D));
 | 
			
		||||
 | 
			
		||||
                        if (lookPacket != null && player != getEntity()) {
 | 
			
		||||
                            ProtocolLibrary.getProtocolManager().sendServerPacket(player, lookPacket, false);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        ProtocolLibrary.getProtocolManager().sendServerPacket(player, tempVelocityPacket, false);
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // If we need to send a packet to update the exp position as it likes to gravitate client
 | 
			
		||||
            // sided to
 | 
			
		||||
            // players.
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the disguised entity
 | 
			
		||||
     *
 | 
			
		||||
@@ -1189,13 +980,12 @@ public abstract class Disguise {
 | 
			
		||||
        DisguiseUtilities.refreshTrackers((TargetedDisguise) this);
 | 
			
		||||
 | 
			
		||||
        // If he is a player, then self disguise himself
 | 
			
		||||
        Bukkit.getScheduler().
 | 
			
		||||
                scheduleSyncDelayedTask(LibsDisguises.getInstance(), new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        DisguiseUtilities.setupFakeDisguise(Disguise.this);
 | 
			
		||||
                    }
 | 
			
		||||
                }, 2);
 | 
			
		||||
        Bukkit.getScheduler().scheduleSyncDelayedTask(LibsDisguises.getInstance(), new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                DisguiseUtilities.setupFakeDisguise(Disguise.this);
 | 
			
		||||
            }
 | 
			
		||||
        }, 2);
 | 
			
		||||
 | 
			
		||||
        if (isHidePlayer() && getEntity() instanceof Player) {
 | 
			
		||||
            PacketContainer removeTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,227 @@
 | 
			
		||||
package me.libraryaddict.disguise.disguisetypes;
 | 
			
		||||
 | 
			
		||||
import com.comphenix.protocol.PacketType;
 | 
			
		||||
import com.comphenix.protocol.ProtocolLibrary;
 | 
			
		||||
import com.comphenix.protocol.events.PacketContainer;
 | 
			
		||||
import com.comphenix.protocol.reflect.StructureModifier;
 | 
			
		||||
import me.libraryaddict.disguise.DisguiseAPI;
 | 
			
		||||
import me.libraryaddict.disguise.DisguiseConfig;
 | 
			
		||||
import me.libraryaddict.disguise.disguisetypes.watchers.BatWatcher;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.translations.LibsMsg;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
import org.bukkit.util.Vector;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.InvocationTargetException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by libraryaddict on 20/05/2021.
 | 
			
		||||
 */
 | 
			
		||||
class DisguiseRunnable extends BukkitRunnable {
 | 
			
		||||
    private int blockX, blockY, blockZ, facing;
 | 
			
		||||
    private int deadTicks = 0;
 | 
			
		||||
    private int actionBarTicks = -1;
 | 
			
		||||
    private long lastRefreshed = System.currentTimeMillis();
 | 
			
		||||
    private Disguise disguise;
 | 
			
		||||
    final Double vectorY;
 | 
			
		||||
    final boolean alwaysSendVelocity;
 | 
			
		||||
 | 
			
		||||
    public DisguiseRunnable(Disguise disguise) {
 | 
			
		||||
        switch (disguise.getType()) {
 | 
			
		||||
            case FIREWORK:
 | 
			
		||||
            case WITHER_SKULL:
 | 
			
		||||
                vectorY = 0.000001D;
 | 
			
		||||
                alwaysSendVelocity = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case EXPERIENCE_ORB:
 | 
			
		||||
                vectorY = 0.0221;
 | 
			
		||||
                alwaysSendVelocity = true;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                vectorY = null;
 | 
			
		||||
                alwaysSendVelocity = false;
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void run() {
 | 
			
		||||
        if (!disguise.isDisguiseInUse() || disguise.getEntity() == null) {
 | 
			
		||||
            cancel();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (++actionBarTicks % 15 == 0) {
 | 
			
		||||
            actionBarTicks = 0;
 | 
			
		||||
 | 
			
		||||
            disguise.doActionBar();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If entity is no longer valid. Remove it.
 | 
			
		||||
        if (disguise.getEntity() instanceof Player && !((Player) disguise.getEntity()).isOnline()) {
 | 
			
		||||
            disguise.removeDisguise();
 | 
			
		||||
        } else if (disguise.disguiseExpires > 0 && (DisguiseConfig.isDynamicExpiry() ? disguise.disguiseExpires-- == 1 :
 | 
			
		||||
                disguise.disguiseExpires < System.currentTimeMillis())) { // If disguise expired
 | 
			
		||||
            disguise.removeDisguise();
 | 
			
		||||
 | 
			
		||||
            if (disguise.getEntity() instanceof Player) {
 | 
			
		||||
                LibsMsg.EXPIRED_DISGUISE.send(disguise.getEntity());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        } else if (!disguise.getEntity().isValid()) {
 | 
			
		||||
            // If it has been dead for 30+ ticks
 | 
			
		||||
            // This is to ensure that this disguise isn't removed while clients think its the real entity
 | 
			
		||||
            // The delay is because if it sends the destroy entity packets straight away, then it means no
 | 
			
		||||
            // death animation
 | 
			
		||||
            // This is probably still a problem for wither and enderdragon deaths.
 | 
			
		||||
            if (deadTicks++ > (disguise.getType() == DisguiseType.ENDER_DRAGON ? 200 : 20)) {
 | 
			
		||||
                if (disguise.isRemoveDisguiseOnDeath()) {
 | 
			
		||||
                    disguise.removeDisguise();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        deadTicks = 0;
 | 
			
		||||
 | 
			
		||||
        // If the disguise type is tnt, we need to resend the entity packet else it will turn invisible
 | 
			
		||||
        if (disguise.getType() == DisguiseType.FIREWORK || disguise.getType() == DisguiseType.EVOKER_FANGS) {
 | 
			
		||||
            if (lastRefreshed + ((disguise.getType() == DisguiseType.FIREWORK ? 40 : 23) * 50) < System.currentTimeMillis()) {
 | 
			
		||||
                lastRefreshed = System.currentTimeMillis();
 | 
			
		||||
 | 
			
		||||
                DisguiseUtilities.refreshTrackers((TargetedDisguise) disguise);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (disguise.isModifyBoundingBox()) {
 | 
			
		||||
            DisguiseUtilities.doBoundingBox((TargetedDisguise) disguise);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (disguise.getType() == DisguiseType.BAT && !((BatWatcher) disguise.getWatcher()).isHanging()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        doVelocity(vectorY, alwaysSendVelocity);
 | 
			
		||||
 | 
			
		||||
        if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) {
 | 
			
		||||
            PacketContainer packet = new PacketContainer(PacketType.Play.Server.REL_ENTITY_MOVE);
 | 
			
		||||
 | 
			
		||||
            packet.getIntegers().write(0, disguise.getEntity().getEntityId());
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                for (Player player : DisguiseUtilities.getPerverts(disguise)) {
 | 
			
		||||
                    if (disguise.getEntity() != player) {
 | 
			
		||||
                        ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
 | 
			
		||||
                        continue;
 | 
			
		||||
                    } else if (!disguise.isSelfDisguiseVisible() || !(disguise.getEntity() instanceof Player)) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    PacketContainer selfPacket = packet.shallowClone();
 | 
			
		||||
 | 
			
		||||
                    selfPacket.getModifier().write(0, DisguiseAPI.getSelfDisguiseId());
 | 
			
		||||
 | 
			
		||||
                    try {
 | 
			
		||||
                        ProtocolLibrary.getProtocolManager().sendServerPacket((Player) disguise.getEntity(), selfPacket, false);
 | 
			
		||||
                    } catch (InvocationTargetException e) {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } catch (InvocationTargetException e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void doVelocity(Double vectorY, boolean alwaysSendVelocity) {
 | 
			
		||||
        // If the vectorY isn't 0. Cos if it is. Then it doesn't want to send any vectors.
 | 
			
		||||
        // If this disguise has velocity sending enabled and the entity is flying.
 | 
			
		||||
        if (disguise.isVelocitySent() && vectorY != null && (alwaysSendVelocity || !disguise.getEntity().isOnGround())) {
 | 
			
		||||
            Vector vector = disguise.getEntity().getVelocity();
 | 
			
		||||
 | 
			
		||||
            // If the entity doesn't have velocity changes already - You know. I really can't wrap my
 | 
			
		||||
            // head about the
 | 
			
		||||
            // if statement.
 | 
			
		||||
            // But it doesn't seem to do anything wrong..
 | 
			
		||||
            if (vector.getY() != 0 && !(vector.getY() < 0 && alwaysSendVelocity && disguise.getEntity().isOnGround())) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // If disguise isn't a experience orb, or the entity isn't standing on the ground
 | 
			
		||||
            if (disguise.getType() != DisguiseType.EXPERIENCE_ORB || !disguise.getEntity().isOnGround()) {
 | 
			
		||||
                PacketContainer lookPacket = null;
 | 
			
		||||
 | 
			
		||||
                if (disguise.getType() == DisguiseType.WITHER_SKULL && DisguiseConfig.isWitherSkullPacketsEnabled()) {
 | 
			
		||||
                    lookPacket = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK);
 | 
			
		||||
 | 
			
		||||
                    StructureModifier<Object> mods = lookPacket.getModifier();
 | 
			
		||||
                    lookPacket.getIntegers().write(0, disguise.getEntity().getEntityId());
 | 
			
		||||
                    Location loc = disguise.getEntity().getLocation();
 | 
			
		||||
 | 
			
		||||
                    mods.write(4,
 | 
			
		||||
                            DisguiseUtilities.getYaw(disguise.getType(), disguise.getEntity().getType(), (byte) Math.floor(loc.getYaw() * 256.0F / 360.0F)));
 | 
			
		||||
                    mods.write(5, DisguiseUtilities
 | 
			
		||||
                            .getPitch(disguise.getType(), disguise.getEntity().getType(), (byte) Math.floor(loc.getPitch() * 256.0F / 360.0F)));
 | 
			
		||||
 | 
			
		||||
                    if (disguise.isSelfDisguiseVisible() && disguise.getEntity() instanceof Player) {
 | 
			
		||||
                        PacketContainer selfLookPacket = lookPacket.shallowClone();
 | 
			
		||||
 | 
			
		||||
                        selfLookPacket.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId());
 | 
			
		||||
 | 
			
		||||
                        try {
 | 
			
		||||
                            ProtocolLibrary.getProtocolManager().sendServerPacket((Player) disguise.getEntity(), selfLookPacket, false);
 | 
			
		||||
                        } catch (InvocationTargetException e) {
 | 
			
		||||
                            e.printStackTrace();
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                try {
 | 
			
		||||
                    PacketContainer velocityPacket = new PacketContainer(PacketType.Play.Server.ENTITY_VELOCITY);
 | 
			
		||||
 | 
			
		||||
                    StructureModifier<Integer> mods = velocityPacket.getIntegers();
 | 
			
		||||
 | 
			
		||||
                    // Write entity ID
 | 
			
		||||
                    mods.write(0, disguise.getEntity().getEntityId());
 | 
			
		||||
                    mods.write(1, (int) (vector.getX() * 8000));
 | 
			
		||||
                    mods.write(3, (int) (vector.getZ() * 8000));
 | 
			
		||||
 | 
			
		||||
                    for (Player player : DisguiseUtilities.getPerverts(disguise)) {
 | 
			
		||||
                        PacketContainer tempVelocityPacket = velocityPacket.shallowClone();
 | 
			
		||||
                        mods = tempVelocityPacket.getIntegers();
 | 
			
		||||
 | 
			
		||||
                        // If the viewing player is the disguised player
 | 
			
		||||
                        if (disguise.getEntity() == player) {
 | 
			
		||||
                            // If not using self disguise, continue
 | 
			
		||||
                            if (!disguise.isSelfDisguiseVisible()) {
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            // Write self disguise ID
 | 
			
		||||
                            mods.write(0, DisguiseAPI.getSelfDisguiseId());
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        mods.write(2, (int) (8000D * (vectorY * ReflectionManager.getPing(player)) * 0.069D));
 | 
			
		||||
 | 
			
		||||
                        if (lookPacket != null && player != disguise.getEntity()) {
 | 
			
		||||
                            ProtocolLibrary.getProtocolManager().sendServerPacket(player, lookPacket, false);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        ProtocolLibrary.getProtocolManager().sendServerPacket(player, tempVelocityPacket, false);
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (Exception e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // If we need to send a packet to update the exp position as it likes to gravitate client
 | 
			
		||||
            // sided to
 | 
			
		||||
            // players.
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -3,7 +3,6 @@ package me.libraryaddict.disguise.utilities.reflection.asm;
 | 
			
		||||
import org.objectweb.asm.*;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.lang.reflect.InvocationTargetException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
@@ -11,8 +10,7 @@ import java.util.Map;
 | 
			
		||||
 * Created by libraryaddict on 17/02/2020.
 | 
			
		||||
 */
 | 
			
		||||
public class Asm13 {
 | 
			
		||||
    public byte[] createClassWithoutMethods(String className, ArrayList<Map.Entry<String, String>> illegalMethods)
 | 
			
		||||
            throws IOException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
 | 
			
		||||
    public byte[] createClassWithoutMethods(String className, ArrayList<Map.Entry<String, String>> illegalMethods) throws IOException {
 | 
			
		||||
        className = className.replace(".", "/") + ".class";
 | 
			
		||||
 | 
			
		||||
        ClassReader cr = new ClassReader(getClass().getClassLoader().getResourceAsStream(className));
 | 
			
		||||
@@ -20,7 +18,6 @@ public class Asm13 {
 | 
			
		||||
 | 
			
		||||
        cr.accept(new ClassVisitor(Opcodes.ASM5, writer) {
 | 
			
		||||
            public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
 | 
			
		||||
 | 
			
		||||
                Map.Entry<String, String> entry =
 | 
			
		||||
                        illegalMethods.stream().filter(e -> e.getKey().equals(name) && e.getValue().equals(desc)).findFirst().orElse(null);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,8 +7,6 @@ import java.io.BufferedInputStream;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.Modifier;
 | 
			
		||||
import java.net.MalformedURLException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.net.URLClassLoader;
 | 
			
		||||
@@ -28,7 +26,6 @@ public class AsmLoader {
 | 
			
		||||
    private final File filePath = new File(LibsDisguises.getInstance().getDataFolder(), "libs/org-ow2-asm-9.1.jar");
 | 
			
		||||
    private boolean asmExists;
 | 
			
		||||
    private URLClassLoader classLoader;
 | 
			
		||||
    private LibsJarFile libsJarFile;
 | 
			
		||||
 | 
			
		||||
    public AsmLoader() {
 | 
			
		||||
        try {
 | 
			
		||||
@@ -47,28 +44,6 @@ public class AsmLoader {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void load() {
 | 
			
		||||
        try {
 | 
			
		||||
            ClassLoader pluginClassLoader = getClass().getClassLoader();
 | 
			
		||||
            Class c = Class.forName("org.bukkit.plugin.java.PluginClassLoader");
 | 
			
		||||
            Field file = c.getDeclaredField("file");
 | 
			
		||||
            file.setAccessible(true);
 | 
			
		||||
 | 
			
		||||
            libsJarFile = new LibsJarFile((File) file.get(pluginClassLoader));
 | 
			
		||||
 | 
			
		||||
            Field field = c.getDeclaredField("jar");
 | 
			
		||||
            field.setAccessible(true);
 | 
			
		||||
 | 
			
		||||
            Field modifiersField = Field.class.getDeclaredField("modifiers");
 | 
			
		||||
            modifiersField.setAccessible(true);
 | 
			
		||||
            modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
 | 
			
		||||
 | 
			
		||||
            field.set(pluginClassLoader, libsJarFile);
 | 
			
		||||
        } catch (Throwable e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void unload() {
 | 
			
		||||
        try {
 | 
			
		||||
            classLoader.close();
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,120 @@
 | 
			
		||||
package me.libraryaddict.disguise.utilities.reflection.asm;
 | 
			
		||||
 | 
			
		||||
import me.libraryaddict.disguise.LibsDisguises;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
 | 
			
		||||
import org.apache.commons.lang.StringUtils;
 | 
			
		||||
import org.bukkit.configuration.file.YamlConfiguration;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.nio.charset.StandardCharsets;
 | 
			
		||||
import java.util.Enumeration;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.jar.JarEntry;
 | 
			
		||||
import java.util.jar.JarFile;
 | 
			
		||||
import java.util.jar.JarOutputStream;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import java.util.zip.ZipEntry;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by libraryaddict on 20/05/2021.
 | 
			
		||||
 */
 | 
			
		||||
public class FakePluginCreator {
 | 
			
		||||
    public String getPluginYAML() {
 | 
			
		||||
        return "name: LibsDisguisesVersioning\nmain: " + getPluginClassPath().replace(".class", "").replace("/", ".") +
 | 
			
		||||
                "\ndescription: Plugin created by Libs Disguises for " +
 | 
			
		||||
                "compatibility with different versions\nversion: 1.0.0\nauthor: libraryaddict\napi-version: '1.13'\nsoftdepend: [ProtocolLib, LibsDisguises]";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public File getDestination() {
 | 
			
		||||
        return new File(LibsDisguises.getInstance().getDataFolder(), "libs/LibsDisguisesCompat.jar");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getPluginClassPath() {
 | 
			
		||||
        return "me/libraryaddict/disguise/utilities/reflection/asm/LibsDisguisesCompat.class";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getVersion() throws Exception {
 | 
			
		||||
        File dest = getDestination();
 | 
			
		||||
 | 
			
		||||
        if (!dest.exists()) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        JarFile jarFile = new JarFile(dest);
 | 
			
		||||
 | 
			
		||||
        try (InputStream stream = jarFile.getInputStream(jarFile.getEntry("version.txt"))) {
 | 
			
		||||
            return new BufferedReader(new InputStreamReader(stream)).lines().collect(Collectors.joining("\n"));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getOurVersion() {
 | 
			
		||||
        YamlConfiguration pluginYml = ReflectionManager.getPluginYAML(LibsDisguises.getInstance().getFile());
 | 
			
		||||
 | 
			
		||||
        String buildNo = StringUtils.stripToNull(pluginYml.getString("build-number"));
 | 
			
		||||
 | 
			
		||||
        return buildNo != null && buildNo.matches("[0-9]+") ? ReflectionManager.getBukkitVersion() + " " + Integer.parseInt(buildNo) :
 | 
			
		||||
                ReflectionManager.getBukkitVersion() + " CUSTOM";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void createJar(String ourVersion, Map<String, byte[]> classes) throws Exception {
 | 
			
		||||
        File dest = getDestination();
 | 
			
		||||
 | 
			
		||||
        if (!dest.getParentFile().exists()) {
 | 
			
		||||
            dest.getParentFile().mkdirs();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (dest.exists()) {
 | 
			
		||||
            dest.delete();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        JarOutputStream out = new JarOutputStream(new FileOutputStream(dest));
 | 
			
		||||
 | 
			
		||||
        out.putNextEntry(new ZipEntry("plugin.yml"));
 | 
			
		||||
        out.write(getPluginYAML().getBytes(StandardCharsets.UTF_8));
 | 
			
		||||
        out.closeEntry();
 | 
			
		||||
 | 
			
		||||
        // Write our main plugin class
 | 
			
		||||
        try (JarFile jar = new JarFile(LibsDisguises.getInstance().getFile())) {
 | 
			
		||||
            Enumeration<JarEntry> entries = jar.entries();
 | 
			
		||||
            String mainPath = getPluginClassPath().replace(".class", "");
 | 
			
		||||
 | 
			
		||||
            while (entries.hasMoreElements()) {
 | 
			
		||||
                JarEntry entry = entries.nextElement();
 | 
			
		||||
 | 
			
		||||
                if (!entry.getName().equals(mainPath) && !entry.getName().startsWith("me/libraryaddict/disguise/disguisetypes/")) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (classes.containsKey(entry.getName())) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                out.putNextEntry(new ZipEntry(entry.getName().equals(mainPath) ? getPluginClassPath() : entry.getName()));
 | 
			
		||||
 | 
			
		||||
                try (InputStream stream = jar.getInputStream(entry)) {
 | 
			
		||||
                    int nRead;
 | 
			
		||||
                    byte[] data = new byte[1024];
 | 
			
		||||
                    while ((nRead = stream.read(data, 0, data.length)) != -1) {
 | 
			
		||||
                        out.write(data, 0, nRead);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                out.closeEntry();
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception ex) {
 | 
			
		||||
            ex.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (Map.Entry<String, byte[]> entry : classes.entrySet()) {
 | 
			
		||||
            out.putNextEntry(new ZipEntry(entry.getKey()));
 | 
			
		||||
            out.write(entry.getValue());
 | 
			
		||||
            out.closeEntry();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        out.putNextEntry(new ZipEntry("version.txt"));
 | 
			
		||||
        out.write(ourVersion.getBytes(StandardCharsets.UTF_8));
 | 
			
		||||
        out.closeEntry();
 | 
			
		||||
 | 
			
		||||
        out.close();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
package me.libraryaddict.disguise.utilities.reflection.asm;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.plugin.java.JavaPlugin;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by libraryaddict on 20/05/2021.
 | 
			
		||||
 */
 | 
			
		||||
public class LibsDisguisesCompat extends JavaPlugin {
 | 
			
		||||
}
 | 
			
		||||
@@ -1,39 +0,0 @@
 | 
			
		||||
package me.libraryaddict.disguise.utilities.reflection.asm;
 | 
			
		||||
 | 
			
		||||
import java.io.ByteArrayInputStream;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.jar.JarFile;
 | 
			
		||||
import java.util.zip.ZipEntry;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by libraryaddict on 15/05/2021.
 | 
			
		||||
 */
 | 
			
		||||
public class LibsJarFile extends JarFile {
 | 
			
		||||
    private final HashMap<String, byte[]> customFiles = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    public LibsJarFile(File file) throws IOException {
 | 
			
		||||
        super(file);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public synchronized InputStream getInputStream(ZipEntry ze) throws IOException {
 | 
			
		||||
        if (customFiles.containsKey(ze.getName())) {
 | 
			
		||||
            return new ByteArrayInputStream(customFiles.get(ze.getName()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return super.getInputStream(ze);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addClass(String name, byte[] bytes) {
 | 
			
		||||
        customFiles.put(name, bytes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void close() throws IOException {
 | 
			
		||||
        customFiles.clear();
 | 
			
		||||
        super.close();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -3,9 +3,12 @@ package me.libraryaddict.disguise.utilities.reflection.asm;
 | 
			
		||||
import com.google.gson.Gson;
 | 
			
		||||
import me.libraryaddict.disguise.LibsDisguises;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
import org.bukkit.plugin.PluginDescriptionFile;
 | 
			
		||||
import org.bukkit.plugin.java.JavaPluginLoader;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
@@ -69,11 +72,29 @@ public class WatcherSanitizer {
 | 
			
		||||
        } catch (NoSuchFieldException | IllegalAccessException ignored) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (Bukkit.getPluginManager().getPlugin("LibsDisguisesVersioning") != null) {
 | 
			
		||||
            throw new IllegalStateException("Why is LibsDisguisesVersioning already active? Did the server owner do something.. Weird?");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        FakePluginCreator fakePluginCreator = new FakePluginCreator();
 | 
			
		||||
 | 
			
		||||
        String ourVers = fakePluginCreator.getOurVersion();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            if (ourVers != null && ourVers.equals(fakePluginCreator.getVersion()) && !ourVers.contains(" CUSTOM")) {
 | 
			
		||||
                loadPlugin(fakePluginCreator);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        LibsDisguises.getInstance().getLogger().info("Creating a new version compatibility jar");
 | 
			
		||||
 | 
			
		||||
        ArrayList<String> mapped = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        try (InputStream stream = LibsDisguises.getInstance().getResource("ANTI_PIRACY_ENCRYPTION")) {
 | 
			
		||||
            AsmLoader loader = new AsmLoader();
 | 
			
		||||
            loader.load();
 | 
			
		||||
 | 
			
		||||
            Object obj;
 | 
			
		||||
            Method getBytes;
 | 
			
		||||
@@ -109,15 +130,18 @@ public class WatcherSanitizer {
 | 
			
		||||
                list.add(new HashMap.SimpleEntry(info.getMethod(), info.getDescriptor()));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Map<String, byte[]> classes = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
            for (Map.Entry<String, ArrayList<Map.Entry<String, String>>> entry : toRemove.entrySet()) {
 | 
			
		||||
                byte[] bytes = (byte[]) getBytes.invoke(obj, entry.getKey(), entry.getValue());
 | 
			
		||||
                mapped.add(entry.getKey());
 | 
			
		||||
 | 
			
		||||
                String name = entry.getKey().replace(".", "/") + ".class";
 | 
			
		||||
 | 
			
		||||
                loader.getLibsJarFile().addClass(name, bytes);
 | 
			
		||||
                classes.put(entry.getKey().replace(".", "/") + ".class", bytes);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            fakePluginCreator.createJar(ourVers, classes);
 | 
			
		||||
            loadPlugin(fakePluginCreator);
 | 
			
		||||
 | 
			
		||||
            if (!loader.isAsmExists()) {
 | 
			
		||||
                loader.unload();
 | 
			
		||||
            }
 | 
			
		||||
@@ -126,4 +150,32 @@ public class WatcherSanitizer {
 | 
			
		||||
            LibsDisguises.getInstance().getLogger().severe("Registered: " + new Gson().toJson(mapped));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void loadPlugin(FakePluginCreator fakePluginCreator) throws Exception {
 | 
			
		||||
        LibsDisguises.getInstance().getLogger().info("Starting version support plugin: LibsDisguisesVersioning");
 | 
			
		||||
        Method method = Class.forName("org.bukkit.plugin.PluginManager", false, WatcherSanitizer.class.getClassLoader().getParent())
 | 
			
		||||
                .getMethod("loadPlugin", File.class);
 | 
			
		||||
 | 
			
		||||
        Plugin plugin = (Plugin) method.invoke(Bukkit.getPluginManager(), fakePluginCreator.getDestination());
 | 
			
		||||
 | 
			
		||||
        Class pluginClassLoader = Class.forName("org.bukkit.plugin.java.PluginClassLoader");
 | 
			
		||||
 | 
			
		||||
        Field loaderField = JavaPluginLoader.class.getDeclaredField("loaders");
 | 
			
		||||
        loaderField.setAccessible(true);
 | 
			
		||||
        List loaderList = (List) loaderField.get(LibsDisguises.getInstance().getPluginLoader());
 | 
			
		||||
 | 
			
		||||
        Field pluginOwner = pluginClassLoader.getDeclaredField("plugin");
 | 
			
		||||
        pluginOwner.setAccessible(true);
 | 
			
		||||
 | 
			
		||||
        // Move Lib's Disguises to load its classes after the new plugin
 | 
			
		||||
        for (Object o : loaderList) {
 | 
			
		||||
            if (pluginOwner.get(o) != LibsDisguises.getInstance()) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            loaderList.remove(o);
 | 
			
		||||
            loaderList.add(o);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import me.libraryaddict.disguise.utilities.LibsPremium;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.reflection.ClassGetter;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.reflection.NmsAddedIn;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.reflection.NmsRemovedIn;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.reflection.asm.FakePluginCreator;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.sounds.DisguiseSoundEnums;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.sounds.SoundGroup;
 | 
			
		||||
import org.apache.commons.lang.StringUtils;
 | 
			
		||||
@@ -34,6 +35,14 @@ public class CompileMethods {
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        doMethods();
 | 
			
		||||
        doSounds();
 | 
			
		||||
        moveCompat();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void moveCompat() {
 | 
			
		||||
        FakePluginCreator creator = new FakePluginCreator();
 | 
			
		||||
 | 
			
		||||
        File compatFile = new File("target/classes/" + creator.getPluginClassPath());
 | 
			
		||||
        compatFile.renameTo(new File(compatFile.getParentFile(), compatFile.getName().replace(".class", "")));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void doSounds() {
 | 
			
		||||
@@ -91,8 +100,7 @@ public class CompileMethods {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void doMethods() {
 | 
			
		||||
        ArrayList<Class<?>> classes =
 | 
			
		||||
                ClassGetter.getClassesForPackage(FlagWatcher.class, "me.libraryaddict.disguise.disguisetypes.watchers");
 | 
			
		||||
        ArrayList<Class<?>> classes = ClassGetter.getClassesForPackage(FlagWatcher.class, "me.libraryaddict.disguise.disguisetypes.watchers");
 | 
			
		||||
 | 
			
		||||
        ArrayList<Class> sorted = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
@@ -106,12 +114,10 @@ public class CompileMethods {
 | 
			
		||||
            for (Method method : c.getMethods()) {
 | 
			
		||||
                if (!FlagWatcher.class.isAssignableFrom(method.getDeclaringClass())) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                } else if (method.getParameterCount() > 1 && !method.isAnnotationPresent(NmsAddedIn.class) &&
 | 
			
		||||
                        !method.isAnnotationPresent(NmsRemovedIn.class)) {
 | 
			
		||||
                } else if (method.getParameterCount() > 1 && !method.isAnnotationPresent(NmsAddedIn.class) && !method.isAnnotationPresent(NmsRemovedIn.class)) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                } else if (!(method.getName().startsWith("set") && method.getParameterCount() == 1) &&
 | 
			
		||||
                        !method.getName().startsWith("get") && !method.getName().startsWith("has") &&
 | 
			
		||||
                        !method.getName().startsWith("is")) {
 | 
			
		||||
                } else if (!(method.getName().startsWith("set") && method.getParameterCount() == 1) && !method.getName().startsWith("get") &&
 | 
			
		||||
                        !method.getName().startsWith("has") && !method.getName().startsWith("is")) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                } else if (method.getName().equals("removePotionEffect")) {
 | 
			
		||||
                    continue;
 | 
			
		||||
@@ -141,8 +147,7 @@ public class CompileMethods {
 | 
			
		||||
                    descriptor = ":" + getMethodDescriptor(method) + ":" + added + ":" + removed;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                String s =
 | 
			
		||||
                        method.getDeclaringClass().getSimpleName() + ":" + method.getName() + ":" + param + descriptor;
 | 
			
		||||
                String s = method.getDeclaringClass().getSimpleName() + ":" + method.getName() + ":" + param + descriptor;
 | 
			
		||||
 | 
			
		||||
                if (methods.contains(s)) {
 | 
			
		||||
                    continue;
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ build-date: ${timestamp}
 | 
			
		||||
build-number: ${build.number}
 | 
			
		||||
author: libraryaddict
 | 
			
		||||
authors: [Byteflux, Navid K.]
 | 
			
		||||
softdepend: [ProtocolLib]
 | 
			
		||||
softdepend: [ProtocolLib, LibsDisguisesVersioning]
 | 
			
		||||
api-version: '1.13'
 | 
			
		||||
commands:
 | 
			
		||||
  libsdisguises:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user