Rewrite stuff to use MethodHandles, and saved disguises to use disguise.toString instead of original format. Updated for java 16
This commit is contained in:
		| @@ -6,28 +6,23 @@ import com.comphenix.protocol.wrappers.WrappedWatchableObject; | ||||
| import lombok.Getter; | ||||
| import me.libraryaddict.disguise.disguisetypes.*; | ||||
| import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.AbstractHorseWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; | ||||
| import me.libraryaddict.disguise.utilities.DisguiseUtilities; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguiseParser; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguisePerm; | ||||
| import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; | ||||
| import org.bukkit.DyeColor; | ||||
| import org.bukkit.Material; | ||||
| import org.bukkit.command.CommandSender; | ||||
| import org.bukkit.configuration.ConfigurationSection; | ||||
| import org.bukkit.configuration.file.YamlConfiguration; | ||||
| import org.bukkit.entity.*; | ||||
| import org.bukkit.entity.Entity; | ||||
| import org.bukkit.entity.LivingEntity; | ||||
| import org.bukkit.entity.Player; | ||||
| import org.bukkit.inventory.EntityEquipment; | ||||
| import org.bukkit.inventory.HorseInventory; | ||||
| import org.bukkit.inventory.ItemStack; | ||||
| import org.bukkit.potion.PotionEffect; | ||||
| import org.bukkit.potion.PotionEffectType; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.Arrays; | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
|   | ||||
| @@ -18,7 +18,6 @@ import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; | ||||
| import me.libraryaddict.disguise.utilities.translations.LibsMsg; | ||||
| import me.libraryaddict.disguise.utilities.translations.TranslateType; | ||||
| import org.bukkit.Bukkit; | ||||
| import org.bukkit.ChatColor; | ||||
| import org.bukkit.NamespacedKey; | ||||
| import org.bukkit.boss.BarColor; | ||||
| import org.bukkit.boss.BarStyle; | ||||
| @@ -31,7 +30,6 @@ import org.bukkit.permissions.PermissionDefault; | ||||
| import org.bukkit.scheduler.BukkitTask; | ||||
|  | ||||
| import java.io.*; | ||||
| import java.lang.reflect.InvocationTargetException; | ||||
| import java.util.*; | ||||
| import java.util.Map.Entry; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| @@ -462,7 +460,7 @@ public class DisguiseConfig { | ||||
|  | ||||
|         try { | ||||
|             return new HashMap.SimpleEntry(entry.getKey(), DisguiseParser.parseDisguise(entry.getValue())); | ||||
|         } catch (IllegalAccessException | InvocationTargetException | DisguiseParseException e) { | ||||
|         } catch (Throwable e) { | ||||
|             DisguiseUtilities.getLogger().warning("Error when attempting to grab the custom disguise " + disguise); | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
| @@ -470,8 +468,7 @@ public class DisguiseConfig { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public static Entry<DisguisePerm, Disguise> getCustomDisguise(Entity target, String disguise) | ||||
|             throws IllegalAccessException, DisguiseParseException, InvocationTargetException { | ||||
|     public static Entry<DisguisePerm, Disguise> getCustomDisguise(Entity target, String disguise) throws Throwable { | ||||
|         if (!Bukkit.isPrimaryThread()) { | ||||
|             throw new IllegalStateException("Custom Disguises should not be called async!"); | ||||
|         } | ||||
| @@ -485,8 +482,7 @@ public class DisguiseConfig { | ||||
|         return new HashMap.SimpleEntry(entry.getKey(), DisguiseParser.parseDisguise(Bukkit.getConsoleSender(), target, entry.getValue())); | ||||
|     } | ||||
|  | ||||
|     public static Entry<DisguisePerm, Disguise> getCustomDisguise(CommandSender invoker, Entity target, String disguise) | ||||
|             throws IllegalAccessException, DisguiseParseException, InvocationTargetException { | ||||
|     public static Entry<DisguisePerm, Disguise> getCustomDisguise(CommandSender invoker, Entity target, String disguise) throws Throwable { | ||||
|         if (!Bukkit.isPrimaryThread()) { | ||||
|             throw new IllegalStateException("Custom Disguises should not be called async!"); | ||||
|         } | ||||
| @@ -946,7 +942,7 @@ public class DisguiseConfig { | ||||
|             DisguiseUtilities.getLogger().info("Loaded custom disguise " + disguiseName); | ||||
|         } catch (DisguiseParseException e) { | ||||
|             throw new DisguiseParseException(LibsMsg.ERROR_LOADING_CUSTOM_DISGUISE, disguiseName, (e.getMessage() == null ? "" : ": " + e.getMessage())); | ||||
|         } catch (IllegalAccessException | InvocationTargetException e) { | ||||
|         } catch (Throwable e) { | ||||
|             e.printStackTrace(); | ||||
|             throw new DisguiseParseException(LibsMsg.ERROR_LOADING_CUSTOM_DISGUISE, disguiseName, ""); | ||||
|         } | ||||
|   | ||||
| @@ -27,14 +27,12 @@ import me.libraryaddict.disguise.utilities.packets.PacketsManager; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguiseParser; | ||||
| import me.libraryaddict.disguise.utilities.reflection.NmsVersion; | ||||
| import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; | ||||
| import me.libraryaddict.disguise.utilities.reflection.asm.WatcherSanitizer; | ||||
| import me.libraryaddict.disguise.utilities.sounds.SoundManager; | ||||
| import me.libraryaddict.disguise.utilities.updates.UpdateChecker; | ||||
| import org.apache.commons.lang.StringUtils; | ||||
| import org.bukkit.Bukkit; | ||||
| import org.bukkit.command.*; | ||||
| import org.bukkit.configuration.file.YamlConfiguration; | ||||
| import org.bukkit.entity.Player; | ||||
| import org.bukkit.plugin.Plugin; | ||||
| import org.bukkit.plugin.java.JavaPlugin; | ||||
| import org.bukkit.scheduler.BukkitRunnable; | ||||
| @@ -67,8 +65,6 @@ 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())) { | ||||
|   | ||||
| @@ -18,6 +18,7 @@ import me.libraryaddict.disguise.utilities.params.ParamInfoManager; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguiseParser; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguisePerm; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguisePermissions; | ||||
| import me.libraryaddict.disguise.utilities.parser.WatcherMethod; | ||||
| import org.bukkit.Bukkit; | ||||
| import org.bukkit.ChatColor; | ||||
| import org.bukkit.command.CommandExecutor; | ||||
| @@ -25,7 +26,6 @@ import org.bukkit.command.CommandSender; | ||||
| import org.bukkit.entity.Player; | ||||
| import org.bukkit.inventory.ItemStack; | ||||
|  | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.*; | ||||
|  | ||||
| /** | ||||
| @@ -118,11 +118,11 @@ public abstract class DisguiseBaseCommand implements CommandExecutor { | ||||
|             DisguisePerm disguisePerm, String[] allArgs, int startsAt, String currentArg) { | ||||
|         ArrayList<String> usedOptions = new ArrayList<>(); | ||||
|  | ||||
|         Method[] methods = ParamInfoManager.getDisguiseWatcherMethods(disguisePerm.getWatcherClass()); | ||||
|         WatcherMethod[] methods = ParamInfoManager.getDisguiseWatcherMethods(disguisePerm.getWatcherClass()); | ||||
|  | ||||
|         // Find which methods the disguiser has already used | ||||
|         for (int i = startsAt; i < allArgs.length; i++) { | ||||
|             for (Method method : methods) { | ||||
|             for (WatcherMethod method : methods) { | ||||
|                 String arg = allArgs[i]; | ||||
|  | ||||
|                 if (!method.getName().equalsIgnoreCase(arg)) { | ||||
| @@ -186,7 +186,7 @@ public abstract class DisguiseBaseCommand implements CommandExecutor { | ||||
|  | ||||
|         if (addMethods) { | ||||
|             // If this is a method, add. Else if it can be a param of the previous argument, add. | ||||
|             for (Method method : ParamInfoManager.getDisguiseWatcherMethods(disguisePerm.getWatcherClass())) { | ||||
|             for (WatcherMethod method : ParamInfoManager.getDisguiseWatcherMethods(disguisePerm.getWatcherClass())) { | ||||
|                 if (!perms.isAllowedDisguise(disguisePerm, Collections.singletonList(method.getName()))) { | ||||
|                     continue; | ||||
|                 } | ||||
|   | ||||
| @@ -50,7 +50,7 @@ public class DisguiseCommand extends DisguiseBaseCommand implements TabCompleter | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|         catch (Exception ex) { | ||||
|         catch (Throwable ex) { | ||||
|             ex.printStackTrace(); | ||||
|             return true; | ||||
|         } | ||||
|   | ||||
| @@ -16,7 +16,6 @@ import org.bukkit.command.CommandSender; | ||||
| import org.bukkit.command.TabCompleter; | ||||
| import org.bukkit.entity.Player; | ||||
|  | ||||
| import java.lang.reflect.InvocationTargetException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @@ -46,27 +45,22 @@ public class DisguiseEntityCommand extends DisguiseBaseCommand implements TabCom | ||||
|         Disguise testDisguise; | ||||
|  | ||||
|         try { | ||||
|             testDisguise = DisguiseParser | ||||
|                     .parseTestDisguise(sender, getPermNode(), disguiseArgs, getPermissions(sender)); | ||||
|         } | ||||
|         catch (DisguiseParseException ex) { | ||||
|             testDisguise = DisguiseParser.parseTestDisguise(sender, getPermNode(), disguiseArgs, getPermissions(sender)); | ||||
|         } catch (DisguiseParseException ex) { | ||||
|             if (ex.getMessage() != null) { | ||||
|                 DisguiseUtilities.sendMessage(sender, ex.getMessage()); | ||||
|             } | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|         catch (IllegalAccessException | InvocationTargetException ex) { | ||||
|         } catch (Throwable ex) { | ||||
|             ex.printStackTrace(); | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         LibsDisguises.getInstance().getListener() | ||||
|                 .addInteraction(sender.getName(), new DisguiseEntityInteraction(disguiseArgs), | ||||
|                         DisguiseConfig.getDisguiseEntityExpire()); | ||||
|                 .addInteraction(sender.getName(), new DisguiseEntityInteraction(disguiseArgs), DisguiseConfig.getDisguiseEntityExpire()); | ||||
|  | ||||
|         LibsMsg.DISG_ENT_CLICK.send(sender, DisguiseConfig.getDisguiseEntityExpire(), | ||||
|                 testDisguise.getDisguiseName()); | ||||
|         LibsMsg.DISG_ENT_CLICK.send(sender, DisguiseConfig.getDisguiseEntityExpire(), testDisguise.getDisguiseName()); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @@ -98,8 +92,7 @@ public class DisguiseEntityCommand extends DisguiseBaseCommand implements TabCom | ||||
|         } | ||||
|  | ||||
|         LibsMsg.DISG_ENT_HELP1.send(sender); | ||||
|         LibsMsg.CAN_USE_DISGS.send(sender, | ||||
|                 StringUtils.join(allowedDisguises, LibsMsg.CAN_USE_DISGS_SEPERATOR.get())); | ||||
|         LibsMsg.CAN_USE_DISGS.send(sender, StringUtils.join(allowedDisguises, LibsMsg.CAN_USE_DISGS_SEPERATOR.get())); | ||||
|  | ||||
|         if (allowedDisguises.contains("player")) { | ||||
|             LibsMsg.DISG_ENT_HELP3.send(sender); | ||||
|   | ||||
| @@ -54,8 +54,7 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom | ||||
|             if (args[0].contains("-")) { | ||||
|                 try { | ||||
|                     entityTarget = Bukkit.getEntity(UUID.fromString(args[0])); | ||||
|                 } | ||||
|                 catch (Exception ignored) { | ||||
|                 } catch (Exception ignored) { | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -76,17 +75,13 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom | ||||
|         Disguise disguise; | ||||
|  | ||||
|         try { | ||||
|             disguise = DisguiseParser.parseDisguise(sender, entityTarget, getPermNode(), | ||||
|                     DisguiseUtilities.split(StringUtils.join(newArgs, " ")), permissions); | ||||
|         } | ||||
|         catch (DisguiseParseException ex) { | ||||
|             disguise = DisguiseParser.parseDisguise(sender, entityTarget, getPermNode(), DisguiseUtilities.split(StringUtils.join(newArgs, " ")), permissions); | ||||
|         } catch (DisguiseParseException ex) { | ||||
|             if (ex.getMessage() != null) { | ||||
|                 DisguiseUtilities.sendMessage(sender, ex.getMessage()); | ||||
|             } | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         catch (Exception ex) { | ||||
|         } catch (Throwable ex) { | ||||
|             ex.printStackTrace(); | ||||
|             return true; | ||||
|         } | ||||
| @@ -96,8 +91,7 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         if (DisguiseConfig.isNameOfPlayerShownAboveDisguise() && | ||||
|                 !entityTarget.hasPermission("libsdisguises.hidename")) { | ||||
|         if (DisguiseConfig.isNameOfPlayerShownAboveDisguise() && !entityTarget.hasPermission("libsdisguises.hidename")) { | ||||
|             if (disguise.getWatcher() instanceof LivingWatcher) { | ||||
|                 disguise.getWatcher().setCustomName(getDisplayName(entityTarget)); | ||||
|  | ||||
| @@ -111,9 +105,9 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom | ||||
|  | ||||
|         if (!setViewDisguise(args)) { | ||||
|             // They prefer to have the opposite of whatever the view disguises option is | ||||
|             if (DisguiseAPI.hasSelfDisguisePreference(disguise.getEntity()) && | ||||
|                     disguise.isSelfDisguiseVisible() == DisguiseConfig.isViewDisguises()) | ||||
|             if (DisguiseAPI.hasSelfDisguisePreference(disguise.getEntity()) && disguise.isSelfDisguiseVisible() == DisguiseConfig.isViewDisguises()) { | ||||
|                 disguise.setViewSelfDisguise(!disguise.isSelfDisguiseVisible()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!DisguiseAPI.isActionBarShown(disguise.getEntity())) { | ||||
| @@ -123,13 +117,12 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom | ||||
|         disguise.startDisguise(sender); | ||||
|  | ||||
|         if (disguise.isDisguiseInUse()) { | ||||
|             LibsMsg.DISG_PLAYER_AS_DISG.send(sender, | ||||
|                     entityTarget instanceof Player ? entityTarget.getName() : | ||||
|                             DisguiseType.getType(entityTarget).toReadable(), disguise.getDisguiseName()); | ||||
|             LibsMsg.DISG_PLAYER_AS_DISG.send(sender, entityTarget instanceof Player ? entityTarget.getName() : DisguiseType.getType(entityTarget).toReadable(), | ||||
|                     disguise.getDisguiseName()); | ||||
|         } else { | ||||
|             LibsMsg.DISG_PLAYER_AS_DISG_FAIL.send(sender, | ||||
|                     entityTarget instanceof Player ? entityTarget.getName() : | ||||
|                             DisguiseType.getType(entityTarget).toReadable(), disguise.getDisguiseName()); | ||||
|             LibsMsg.DISG_PLAYER_AS_DISG_FAIL | ||||
|                     .send(sender, entityTarget instanceof Player ? entityTarget.getName() : DisguiseType.getType(entityTarget).toReadable(), | ||||
|                             disguise.getDisguiseName()); | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
| @@ -137,8 +130,9 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom | ||||
|  | ||||
|     private boolean setViewDisguise(String[] strings) { | ||||
|         for (String string : strings) { | ||||
|             if (!string.equalsIgnoreCase("setSelfDisguiseVisible")) | ||||
|             if (!string.equalsIgnoreCase("setSelfDisguiseVisible")) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
| @@ -182,8 +176,7 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom | ||||
|         } | ||||
|  | ||||
|         LibsMsg.D_HELP1.send(sender); | ||||
|         LibsMsg.CAN_USE_DISGS.send(sender, | ||||
|                 StringUtils.join(allowedDisguises, LibsMsg.CAN_USE_DISGS_SEPERATOR.get())); | ||||
|         LibsMsg.CAN_USE_DISGS.send(sender, StringUtils.join(allowedDisguises, LibsMsg.CAN_USE_DISGS_SEPERATOR.get())); | ||||
|  | ||||
|         if (allowedDisguises.contains("player")) { | ||||
|             LibsMsg.D_HELP3.send(sender); | ||||
|   | ||||
| @@ -66,8 +66,7 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         if (args[0].equalsIgnoreCase(TranslateType.DISGUISES.get("EntityType")) || | ||||
|                 args[0].equalsIgnoreCase(TranslateType.DISGUISES.get("EntityType") + "s")) { | ||||
|         if (args[0].equalsIgnoreCase(TranslateType.DISGUISES.get("EntityType")) || args[0].equalsIgnoreCase(TranslateType.DISGUISES.get("EntityType") + "s")) { | ||||
|             ArrayList<String> classes = new ArrayList<>(); | ||||
|  | ||||
|             for (Class c : validClasses) { | ||||
| @@ -76,8 +75,7 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom | ||||
|  | ||||
|             Collections.sort(classes); | ||||
|  | ||||
|             LibsMsg.DRADIUS_ENTITIES.send(sender, | ||||
|                     ChatColor.GREEN + StringUtils.join(classes, ChatColor.DARK_GREEN + ", " + ChatColor.GREEN)); | ||||
|             LibsMsg.DRADIUS_ENTITIES.send(sender, ChatColor.GREEN + StringUtils.join(classes, ChatColor.DARK_GREEN + ", " + ChatColor.GREEN)); | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
| @@ -97,8 +95,7 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom | ||||
|             if (starting == 0) { | ||||
|                 try { | ||||
|                     type = EntityType.valueOf(args[0].toUpperCase(Locale.ENGLISH)); | ||||
|                 } | ||||
|                 catch (Exception ignored) { | ||||
|                 } catch (Exception ignored) { | ||||
|                 } | ||||
|  | ||||
|                 if (type == null) { | ||||
| @@ -168,17 +165,14 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 if (testDisguise.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled() && | ||||
|                         entity instanceof LivingEntity) { | ||||
|                 if (testDisguise.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled() && entity instanceof LivingEntity) { | ||||
|                     miscDisguises++; | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 Disguise disguise = DisguiseParser | ||||
|                         .parseDisguise(sender, entity, getPermNode(), disguiseArgs, permissions); | ||||
|                 Disguise disguise = DisguiseParser.parseDisguise(sender, entity, getPermNode(), disguiseArgs, permissions); | ||||
|  | ||||
|                 if (entity instanceof Player && DisguiseConfig.isNameOfPlayerShownAboveDisguise() && | ||||
|                         !entity.hasPermission("libsdisguises.hidename")) { | ||||
|                 if (entity instanceof Player && DisguiseConfig.isNameOfPlayerShownAboveDisguise() && !entity.hasPermission("libsdisguises.hidename")) { | ||||
|                     if (disguise.getWatcher() instanceof LivingWatcher) { | ||||
|                         disguise.getWatcher().setCustomName(getDisplayName(entity)); | ||||
|                         if (DisguiseConfig.isNameAboveHeadAlwaysVisible()) { | ||||
| @@ -191,9 +185,9 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom | ||||
|  | ||||
|                 if (!setViewDisguise(args)) { | ||||
|                     // They prefer to have the opposite of whatever the view disguises option is | ||||
|                     if (DisguiseAPI.hasSelfDisguisePreference(disguise.getEntity()) && | ||||
|                             disguise.isSelfDisguiseVisible() == DisguiseConfig.isViewDisguises()) | ||||
|                     if (DisguiseAPI.hasSelfDisguisePreference(disguise.getEntity()) && disguise.isSelfDisguiseVisible() == DisguiseConfig.isViewDisguises()) { | ||||
|                         disguise.setViewSelfDisguise(!disguise.isSelfDisguiseVisible()); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if (!DisguiseAPI.isActionBarShown(disguise.getEntity())) { | ||||
| @@ -216,13 +210,11 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom | ||||
|             if (miscDisguises > 0) { | ||||
|                 LibsMsg.DRADIUS_MISCDISG.send(sender, miscDisguises); | ||||
|             } | ||||
|         } | ||||
|         catch (DisguiseParseException ex) { | ||||
|         } catch (DisguiseParseException ex) { | ||||
|             if (ex.getMessage() != null) { | ||||
|                 DisguiseUtilities.sendMessage(sender, ex.getMessage()); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) { | ||||
|         } catch (Throwable ex) { | ||||
|             ex.printStackTrace(); | ||||
|         } | ||||
|  | ||||
| @@ -231,8 +223,9 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom | ||||
|  | ||||
|     private boolean setViewDisguise(String[] strings) { | ||||
|         for (String string : strings) { | ||||
|             if (!string.equalsIgnoreCase("setSelfDisguiseVisible")) | ||||
|             if (!string.equalsIgnoreCase("setSelfDisguiseVisible")) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
| @@ -259,16 +252,18 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom | ||||
|  | ||||
|         if (!isInteger(args[0])) { | ||||
|             for (Class c : validClasses) { | ||||
|                 if (!TranslateType.DISGUISES.get(c.getSimpleName()).equalsIgnoreCase(args[0])) | ||||
|                 if (!TranslateType.DISGUISES.get(c.getSimpleName()).equalsIgnoreCase(args[0])) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 starting = 2; | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             // Not a valid radius | ||||
|             if (starting == 1 || args.length == 1 || !isInteger(args[1])) | ||||
|             if (starting == 1 || args.length == 1 || !isInteger(args[1])) { | ||||
|                 return filterTabs(tabs, origArgs); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         tabs.addAll(getTabDisguiseTypes(sender, perms, args, starting, getCurrentArg(origArgs))); | ||||
|   | ||||
| @@ -11,7 +11,6 @@ import me.libraryaddict.disguise.utilities.LibsEntityInteract; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguiseParser; | ||||
| import me.libraryaddict.disguise.utilities.translations.LibsMsg; | ||||
| import org.bukkit.ChatColor; | ||||
| import org.bukkit.command.CommandSender; | ||||
| import org.bukkit.entity.Entity; | ||||
| import org.bukkit.entity.LivingEntity; | ||||
| @@ -37,25 +36,22 @@ public class DisguiseEntityInteraction implements LibsEntityInteract { | ||||
|         Disguise disguise; | ||||
|  | ||||
|         try { | ||||
|             disguise = DisguiseParser.parseDisguise(p, entity, "disguiseentity", disguiseArgs, | ||||
|                     DisguiseParser.getPermissions(p, "disguiseentity")); | ||||
|             disguise = DisguiseParser.parseDisguise(p, entity, "disguiseentity", disguiseArgs, DisguiseParser.getPermissions(p, "disguiseentity")); | ||||
|         } catch (DisguiseParseException e) { | ||||
|             if (e.getMessage() != null) { | ||||
|                 DisguiseUtilities.sendMessage(p, e.getMessage()); | ||||
|             } | ||||
|  | ||||
|             return; | ||||
|         } catch (Exception e) { | ||||
|         } catch (Throwable e) { | ||||
|             e.printStackTrace(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (disguise.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled() && | ||||
|                 entity instanceof LivingEntity) { | ||||
|         if (disguise.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled() && entity instanceof LivingEntity) { | ||||
|             LibsMsg.DISABLED_LIVING_TO_MISC.send(p); | ||||
|         } else { | ||||
|             if (entity instanceof Player && DisguiseConfig.isNameOfPlayerShownAboveDisguise() && | ||||
|                     !entity.hasPermission("libsdisguises.hidename")) { | ||||
|             if (entity instanceof Player && DisguiseConfig.isNameOfPlayerShownAboveDisguise() && !entity.hasPermission("libsdisguises.hidename")) { | ||||
|                 if (disguise.getWatcher() instanceof LivingWatcher) { | ||||
|                     disguise.getWatcher().setCustomName(getDisplayName(entity)); | ||||
|  | ||||
|   | ||||
| @@ -53,17 +53,13 @@ public class DisguiseModifyInteraction implements LibsEntityInteract { | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             DisguiseParser | ||||
|                     .callMethods(p, disguise, perms, disguisePerm, new ArrayList<>(Arrays.asList(options)), options, | ||||
|                             "DisguiseModifyEntity"); | ||||
|             DisguiseParser.callMethods(p, disguise, perms, disguisePerm, new ArrayList<>(Arrays.asList(options)), options, "DisguiseModifyEntity"); | ||||
|             LibsMsg.LISTENER_MODIFIED_DISG.send(p); | ||||
|         } | ||||
|         catch (DisguiseParseException ex) { | ||||
|         } catch (DisguiseParseException ex) { | ||||
|             if (ex.getMessage() != null) { | ||||
|                 DisguiseUtilities.sendMessage(p, ex.getMessage()); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) { | ||||
|         } catch (Throwable ex) { | ||||
|             ex.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -68,7 +68,7 @@ public class DisguiseModifyCommand extends DisguiseBaseCommand implements TabCom | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|         catch (Exception ex) { | ||||
|         catch (Throwable ex) { | ||||
|             ex.printStackTrace(); | ||||
|             return true; | ||||
|         } | ||||
|   | ||||
| @@ -97,7 +97,7 @@ public class DisguiseModifyPlayerCommand extends DisguiseBaseCommand implements | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         catch (Exception ex) { | ||||
|         catch (Throwable ex) { | ||||
|             ex.printStackTrace(); | ||||
|             return true; | ||||
|         } | ||||
|   | ||||
| @@ -7,10 +7,7 @@ import me.libraryaddict.disguise.disguisetypes.Disguise; | ||||
| import me.libraryaddict.disguise.disguisetypes.DisguiseType; | ||||
| import me.libraryaddict.disguise.utilities.DisguiseUtilities; | ||||
| import me.libraryaddict.disguise.utilities.params.ParamInfoManager; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguiseParser; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguisePerm; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguisePermissions; | ||||
| import me.libraryaddict.disguise.utilities.parser.*; | ||||
| import me.libraryaddict.disguise.utilities.translations.LibsMsg; | ||||
| import me.libraryaddict.disguise.utilities.translations.TranslateType; | ||||
| import org.apache.commons.lang.StringUtils; | ||||
| @@ -23,7 +20,6 @@ import org.bukkit.command.TabCompleter; | ||||
| import org.bukkit.entity.Entity; | ||||
| import org.bukkit.entity.Player; | ||||
|  | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.*; | ||||
|  | ||||
| public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements TabCompleter { | ||||
| @@ -177,7 +173,7 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements | ||||
|                 } | ||||
|  | ||||
|                 return true; | ||||
|             } catch (Exception ex) { | ||||
|             } catch (Throwable ex) { | ||||
|                 ex.printStackTrace(); | ||||
|                 return true; | ||||
|             } | ||||
| @@ -259,7 +255,7 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements | ||||
|  | ||||
|             DisguiseType disguiseType = disguise.getType(); | ||||
|  | ||||
|             for (Method method : ParamInfoManager.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { | ||||
|             for (WatcherMethod method : ParamInfoManager.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { | ||||
|                 for (String arg : args) { | ||||
|                     if (!method.getName().equalsIgnoreCase(arg) || usedOptions.contains(arg)) { | ||||
|                         continue; | ||||
|   | ||||
| @@ -6,6 +6,7 @@ import me.libraryaddict.disguise.utilities.params.ParamInfoManager; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguiseParser; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguisePerm; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguisePermissions; | ||||
| import me.libraryaddict.disguise.utilities.parser.WatcherMethod; | ||||
| import me.libraryaddict.disguise.utilities.translations.LibsMsg; | ||||
| import me.libraryaddict.disguise.utilities.translations.TranslateType; | ||||
| import org.apache.commons.lang.StringUtils; | ||||
| @@ -14,7 +15,6 @@ import org.bukkit.command.Command; | ||||
| import org.bukkit.command.CommandSender; | ||||
| import org.bukkit.command.TabCompleter; | ||||
|  | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| @@ -79,7 +79,7 @@ public class DisguiseHelpCommand extends DisguiseBaseCommand implements TabCompl | ||||
|                 int ignored = 0; | ||||
|  | ||||
|                 try { | ||||
|                     for (Method method : ParamInfoManager.getDisguiseWatcherMethods(watcher)) { | ||||
|                     for (WatcherMethod method : ParamInfoManager.getDisguiseWatcherMethods(watcher)) { | ||||
|                         if (args.length < 2 || !args[1].equalsIgnoreCase(LibsMsg.DHELP_SHOW.get())) { | ||||
|                             if (!perms.isAllowedDisguise(type, Collections.singleton(method.getName().toLowerCase( | ||||
|                                     Locale.ENGLISH)))) { | ||||
|   | ||||
| @@ -262,7 +262,7 @@ public abstract class Disguise { | ||||
|             } catch (Exception e) { | ||||
|                 e.printStackTrace(); | ||||
|             } | ||||
|         } else { | ||||
|         } else if (getWatcher().getDisguise() != this) { | ||||
|             getWatcher().setDisguise((TargetedDisguise) this); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -586,11 +586,16 @@ public class FlagWatcher { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     protected TargetedDisguise getDisguise() { | ||||
|     public TargetedDisguise getDisguise() { | ||||
|         return disguise; | ||||
|     } | ||||
|  | ||||
|     protected void setDisguise(TargetedDisguise disguise) { | ||||
|     @Deprecated | ||||
|     public void setDisguise(TargetedDisguise disguise) { | ||||
|         if (this.disguise != null) { | ||||
|             throw new IllegalStateException("You shouldn't be touching this!"); | ||||
|         } | ||||
|  | ||||
|         this.disguise = disguise; | ||||
|         equipment.setFlagWatcher(this); | ||||
|  | ||||
|   | ||||
| @@ -19,7 +19,6 @@ import org.bukkit.entity.Player; | ||||
| import org.bukkit.scheduler.BukkitRunnable; | ||||
|  | ||||
| import java.lang.reflect.InvocationTargetException; | ||||
| import java.util.UUID; | ||||
|  | ||||
| public class PlayerDisguise extends TargetedDisguise { | ||||
|     private transient LibsProfileLookup currentLookup; | ||||
|   | ||||
| @@ -4,7 +4,6 @@ import com.comphenix.protocol.PacketType; | ||||
| import com.comphenix.protocol.ProtocolLibrary; | ||||
| import com.comphenix.protocol.events.PacketContainer; | ||||
| import com.comphenix.protocol.reflect.StructureModifier; | ||||
| import lombok.Getter; | ||||
| import me.libraryaddict.disguise.DisguiseAPI; | ||||
| import me.libraryaddict.disguise.disguisetypes.Disguise; | ||||
| import me.libraryaddict.disguise.disguisetypes.FlagWatcher; | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| package me.libraryaddict.disguise.disguisetypes.watchers; | ||||
|  | ||||
| import lombok.Getter; | ||||
| import me.libraryaddict.disguise.disguisetypes.Disguise; | ||||
| import me.libraryaddict.disguise.disguisetypes.GolemCrack; | ||||
| import me.libraryaddict.disguise.utilities.reflection.NmsAddedIn; | ||||
|   | ||||
| @@ -11,7 +11,6 @@ import me.libraryaddict.disguise.disguisetypes.Disguise; | ||||
| import me.libraryaddict.disguise.disguisetypes.FlagWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.MetaIndex; | ||||
| import me.libraryaddict.disguise.utilities.DisguiseUtilities; | ||||
| import me.libraryaddict.disguise.utilities.parser.RandomDefaultValue; | ||||
| import me.libraryaddict.disguise.utilities.reflection.NmsAddedIn; | ||||
| import me.libraryaddict.disguise.utilities.reflection.NmsVersion; | ||||
| import org.bukkit.Color; | ||||
|   | ||||
| @@ -18,7 +18,6 @@ import lombok.Getter; | ||||
| import lombok.Setter; | ||||
| import me.libraryaddict.disguise.DisguiseAPI; | ||||
| import me.libraryaddict.disguise.DisguiseConfig; | ||||
| import me.libraryaddict.disguise.DisguiseConfig.DisguisePushing; | ||||
| import me.libraryaddict.disguise.LibsDisguises; | ||||
| import me.libraryaddict.disguise.disguisetypes.*; | ||||
| import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType; | ||||
| @@ -29,6 +28,7 @@ import me.libraryaddict.disguise.utilities.json.*; | ||||
| import me.libraryaddict.disguise.utilities.mineskin.MineSkinAPI; | ||||
| import me.libraryaddict.disguise.utilities.packets.LibsPackets; | ||||
| import me.libraryaddict.disguise.utilities.packets.PacketsManager; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguiseParser; | ||||
| import me.libraryaddict.disguise.utilities.reflection.FakeBoundingBox; | ||||
| import me.libraryaddict.disguise.utilities.reflection.LibsProfileLookup; | ||||
| import me.libraryaddict.disguise.utilities.reflection.NmsVersion; | ||||
| @@ -194,6 +194,25 @@ public class DisguiseUtilities { | ||||
|     private static long lastSavedPreferences; | ||||
|     @Getter | ||||
|     private final static ConcurrentHashMap<String, DScoreTeam> teams = new ConcurrentHashMap<>(); | ||||
|     private final static boolean java16; | ||||
|     private static boolean criedOverJava16; | ||||
|  | ||||
|     static { | ||||
|         final Matcher matcher = Pattern.compile("(?:1\\.)?(\\d+)").matcher(System.getProperty("java.version")); | ||||
|  | ||||
|         if (!matcher.find()) { | ||||
|             java16 = true; | ||||
|         } else { | ||||
|             int vers = 16; | ||||
|  | ||||
|             try { | ||||
|                 vers = Integer.parseInt(matcher.group(1)); | ||||
|             } catch (NumberFormatException ignored) { | ||||
|             } | ||||
|  | ||||
|             java16 = vers >= 16; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Only allow saves every 2 minutes | ||||
| @@ -607,19 +626,19 @@ public class DisguiseUtilities { | ||||
|                     disguiseFile.delete(); | ||||
|                 } | ||||
|             } else { | ||||
|                 Disguise[] disguises = new Disguise[disguise.length]; | ||||
|  | ||||
|                 for (int i = 0; i < disguise.length; i++) { | ||||
|                     Disguise dis = disguise[i].clone(); | ||||
|                     dis.setEntity(null); | ||||
|  | ||||
|                     disguises[i] = dis; | ||||
|                 } | ||||
|  | ||||
|                 // I hear pirates don't obey standards | ||||
|                 @SuppressWarnings("MismatchedStringCase") | ||||
|                 PrintWriter writer = new PrintWriter(disguiseFile, "12345".equals("%%__USER__%%") ? "US-ASCII" : "UTF-8"); | ||||
|                 writer.write(gson.toJson(disguises)); | ||||
|  | ||||
|                 for (int i = 0; i < disguise.length; i++) { | ||||
|                     writer.write(DisguiseParser.parseToString(disguise[i])); | ||||
|  | ||||
|                     if (i + 1 < disguise.length) { | ||||
|                         writer.write("\n"); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 writer.close(); | ||||
|  | ||||
|                 savedDisguiseList.add(owningEntity); | ||||
| @@ -662,14 +681,36 @@ public class DisguiseUtilities { | ||||
|                 removeSavedDisguise(entityUUID); | ||||
|             } | ||||
|  | ||||
|             Disguise[] disguises = gson.fromJson(cached, Disguise[].class); | ||||
|             Disguise[] disguises; | ||||
|  | ||||
|             if (cached.isEmpty()) { | ||||
|                 return new Disguise[0]; | ||||
|             } | ||||
|  | ||||
|             if (Character.isAlphabetic(cached.charAt(0))) { | ||||
|                 String[] spl = cached.split("\n"); | ||||
|                 disguises = new Disguise[spl.length]; | ||||
|  | ||||
|                 for (int i = 0; i < disguises.length; i++) { | ||||
|                     disguises[i] = DisguiseParser.parseDisguise(spl[i]); | ||||
|                 } | ||||
|             } else if (!java16) { | ||||
|                 disguises = gson.fromJson(cached, Disguise[].class); | ||||
|             } else { | ||||
|                 if (!criedOverJava16) { | ||||
|                     criedOverJava16 = true; | ||||
|                     getLogger().warning("Failed to load a disguise using old format, this is due to Java 16 breaking stuff. This error will only print once."); | ||||
|                 } | ||||
|  | ||||
|                 return new Disguise[0]; | ||||
|             } | ||||
|  | ||||
|             if (disguises == null) { | ||||
|                 return new Disguise[0]; | ||||
|             } | ||||
|  | ||||
|             return disguises; | ||||
|         } catch (Exception e) { | ||||
|         } catch (Throwable e) { | ||||
|             getLogger().severe("Malformed disguise for " + entityUUID); | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|   | ||||
| @@ -3,18 +3,19 @@ package me.libraryaddict.disguise.utilities.json; | ||||
| import com.google.gson.*; | ||||
| import me.libraryaddict.disguise.disguisetypes.*; | ||||
|  | ||||
| import java.lang.invoke.MethodHandle; | ||||
| import java.lang.invoke.MethodHandles; | ||||
| import java.lang.invoke.MethodType; | ||||
| import java.lang.reflect.Method; | ||||
| import java.lang.reflect.Type; | ||||
|  | ||||
| /** | ||||
|  * Created by libraryaddict on 1/06/2017. | ||||
|  */ | ||||
| public class SerializerDisguise implements JsonDeserializer<Disguise>, JsonSerializer<Disguise>, | ||||
|         InstanceCreator<Disguise> { | ||||
| public class SerializerDisguise implements JsonDeserializer<Disguise>, JsonSerializer<Disguise>, InstanceCreator<Disguise> { | ||||
|  | ||||
|     @Override | ||||
|     public Disguise deserialize(JsonElement json, Type typeOfT, | ||||
|             JsonDeserializationContext context) throws JsonParseException { | ||||
|     public Disguise deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { | ||||
|         JsonObject obj = (JsonObject) json; | ||||
|         DisguiseType type = DisguiseType.valueOf(obj.get("disguiseType").getAsString()); | ||||
|         TargetedDisguise disg; | ||||
| @@ -25,29 +26,24 @@ public class SerializerDisguise implements JsonDeserializer<Disguise>, JsonSeria | ||||
|             disg = context.deserialize(json, MobDisguise.class); | ||||
|         } else if (type.isMisc()) { | ||||
|             disg = context.deserialize(json, MiscDisguise.class); | ||||
|         } else | ||||
|         } else { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             Method method = FlagWatcher.class.getDeclaredMethod("setDisguise", TargetedDisguise.class); | ||||
|             method.setAccessible(true); | ||||
|             method.invoke(disg.getWatcher(), disg); | ||||
|         } | ||||
|         catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|         disg.getWatcher().setDisguise(disg); | ||||
|  | ||||
|         return disg; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Disguise createInstance(Type type) { | ||||
|         if (type == PlayerDisguise.class) | ||||
|         if (type == PlayerDisguise.class) { | ||||
|             return new PlayerDisguise("SaveDisgError"); | ||||
|         else if (type == MobDisguise.class) | ||||
|         } else if (type == MobDisguise.class) { | ||||
|             return new MobDisguise(DisguiseType.SHEEP); | ||||
|         else if (type == MiscDisguise.class) | ||||
|         } else if (type == MiscDisguise.class) { | ||||
|             return new MiscDisguise(DisguiseType.BOAT); | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
| @@ -56,12 +52,13 @@ public class SerializerDisguise implements JsonDeserializer<Disguise>, JsonSeria | ||||
|     public JsonElement serialize(Disguise src, Type typeOfSrc, JsonSerializationContext context) { | ||||
|         if (src.isCustomDisguise()) { | ||||
|             return context.serialize(src, ModdedDisguise.class); | ||||
|         } else if (src.isPlayerDisguise()) | ||||
|         } else if (src.isPlayerDisguise()) { | ||||
|             return context.serialize(src, PlayerDisguise.class); | ||||
|         else if (src.isMobDisguise()) | ||||
|         } else if (src.isMobDisguise()) { | ||||
|             return context.serialize(src, MobDisguise.class); | ||||
|         else if (src.isMiscDisguise()) | ||||
|         } else if (src.isMiscDisguise()) { | ||||
|             return context.serialize(src, MiscDisguise.class); | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|   | ||||
| @@ -11,6 +11,9 @@ import me.libraryaddict.disguise.utilities.params.types.custom.ParamInfoParticle | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; | ||||
| import org.bukkit.inventory.ItemStack; | ||||
|  | ||||
| import java.lang.invoke.MethodHandle; | ||||
| import java.lang.invoke.MethodHandles; | ||||
| import java.lang.invoke.MethodType; | ||||
| import java.lang.reflect.Field; | ||||
| import java.lang.reflect.Method; | ||||
| import java.lang.reflect.ParameterizedType; | ||||
| @@ -141,15 +144,7 @@ public class SerializerFlagWatcher implements JsonDeserializer<FlagWatcher>, Jso | ||||
|         JsonObject obj = (JsonObject) gson.toJsonTree(src); | ||||
|  | ||||
|         obj.addProperty("flagType", src.getClass().getName()); | ||||
|  | ||||
|         try { | ||||
|             Method method = FlagWatcher.class.getDeclaredMethod("getDisguise"); | ||||
|             method.setAccessible(true); | ||||
|             Disguise disguise = (Disguise) method.invoke(src); | ||||
|             obj.addProperty("entityType", disguise.getType().name()); | ||||
|         } catch (Exception ex) { | ||||
|             ex.printStackTrace(); | ||||
|         } | ||||
|         obj.addProperty("entityType", src.getDisguise().getType().name()); | ||||
|  | ||||
|         return obj; | ||||
|     } | ||||
|   | ||||
| @@ -24,7 +24,6 @@ import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; | ||||
| import org.bukkit.Art; | ||||
| import org.bukkit.Location; | ||||
| import org.bukkit.Material; | ||||
| import org.bukkit.block.data.BlockData; | ||||
| import org.bukkit.entity.Damageable; | ||||
| import org.bukkit.entity.Entity; | ||||
| import org.bukkit.entity.EntityType; | ||||
|   | ||||
| @@ -1,32 +1,26 @@ | ||||
| package me.libraryaddict.disguise.utilities.params; | ||||
|  | ||||
| import lombok.Getter; | ||||
| import me.libraryaddict.disguise.DisguiseConfig; | ||||
| import me.libraryaddict.disguise.disguisetypes.Disguise; | ||||
| import me.libraryaddict.disguise.disguisetypes.DisguiseType; | ||||
| import me.libraryaddict.disguise.disguisetypes.FlagWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.FallingBlockWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher; | ||||
| import me.libraryaddict.disguise.utilities.params.types.custom.ParamInfoItemBlock; | ||||
| import me.libraryaddict.disguise.utilities.params.types.custom.ParamInfoSoundGroup; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguisePerm; | ||||
| import me.libraryaddict.disguise.utilities.parser.WatcherMethod; | ||||
| import me.libraryaddict.disguise.utilities.watchers.DisguiseMethods; | ||||
| import org.bukkit.ChatColor; | ||||
| import org.bukkit.Material; | ||||
| import org.bukkit.boss.BarColor; | ||||
| import org.bukkit.boss.BarStyle; | ||||
| import org.bukkit.inventory.ItemStack; | ||||
|  | ||||
| import javax.annotation.Nullable; | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Locale; | ||||
|  | ||||
| public class ParamInfoManager { | ||||
|     private static List<ParamInfo> paramList; | ||||
|     @Getter | ||||
|     private static DisguiseMethods disguiseMethods; | ||||
|     @Getter | ||||
|     private static ParamInfoItemBlock paramInfoItemBlock; | ||||
| @@ -51,17 +45,16 @@ public class ParamInfoManager { | ||||
|         return info.toString(object); | ||||
|     } | ||||
|  | ||||
|     public static ParamInfo getParamInfo(Method method) { | ||||
|     public static ParamInfo getParamInfo(WatcherMethod method) { | ||||
|         if (method.getName().equals("setSoundGroup")) { | ||||
|             return getParamInfoSoundGroup(); | ||||
|         } | ||||
|  | ||||
|         if (method.getDeclaringClass() == FallingBlockWatcher.class && | ||||
|                 (method.getParameterTypes()[0] == Material.class || method.getParameterTypes()[0] == ItemStack.class)) { | ||||
|         if (method.getWatcherClass() == FallingBlockWatcher.class && (method.getParam() == Material.class || method.getParam() == ItemStack.class)) { | ||||
|             return getParamInfoItemBlock(); | ||||
|         } | ||||
|  | ||||
|         return getParamInfo(method.getParameterTypes()[0]); | ||||
|         return getParamInfo(method.getParam()); | ||||
|     } | ||||
|  | ||||
|     public static ParamInfo getParamInfo(Class c) { | ||||
| @@ -81,7 +74,7 @@ public class ParamInfoManager { | ||||
|     } | ||||
|  | ||||
|     public static ParamInfo getParamInfo(DisguiseType disguiseType, String methodName) { | ||||
|         for (Method method : getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { | ||||
|         for (WatcherMethod method : getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { | ||||
|             if (!method.getName().toLowerCase(Locale.ENGLISH).equals(methodName.toLowerCase(Locale.ENGLISH))) { | ||||
|                 continue; | ||||
|             } | ||||
| @@ -96,22 +89,18 @@ public class ParamInfoManager { | ||||
|         ParamInfoTypes infoTypes = new ParamInfoTypes(); | ||||
|         paramList = infoTypes.getParamInfos(); | ||||
|         paramInfoItemBlock = infoTypes.getParamInfoBlock(); | ||||
|         paramInfoSoundGroup = | ||||
|                 (ParamInfoSoundGroup) paramList.stream().filter(p -> p instanceof ParamInfoSoundGroup).findAny() | ||||
|                         .orElse(null); | ||||
|         paramInfoSoundGroup = (ParamInfoSoundGroup) paramList.stream().filter(p -> p instanceof ParamInfoSoundGroup).findAny().orElse(null); | ||||
|         disguiseMethods = new DisguiseMethods(); | ||||
|  | ||||
|         //paramList.sort((o1, o2) -> String.CASE_INSENSITIVE_ORDER.compare(o1.getName(), o2.getName())); | ||||
|     } | ||||
|  | ||||
|     public static Method[] getDisguiseWatcherMethods( | ||||
|             @Nullable | ||||
|                     Class<? extends FlagWatcher> watcherClass) { | ||||
|     public static WatcherMethod[] getDisguiseWatcherMethods(@Nullable Class<? extends FlagWatcher> watcherClass) { | ||||
|         if (watcherClass == null) { | ||||
|             return new Method[0]; | ||||
|             return new WatcherMethod[0]; | ||||
|         } | ||||
|  | ||||
|         ArrayList<Method> methods = new ArrayList<>(disguiseMethods.getMethods(watcherClass)); | ||||
|         ArrayList<WatcherMethod> methods = new ArrayList<>(disguiseMethods.getMethods(watcherClass)); | ||||
|  | ||||
|         // Order first by their declaring class, the top class (SheepWatcher) goes before (FlagWatcher) | ||||
|         // Order methods in the same watcher by their name from A to Z | ||||
| @@ -126,59 +115,16 @@ public class ParamInfoManager { | ||||
|             return String.CASE_INSENSITIVE_ORDER.compare(m1.getName(), m2.getName()); | ||||
|         }); | ||||
|  | ||||
|         // Add these last as it's what we want to present to be called the least | ||||
|         for (String methodName : new String[]{"setSelfDisguiseVisible", "setHideHeldItemFromSelf", | ||||
|                 "setHideArmorFromSelf", "setHearSelfDisguise", "setHidePlayer", "setExpires", "setNotifyBar", | ||||
|                 "setBossBarColor", "setBossBarStyle", "setTallDisguisesVisible", "setDynamicName", "setSoundGroup", | ||||
|                 "setDisguiseName", "setDeadmau5Ears"}) { | ||||
|             try { | ||||
|                 Class cl = boolean.class; | ||||
|                 Class disguiseClass = Disguise.class; | ||||
|  | ||||
|                 switch (methodName) { | ||||
|                     case "setExpires": | ||||
|                         cl = long.class; | ||||
|                         break; | ||||
|                     case "setNotifyBar": | ||||
|                         cl = DisguiseConfig.NotifyBar.class; | ||||
|                         break; | ||||
|                     case "setBossBarColor": | ||||
|                         cl = BarColor.class; | ||||
|                         break; | ||||
|                     case "setBossBarStyle": | ||||
|                         cl = BarStyle.class; | ||||
|                         break; | ||||
|                     case "setSoundGroup": | ||||
|                     case "setDisguiseName": | ||||
|                         cl = String.class; | ||||
|                         break; | ||||
|                     case "setDeadmau5Ears": | ||||
|                         if (watcherClass != PlayerWatcher.class) { | ||||
|                             continue; | ||||
|                         } | ||||
|  | ||||
|                         disguiseClass = PlayerDisguise.class; | ||||
|                         break; | ||||
|                     default: | ||||
|                         break; | ||||
|                 } | ||||
|  | ||||
|                 methods.add(disguiseClass.getMethod(methodName, cl)); | ||||
|             } catch (Exception ex) { | ||||
|                 ex.printStackTrace(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return methods.toArray(new Method[0]); | ||||
|         return methods.toArray(new WatcherMethod[0]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Value of the method, used namely for ordering the more unique methods to a disguise | ||||
|      */ | ||||
|     public static int getValue(Method method) { | ||||
|         ChatColor methodColor = ChatColor.YELLOW; | ||||
|  | ||||
|         Class<?> declaring = method.getDeclaringClass(); | ||||
|     public static int getValue(WatcherMethod method) { | ||||
|         Class<?> declaring = method.getWatcherClass(); | ||||
|  | ||||
|         if (declaring == LivingWatcher.class) { | ||||
|             return 1; | ||||
|   | ||||
| @@ -14,7 +14,6 @@ import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; | ||||
| import me.libraryaddict.disguise.utilities.translations.LibsMsg; | ||||
| import me.libraryaddict.disguise.utilities.translations.TranslateType; | ||||
| import org.bukkit.Bukkit; | ||||
| import org.bukkit.ChatColor; | ||||
| import org.bukkit.Material; | ||||
| import org.bukkit.block.data.BlockData; | ||||
| import org.bukkit.command.CommandSender; | ||||
| @@ -26,8 +25,10 @@ import org.bukkit.inventory.ItemStack; | ||||
| import org.bukkit.permissions.PermissionAttachmentInfo; | ||||
| import org.bukkit.potion.PotionEffectType; | ||||
|  | ||||
| import java.lang.invoke.MethodHandle; | ||||
| import java.lang.invoke.MethodHandles; | ||||
| import java.lang.invoke.MethodType; | ||||
| import java.lang.reflect.InvocationTargetException; | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.*; | ||||
| import java.util.Map.Entry; | ||||
| import java.util.concurrent.ThreadLocalRandom; | ||||
| @@ -37,10 +38,12 @@ public class DisguiseParser { | ||||
|     /** | ||||
|      * <Setter, <Getter, DefaultValue>> | ||||
|      */ | ||||
|     private static HashMap<Method, Map.Entry<Method, Object>> defaultWatcherValues = new HashMap<>(); | ||||
|     private static HashMap<WatcherMethod, Map.Entry<WatcherMethod, Object>> defaultWatcherValues = new HashMap<>(); | ||||
|  | ||||
|     public static void createDefaultMethods() { | ||||
|         try { | ||||
|             ArrayList<WatcherMethod> allMethods = ParamInfoManager.getDisguiseMethods().getMethods(); | ||||
|  | ||||
|             for (DisguiseType type : DisguiseType.values()) { | ||||
|                 if (type.getEntityType() == null) { | ||||
|                     continue; | ||||
| @@ -60,19 +63,19 @@ public class DisguiseParser { | ||||
|  | ||||
|                 FlagWatcher watcher = type.getWatcherClass().getConstructor(Disguise.class).newInstance(disguise); | ||||
|  | ||||
|                 Method[] methods = ParamInfoManager.getDisguiseWatcherMethods(watcher.getClass()); | ||||
|                 WatcherMethod[] methods = ParamInfoManager.getDisguiseWatcherMethods(watcher.getClass()); | ||||
|  | ||||
|                 for (Method setMethod : methods) { | ||||
|                 for (WatcherMethod setMethod : methods) { | ||||
|                     // Invalidate methods that can't be handled normally | ||||
|                     if (setMethod.getName().equals("addPotionEffect")) { | ||||
|                         continue; | ||||
|                     } else if (setMethod.getName().equals("setSkin") && setMethod.getParameterTypes()[0] == String.class) { | ||||
|                     } else if (setMethod.getName().equals("setSkin") && setMethod.getParam() == String.class) { | ||||
|                         continue; | ||||
|                     } else if (setMethod.getName().equals("setTarget") && setMethod.getParameterTypes()[0] != int.class) { | ||||
|                     } else if (setMethod.getName().equals("setTarget") && setMethod.getParam() != int.class) { | ||||
|                         continue; | ||||
|                     } else if (setMethod.getName().equals("setItemInMainHand") && setMethod.getParameterTypes()[0] == Material.class) { | ||||
|                     } else if (setMethod.getName().equals("setItemInMainHand") && setMethod.getParam() == Material.class) { | ||||
|                         continue; | ||||
|                     } else if (setMethod.getName().matches("setArmor") && setMethod.getParameterTypes()[0] == ItemStack[].class) { | ||||
|                     } else if (setMethod.getName().matches("setArmor") && setMethod.getParam() == ItemStack[].class) { | ||||
|                         continue; | ||||
|                     } | ||||
|  | ||||
| @@ -82,37 +85,50 @@ public class DisguiseParser { | ||||
|                         getName = "hasNectar"; | ||||
|                     } else if (getName.equals("HasStung")) { | ||||
|                         getName = "hasStung"; | ||||
|                     } else if (setMethod.getParameterTypes()[0].isAssignableFrom(boolean.class)) { | ||||
|                     } else if (setMethod.getParam().isAssignableFrom(boolean.class)) { | ||||
|                         getName = "is" + getName; | ||||
|                     } else { | ||||
|                         getName = "get" + getName; | ||||
|                     } | ||||
|  | ||||
|                     Method getMethod = setMethod.getDeclaringClass().getMethod(getName); | ||||
|                     WatcherMethod getMethod = null; | ||||
|  | ||||
|                     for (WatcherMethod m : allMethods) { | ||||
|                         if (m.getWatcherClass() != setMethod.getWatcherClass() || m.getParam() != null) { | ||||
|                             continue; | ||||
|                         } | ||||
|  | ||||
|                         if (!m.getName().equals(getName)) { | ||||
|                             continue; | ||||
|                         } | ||||
|  | ||||
|                         getMethod = m; | ||||
|                         break; | ||||
|                     } | ||||
|  | ||||
|                     if (getMethod == null) { | ||||
|                         DisguiseUtilities.getLogger().severe(String | ||||
|                                 .format("No such method '%s' when looking for the companion of '%s' in '%s'", getName, setMethod.getName(), | ||||
|                                         setMethod.getDeclaringClass().getSimpleName())); | ||||
|                                         setMethod.getWatcherClass().getSimpleName())); | ||||
|                         continue; | ||||
|                     } else if (getMethod.getReturnType() != setMethod.getParameterTypes()[0]) { | ||||
|                     } else if (getMethod.getReturnType() != setMethod.getParam()) { | ||||
|                         DisguiseUtilities.getLogger().severe(String | ||||
|                                 .format("Invalid return type of '%s' when looking for the companion of '%s' in '%s'", getName, setMethod.getName(), | ||||
|                                         setMethod.getDeclaringClass().getSimpleName())); | ||||
|                                         setMethod.getWatcherClass().getSimpleName())); | ||||
|                         continue; | ||||
|                     } | ||||
|  | ||||
|                     Object defaultValue = null; | ||||
|  | ||||
|                     // Value is randomish so shouldn't be checked, should always specify value when setting | ||||
|                     if (!setMethod.isAnnotationPresent(RandomDefaultValue.class)) { | ||||
|                     if (!setMethod.isRandomDefault()) { | ||||
|                         Object invokeWith = watcher; | ||||
|  | ||||
|                         if (!FlagWatcher.class.isAssignableFrom(getMethod.getDeclaringClass())) { | ||||
|                         if (!FlagWatcher.class.isAssignableFrom(getMethod.getWatcherClass())) { | ||||
|                             invokeWith = disguise; | ||||
|                         } | ||||
|  | ||||
|                         defaultValue = getMethod.invoke(invokeWith); | ||||
|                         defaultValue = getMethod.getMethod().bindTo(invokeWith).invoke(); | ||||
|                     } | ||||
|  | ||||
|                     addWatcherDefault(setMethod, getMethod, defaultValue); | ||||
| @@ -120,10 +136,12 @@ public class DisguiseParser { | ||||
|             } | ||||
|         } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { | ||||
|             e.printStackTrace(); | ||||
|         } catch (Throwable throwable) { | ||||
|             throwable.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static HashMap<Method, Entry<Method, Object>> getMethodDefaults() { | ||||
|     public static HashMap<WatcherMethod, Entry<WatcherMethod, Object>> getMethodDefaults() { | ||||
|         return defaultWatcherValues; | ||||
|     } | ||||
|  | ||||
| @@ -144,14 +162,16 @@ public class DisguiseParser { | ||||
|                 stringBuilder.append(" ").append(DisguiseUtilities.quote(((PlayerDisguise) disguise).getName())); | ||||
|             } | ||||
|  | ||||
|             Method[] methods = ParamInfoManager.getDisguiseWatcherMethods(disguise.getType().getWatcherClass()); | ||||
|             WatcherMethod[] methods = ParamInfoManager.getDisguiseWatcherMethods(disguise.getType().getWatcherClass()); | ||||
|  | ||||
|             for (int i = methods.length - 1; i >= 0; i--) { | ||||
|                 Method m = methods[i]; | ||||
|                 WatcherMethod m = methods[i]; | ||||
|  | ||||
|                 // Special handling for this method | ||||
|                 if (m.getName().equals("addPotionEffect")) { | ||||
|                     PotionEffectType[] types = (PotionEffectType[]) m.getDeclaringClass().getMethod("getPotionEffects").invoke(disguise.getWatcher()); | ||||
|                     MethodHandle getPotion = | ||||
|                             MethodHandles.publicLookup().bind(disguise.getWatcher(), "getPotionEffects", MethodType.methodType(PotionEffectType[].class)); | ||||
|                     PotionEffectType[] types = (PotionEffectType[]) getPotion.invoke(); | ||||
|  | ||||
|                     for (PotionEffectType type : types) { | ||||
|                         if (type == null) { | ||||
| @@ -169,15 +189,15 @@ public class DisguiseParser { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 Entry<Method, Object> entry = defaultWatcherValues.get(m); | ||||
|                 Entry<WatcherMethod, Object> entry = defaultWatcherValues.get(m); | ||||
|  | ||||
|                 if (entry == null) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 Object invokeWith = m.getDeclaringClass().isInstance(disguise) ? disguise : disguise.getWatcher(); | ||||
|                 Object invokeWith = m.getWatcherClass().isInstance(disguise) ? disguise : disguise.getWatcher(); | ||||
|  | ||||
|                 Object ourValue = entry.getKey().invoke(invokeWith); | ||||
|                 Object ourValue = entry.getKey().getMethod().bindTo(invokeWith).invoke(); | ||||
|  | ||||
|                 // Escape a hacky fix for custom names, disguised players with custom names don't want to show it | ||||
|                 // so it was set to an empty string. | ||||
| @@ -200,7 +220,7 @@ public class DisguiseParser { | ||||
|                     } | ||||
|                 } else { | ||||
|                     // If its the same as default, continue | ||||
|                     if (!m.isAnnotationPresent(RandomDefaultValue.class) && Objects.deepEquals(entry.getValue(), ourValue)) { | ||||
|                     if (!m.isRandomDefault() && Objects.deepEquals(entry.getValue(), ourValue)) { | ||||
|                         continue; | ||||
|                     } | ||||
|                 } | ||||
| @@ -225,28 +245,28 @@ public class DisguiseParser { | ||||
|             } | ||||
|  | ||||
|             return stringBuilder.toString(); | ||||
|         } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { | ||||
|         } catch (Throwable e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     private static void addWatcherDefault(Method setMethod, Method getMethod, Object object) { | ||||
|     private static void addWatcherDefault(WatcherMethod setMethod, WatcherMethod getMethod, Object object) { | ||||
|         if (defaultWatcherValues.containsKey(setMethod)) { | ||||
|             Object dObj = defaultWatcherValues.get(setMethod).getValue(); | ||||
|  | ||||
|             if (!Objects.deepEquals(dObj, object)) { | ||||
|                 throw new IllegalStateException(String.format( | ||||
|                         "%s has conflicting values in class %s! This means it expected the same value again but " + "received a " + | ||||
|                                 "different value on a different disguise! %s is not the same as %s!", setMethod.getName(), | ||||
|                         setMethod.getDeclaringClass().getName(), object, dObj)); | ||||
|                                 "different value on a different disguise! %s is not the same as %s!", setMethod.toString(), setMethod.toString(), object, | ||||
|                         dObj)); | ||||
|             } | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         Map.Entry<Method, Object> entry = new HashMap.SimpleEntry<>(getMethod, object); | ||||
|         Map.Entry<WatcherMethod, Object> entry = new HashMap.SimpleEntry<>(getMethod, object); | ||||
|  | ||||
|         defaultWatcherValues.put(setMethod, entry); | ||||
|     } | ||||
| @@ -569,8 +589,7 @@ public class DisguiseParser { | ||||
|      * @throws IllegalAccessException | ||||
|      * @throws InvocationTargetException | ||||
|      */ | ||||
|     public static Disguise parseTestDisguise(CommandSender sender, String permNode, String[] args, DisguisePermissions permissions) | ||||
|             throws DisguiseParseException, IllegalAccessException, InvocationTargetException { | ||||
|     public static Disguise parseTestDisguise(CommandSender sender, String permNode, String[] args, DisguisePermissions permissions) throws Throwable { | ||||
|  | ||||
|         // Clone array so original array isn't modified | ||||
|         args = Arrays.copyOf(args, args.length); | ||||
| @@ -583,8 +602,7 @@ public class DisguiseParser { | ||||
|         return parseDisguise(sender, null, permNode, args, permissions); | ||||
|     } | ||||
|  | ||||
|     public static void modifyDisguise(Disguise disguise, Entity target, String[] params) | ||||
|             throws IllegalAccessException, DisguiseParseException, InvocationTargetException { | ||||
|     public static void modifyDisguise(Disguise disguise, Entity target, String[] params) throws Throwable { | ||||
|         if (target != null) { | ||||
|             params = DisguiseParser.parsePlaceholders(params, target, target); | ||||
|         } | ||||
| @@ -593,25 +611,23 @@ public class DisguiseParser { | ||||
|                 new DisguisePerm(disguise.getType()), new ArrayList<>(), params, "Disguise"); | ||||
|     } | ||||
|  | ||||
|     public static void modifyDisguise(Disguise disguise, String[] params) throws IllegalAccessException, InvocationTargetException, DisguiseParseException { | ||||
|     public static void modifyDisguise(Disguise disguise, String[] params) throws Throwable { | ||||
|         modifyDisguise(disguise, null, params); | ||||
|     } | ||||
|  | ||||
|     public static void modifyDisguise(Disguise disguise, String params) throws IllegalAccessException, DisguiseParseException, InvocationTargetException { | ||||
|     public static void modifyDisguise(Disguise disguise, String params) throws Throwable { | ||||
|         modifyDisguise(disguise, DisguiseUtilities.split(params)); | ||||
|     } | ||||
|  | ||||
|     public static void modifyDisguise(Disguise disguise, Entity target, String params) | ||||
|             throws IllegalAccessException, InvocationTargetException, DisguiseParseException { | ||||
|     public static void modifyDisguise(Disguise disguise, Entity target, String params) throws Throwable { | ||||
|         modifyDisguise(disguise, target, DisguiseUtilities.split(params)); | ||||
|     } | ||||
|  | ||||
|     public static Disguise parseDisguise(String disguise) throws IllegalAccessException, InvocationTargetException, DisguiseParseException { | ||||
|     public static Disguise parseDisguise(String disguise) throws Throwable { | ||||
|         return parseDisguise(Bukkit.getConsoleSender(), null, disguise); | ||||
|     } | ||||
|  | ||||
|     public static Disguise parseDisguise(CommandSender sender, Entity target, String disguise) | ||||
|             throws IllegalAccessException, InvocationTargetException, DisguiseParseException { | ||||
|     public static Disguise parseDisguise(CommandSender sender, Entity target, String disguise) throws Throwable { | ||||
|         return parseDisguise(sender, target, "disguise", DisguiseUtilities.split(disguise), new DisguisePermissions(Bukkit.getConsoleSender(), "disguise")); | ||||
|     } | ||||
|  | ||||
| @@ -622,7 +638,7 @@ public class DisguiseParser { | ||||
|      * disguise has been feed a proper disguisetype. | ||||
|      */ | ||||
|     public static Disguise parseDisguise(CommandSender sender, Entity target, String permNode, String[] args, DisguisePermissions permissions) | ||||
|             throws DisguiseParseException, IllegalAccessException, InvocationTargetException { | ||||
|             throws Throwable { | ||||
|         if (!Bukkit.isPrimaryThread()) { | ||||
|             throw new IllegalStateException("DisguiseParser should not be called async!"); | ||||
|         } | ||||
| @@ -883,9 +899,8 @@ public class DisguiseParser { | ||||
|     } | ||||
|  | ||||
|     public static void callMethods(CommandSender sender, Disguise disguise, DisguisePermissions disguisePermission, DisguisePerm disguisePerm, | ||||
|                                    Collection<String> usedOptions, String[] args, String permNode) | ||||
|             throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, DisguiseParseException { | ||||
|         Method[] methods = ParamInfoManager.getDisguiseWatcherMethods(disguise.getWatcher().getClass()); | ||||
|                                    Collection<String> usedOptions, String[] args, String permNode) throws Throwable { | ||||
|         WatcherMethod[] methods = ParamInfoManager.getDisguiseWatcherMethods(disguise.getWatcher().getClass()); | ||||
|         List<String> list = new ArrayList<>(Arrays.asList(args)); | ||||
|         HashMap<String, HashMap<String, Boolean>> disguiseOptions = getDisguiseOptions(sender, permNode, disguisePerm); | ||||
|  | ||||
| @@ -895,11 +910,11 @@ public class DisguiseParser { | ||||
|             // Translate the name they provided, to a name we recognize | ||||
|             String methodNameJava = TranslateType.DISGUISE_OPTIONS.reverseGet(methodNameProvided); | ||||
|             // The method we'll use | ||||
|             Method methodToUse = null; | ||||
|             WatcherMethod methodToUse = null; | ||||
|             Object valueToSet = null; | ||||
|             DisguiseParseException parseException = null; | ||||
|  | ||||
|             for (Method method : methods) { | ||||
|             for (WatcherMethod method : methods) { | ||||
|                 if (!method.getName().equalsIgnoreCase(methodNameJava)) { | ||||
|                     continue; | ||||
|                 } | ||||
| @@ -963,11 +978,15 @@ public class DisguiseParser { | ||||
|                 valueToSet = DisguiseUtilities.quoteNewLine((String) valueToSet); | ||||
|             } | ||||
|  | ||||
|             if (FlagWatcher.class.isAssignableFrom(methodToUse.getDeclaringClass())) { | ||||
|                 methodToUse.invoke(disguise.getWatcher(), valueToSet); | ||||
|             MethodHandle handle = methodToUse.getMethod(); | ||||
|  | ||||
|             if (FlagWatcher.class.isAssignableFrom(methodToUse.getWatcherClass())) { | ||||
|                 handle = handle.bindTo(disguise.getWatcher()); | ||||
|             } else { | ||||
|                 methodToUse.invoke(disguise, valueToSet); | ||||
|                 handle = handle.bindTo(disguise); | ||||
|             } | ||||
|  | ||||
|             handle.invoke(valueToSet); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,21 @@ | ||||
| package me.libraryaddict.disguise.utilities.parser; | ||||
|  | ||||
| import lombok.Getter; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import me.libraryaddict.disguise.disguisetypes.FlagWatcher; | ||||
|  | ||||
| import java.lang.invoke.MethodHandle; | ||||
|  | ||||
| /** | ||||
|  * Created by libraryaddict on 21/05/2021. | ||||
|  */ | ||||
| @RequiredArgsConstructor | ||||
| @Getter | ||||
| public class WatcherMethod { | ||||
|     private final Class<? extends FlagWatcher> watcherClass; | ||||
|     private final MethodHandle method; | ||||
|     private final String name; | ||||
|     private final Class returnType; | ||||
|     private final Class param; | ||||
|     private final boolean randomDefault; | ||||
| } | ||||
| @@ -26,7 +26,6 @@ import org.bukkit.entity.*; | ||||
| import org.bukkit.inventory.EquipmentSlot; | ||||
| import org.bukkit.inventory.ItemStack; | ||||
| import org.bukkit.inventory.meta.ItemMeta; | ||||
| import org.bukkit.material.MaterialData; | ||||
| import org.bukkit.plugin.SimplePluginManager; | ||||
| import org.bukkit.potion.PotionEffect; | ||||
| import org.bukkit.scheduler.BukkitRunnable; | ||||
|   | ||||
| @@ -1,34 +1,24 @@ | ||||
| package me.libraryaddict.disguise.utilities.reflection.asm; | ||||
| package me.libraryaddict.disguise.utilities.reflection; | ||||
| 
 | ||||
| import lombok.Getter; | ||||
| import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; | ||||
| import lombok.Setter; | ||||
| 
 | ||||
| /** | ||||
|  * Created by libraryaddict on 17/02/2020. | ||||
|  */ | ||||
| @Getter | ||||
| @Setter | ||||
| public class WatcherInfo { | ||||
|     private int added = -1; | ||||
|     private int removed = -1; | ||||
|     private boolean deprecated; | ||||
|     private String returnType; | ||||
|     private boolean randomDefault; | ||||
|     private String watcher; | ||||
|     private String method; | ||||
|     private String param; | ||||
|     String descriptor; | ||||
| 
 | ||||
|     public WatcherInfo(String string) { | ||||
|         String[] split = string.split(":", -1); | ||||
| 
 | ||||
|         if (split.length > 3) { | ||||
|             descriptor = split[3]; | ||||
|             added = Integer.parseInt(split[4]); | ||||
|             removed = Integer.parseInt(split[5]); | ||||
|         } | ||||
| 
 | ||||
|         watcher = split[0]; | ||||
|         method = split[1]; | ||||
|         param = split[2]; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isSupported() { | ||||
|         if (getAdded() >= 0 && added > ReflectionManager.getVersion().ordinal()) { | ||||
|             return false; | ||||
| @@ -1,34 +0,0 @@ | ||||
| package me.libraryaddict.disguise.utilities.reflection.asm; | ||||
|  | ||||
| import org.objectweb.asm.*; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| 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 { | ||||
|         className = className.replace(".", "/") + ".class"; | ||||
|  | ||||
|         ClassReader cr = new ClassReader(getClass().getClassLoader().getResourceAsStream(className)); | ||||
|         ClassWriter writer = new ClassWriter(cr, 0); | ||||
|  | ||||
|         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); | ||||
|  | ||||
|                 if (entry != null) { | ||||
|                     return null; | ||||
|                 } | ||||
|  | ||||
|                 return super.visitMethod(access, name, desc, signature, exceptions); | ||||
|             } | ||||
|         }, 0); | ||||
|  | ||||
|         return writer.toByteArray(); | ||||
|     } | ||||
| } | ||||
| @@ -1,83 +0,0 @@ | ||||
| package me.libraryaddict.disguise.utilities.reflection.asm; | ||||
|  | ||||
| import lombok.Getter; | ||||
| import me.libraryaddict.disguise.LibsDisguises; | ||||
|  | ||||
| import java.io.BufferedInputStream; | ||||
| import java.io.File; | ||||
| import java.io.FileOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.net.MalformedURLException; | ||||
| import java.net.URL; | ||||
| import java.net.URLClassLoader; | ||||
|  | ||||
| /** | ||||
|  * Created by libraryaddict on 20/02/2020. | ||||
|  */ | ||||
| @Getter | ||||
| public class AsmLoader { | ||||
|     //   private String urlToGrab = "https://repository.ow2.org/nexus/content/repositories/releases/org/ow2/asm/asm/7 | ||||
|     //   .3" + | ||||
|     //          ".1/asm-7.3.1.jar"; | ||||
|     /** | ||||
|      * Using maven | ||||
|      */ | ||||
|     private final String urlToGrab = "https://search.maven.org/remotecontent?filepath=org/ow2/asm/asm/9.1/asm-9.1.jar"; | ||||
|     private final File filePath = new File(LibsDisguises.getInstance().getDataFolder(), "libs/org-ow2-asm-9.1.jar"); | ||||
|     private boolean asmExists; | ||||
|     private URLClassLoader classLoader; | ||||
|  | ||||
|     public AsmLoader() { | ||||
|         try { | ||||
|             Class.forName("org.objectweb.asm.ClassReader"); | ||||
|             asmExists = true; | ||||
|         } catch (NoClassDefFoundError | ClassNotFoundException ex) { | ||||
|             // It doesn't exist, good! Lets load it! | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void loadClassloader() { | ||||
|         try { | ||||
|             classLoader = URLClassLoader.newInstance(new URL[]{filePath.toURI().toURL(), LibsDisguises.getInstance().getFile().toURI().toURL()}); | ||||
|         } catch (MalformedURLException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void unload() { | ||||
|         try { | ||||
|             classLoader.close(); | ||||
|         } catch (IOException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void doDownloadIfRequired() { | ||||
|         if (!hasASM()) { | ||||
|             LibsDisguises.getInstance().getLogger().info("Downloading required library for asm!"); | ||||
|  | ||||
|             downloadASM(); | ||||
|  | ||||
|             LibsDisguises.getInstance().getLogger().info("Downloaded!"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private boolean hasASM() { | ||||
|         return filePath.exists(); | ||||
|     } | ||||
|  | ||||
|     private void downloadASM() { | ||||
|         filePath.getParentFile().mkdirs(); | ||||
|  | ||||
|         try (BufferedInputStream in = new BufferedInputStream(new URL(getUrlToGrab()).openStream()); | ||||
|              FileOutputStream fileOutputStream = new FileOutputStream(getFilePath())) { | ||||
|             byte[] dataBuffer = new byte[1024]; | ||||
|             int bytesRead; | ||||
|             while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) { | ||||
|                 fileOutputStream.write(dataBuffer, 0, bytesRead); | ||||
|             } | ||||
|         } catch (IOException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,120 +0,0 @@ | ||||
| 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(); | ||||
|     } | ||||
| } | ||||
| @@ -1,16 +0,0 @@ | ||||
| package me.libraryaddict.disguise.utilities.reflection.asm; | ||||
|  | ||||
| import me.libraryaddict.disguise.utilities.reflection.ClassGetter; | ||||
| import org.bukkit.plugin.java.JavaPlugin; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
|  | ||||
| /** | ||||
|  * Created by libraryaddict on 20/05/2021. | ||||
|  */ | ||||
| public class LibsDisguisesCompat extends JavaPlugin { | ||||
|     @Override | ||||
|     public void onLoad() { | ||||
|         ClassGetter.getClassesForPackage("me.libraryaddict.disguise.disguisetypes"); | ||||
|     } | ||||
| } | ||||
| @@ -1,185 +0,0 @@ | ||||
| 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; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.util.*; | ||||
|  | ||||
| /** | ||||
|  * Created by libraryaddict on 17/02/2020. | ||||
|  */ | ||||
| public class WatcherSanitizer { | ||||
|     public static void checkPreLoaded() throws NoSuchFieldException, IllegalAccessException { | ||||
|         JavaPluginLoader javaLoader = (JavaPluginLoader) LibsDisguises.getInstance().getPluginLoader(); | ||||
|  | ||||
|         Field lM = JavaPluginLoader.class.getDeclaredField("loaders"); | ||||
|         lM.setAccessible(true); | ||||
|         List loaders = (List) lM.get(javaLoader); | ||||
|  | ||||
|         Field lF = WatcherSanitizer.class.getClassLoader().getClass().getDeclaredField("classes"); | ||||
|         lF.setAccessible(true); | ||||
|         Field dF = WatcherSanitizer.class.getClassLoader().getClass().getDeclaredField("description"); | ||||
|         dF.setAccessible(true); | ||||
|  | ||||
|         for (Object loader : loaders) { | ||||
|             Map<String, Class<?>> lClasses = (Map<String, Class<?>>) lF.get(loader); | ||||
|             PluginDescriptionFile desc = (PluginDescriptionFile) dF.get(loader); | ||||
|  | ||||
|             if (hasWatcher(lClasses)) { | ||||
|                 LibsDisguises.getInstance().getLogger() | ||||
|                         .severe(desc.getFullName() + " has been a naughty plugin, they're declaring access to the disguise watchers before Lib's " + | ||||
|                                 "Disguises can properly load them! They should add 'LibsDisguises' to the 'depend' section of" + " their plugin.yml!"); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         Field cM = JavaPluginLoader.class.getDeclaredField("classes"); | ||||
|         cM.setAccessible(true); | ||||
|         Map<String, Class<?>> classes = (Map<String, Class<?>>) cM.get(javaLoader); | ||||
|  | ||||
|         if (hasWatcher(classes)) { | ||||
|             LibsDisguises.getInstance().getLogger() | ||||
|                     .severe("Somehow the main server has a Watcher instance! Hopefully there was a plugin mentioned " + "above! This is a bug!"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static boolean hasWatcher(Map<String, Class<?>> classes) { | ||||
|         for (Class c : classes.values()) { | ||||
|             if (!c.getName().startsWith("me.libraryaddict.disguise.disguisetypes.watchers.") && | ||||
|                     !c.getName().equals("me.libraryaddict.disguise.disguisetypes.FlagWatcher")) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     public static void init() { | ||||
|         try { | ||||
|             checkPreLoaded(); | ||||
|         } catch (NoSuchFieldException | IllegalAccessException e) { | ||||
|             LibsDisguises.getInstance().getLogger().info("Failed to check for early class access, this shouldn't be an issue"); | ||||
|         } | ||||
|  | ||||
|         if (Bukkit.getPluginManager().getPlugin("LibsDisguisesVersioning") != null) { | ||||
|             throw new IllegalStateException("Why is LibsDisguisesVersioning already active? Did the server owner do something.. Weird?"); | ||||
|         } | ||||
|  | ||||
|         LibsDisguises.getInstance().getLogger() | ||||
|                 .info("Due to issues with Java 16, you may notice harmless errors saying plugin loaded another plugin that isnt a soft depend or so on"); | ||||
|  | ||||
|         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(); | ||||
|  | ||||
|             Object obj; | ||||
|             Method getBytes; | ||||
|  | ||||
|             if (!loader.isAsmExists()) { | ||||
|                 loader.doDownloadIfRequired(); | ||||
|                 loader.loadClassloader(); | ||||
|  | ||||
|                 obj = Class.forName("me.libraryaddict.disguise.utilities.reflection.asm.Asm13", true, loader.getClassLoader()).newInstance(); | ||||
|             } else { | ||||
|                 obj = new Asm13(); | ||||
|             } | ||||
|  | ||||
|             getBytes = obj.getClass().getMethod("createClassWithoutMethods", String.class, ArrayList.class); | ||||
|  | ||||
|             String[] lines = new String(ReflectionManager.readFuzzyFully(stream), StandardCharsets.UTF_8).split("\n"); | ||||
|  | ||||
|             LinkedHashMap<String, ArrayList<Map.Entry<String, String>>> toRemove = new LinkedHashMap<>(); | ||||
|  | ||||
|             for (String s : lines) { | ||||
|                 WatcherInfo info = new WatcherInfo(s); | ||||
|  | ||||
|                 if (info.isSupported()) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 String path = "me.libraryaddict.disguise.disguisetypes." + (info.getWatcher().equals("FlagWatcher") ? "" : "watchers.") + info.getWatcher(); | ||||
|  | ||||
|                 toRemove.putIfAbsent(path, new ArrayList<>()); | ||||
|  | ||||
|                 ArrayList<Map.Entry<String, String>> list = toRemove.get(path); | ||||
|  | ||||
|                 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()); | ||||
|  | ||||
|                 classes.put(entry.getKey().replace(".", "/") + ".class", bytes); | ||||
|             } | ||||
|  | ||||
|             fakePluginCreator.createJar(ourVers, classes); | ||||
|             loadPlugin(fakePluginCreator); | ||||
|  | ||||
|             if (!loader.isAsmExists()) { | ||||
|                 loader.unload(); | ||||
|             } | ||||
|         } catch (Throwable e) { | ||||
|             e.printStackTrace(); | ||||
|             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; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -3,11 +3,11 @@ package me.libraryaddict.disguise.utilities.translations; | ||||
| import me.libraryaddict.disguise.disguisetypes.DisguiseType; | ||||
| import me.libraryaddict.disguise.utilities.params.ParamInfo; | ||||
| import me.libraryaddict.disguise.utilities.params.ParamInfoManager; | ||||
| import me.libraryaddict.disguise.utilities.parser.WatcherMethod; | ||||
| import org.apache.commons.lang.StringUtils; | ||||
| import org.bukkit.entity.Entity; | ||||
| import org.bukkit.entity.EntityType; | ||||
|  | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Locale; | ||||
|  | ||||
| @@ -58,9 +58,9 @@ public class TranslateFiller { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             for (Method method : ParamInfoManager.getDisguiseWatcherMethods(type.getWatcherClass())) { | ||||
|                 Class para = method.getParameterTypes()[0]; | ||||
|                 String className = method.getDeclaringClass().getSimpleName().replace("Watcher", ""); | ||||
|             for (WatcherMethod method : ParamInfoManager.getDisguiseWatcherMethods(type.getWatcherClass())) { | ||||
|                 Class para = method.getParam(); | ||||
|                 String className = method.getWatcherClass().getSimpleName().replace("Watcher", ""); | ||||
|  | ||||
|                 if (className.equals("Flag") || className.equals("Disguise")) | ||||
|                     className = "Entity"; | ||||
|   | ||||
| @@ -1,11 +1,13 @@ | ||||
| package me.libraryaddict.disguise.utilities.watchers; | ||||
|  | ||||
| import com.google.gson.Gson; | ||||
| import me.libraryaddict.disguise.disguisetypes.FlagWatcher; | ||||
| import me.libraryaddict.disguise.utilities.LibsPremium; | ||||
| import me.libraryaddict.disguise.utilities.parser.RandomDefaultValue; | ||||
| 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.reflection.WatcherInfo; | ||||
| import me.libraryaddict.disguise.utilities.sounds.DisguiseSoundEnums; | ||||
| import me.libraryaddict.disguise.utilities.sounds.SoundGroup; | ||||
| import org.apache.commons.lang.StringUtils; | ||||
| @@ -35,14 +37,6 @@ 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() { | ||||
| @@ -140,14 +134,20 @@ public class CompileMethods { | ||||
|                     removed = method.getDeclaringClass().getAnnotation(NmsRemovedIn.class).value().ordinal(); | ||||
|                 } | ||||
|  | ||||
|                 String param = method.getParameterCount() == 1 ? method.getParameterTypes()[0].getName() : ""; | ||||
|                 String descriptor = ""; | ||||
|                 String param = method.getParameterCount() == 1 ? method.getParameterTypes()[0].getName() : null; | ||||
|  | ||||
|                 if (added >= 0 || removed >= 0) { | ||||
|                     descriptor = ":" + getMethodDescriptor(method) + ":" + added + ":" + removed; | ||||
|                 } | ||||
|                 WatcherInfo info = new WatcherInfo(); | ||||
|                 info.setMethod(method.getName()); | ||||
|                 info.setAdded(added); | ||||
|                 info.setRemoved(removed); | ||||
|                 info.setDeprecated(method.isAnnotationPresent(Deprecated.class)); | ||||
|                 info.setParam(param); | ||||
|                 info.setDescriptor(getMethodDescriptor(method)); | ||||
|                 info.setWatcher(method.getDeclaringClass().getSimpleName()); | ||||
|                 info.setReturnType(method.getReturnType().getName()); | ||||
|                 info.setRandomDefault(method.isAnnotationPresent(RandomDefaultValue.class)); | ||||
|  | ||||
|                 String s = method.getDeclaringClass().getSimpleName() + ":" + method.getName() + ":" + param + descriptor; | ||||
|                 String s = new Gson().toJson(info); | ||||
|  | ||||
|                 if (methods.contains(s)) { | ||||
|                     continue; | ||||
|   | ||||
| @@ -1,16 +1,24 @@ | ||||
| package me.libraryaddict.disguise.utilities.watchers; | ||||
|  | ||||
| import com.google.gson.Gson; | ||||
| import lombok.Getter; | ||||
| import me.libraryaddict.disguise.DisguiseConfig; | ||||
| import me.libraryaddict.disguise.LibsDisguises; | ||||
| import me.libraryaddict.disguise.disguisetypes.Disguise; | ||||
| import me.libraryaddict.disguise.disguisetypes.DisguiseType; | ||||
| import me.libraryaddict.disguise.disguisetypes.FlagWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; | ||||
| import me.libraryaddict.disguise.utilities.params.ParamInfoManager; | ||||
| import me.libraryaddict.disguise.utilities.reflection.NmsRemovedIn; | ||||
| import me.libraryaddict.disguise.utilities.parser.WatcherMethod; | ||||
| import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; | ||||
| import me.libraryaddict.disguise.utilities.reflection.asm.WatcherInfo; | ||||
| import me.libraryaddict.disguise.utilities.reflection.WatcherInfo; | ||||
| import org.bukkit.boss.BarColor; | ||||
| import org.bukkit.boss.BarStyle; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.lang.reflect.Method; | ||||
| import java.lang.invoke.MethodHandle; | ||||
| import java.lang.invoke.MethodHandles; | ||||
| import java.lang.invoke.MethodType; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| @@ -20,10 +28,13 @@ import java.util.List; | ||||
|  * Created by libraryaddict on 13/02/2020. | ||||
|  */ | ||||
| public class DisguiseMethods { | ||||
|     private HashMap<Class<? extends FlagWatcher>, List<Method>> watcherMethods = new HashMap<>(); | ||||
|     private HashMap<Class<? extends FlagWatcher>, List<WatcherMethod>> watcherMethods = new HashMap<>(); | ||||
|     private HashMap<Class<? extends Disguise>, List<WatcherMethod>> disguiseMethods = new HashMap<>(); | ||||
|     @Getter | ||||
|     private ArrayList<WatcherMethod> methods = new ArrayList<>(); | ||||
|  | ||||
|     public ArrayList<Method> getMethods(Class c) { | ||||
|         ArrayList<Method> methods = new ArrayList<>(); | ||||
|     public ArrayList<WatcherMethod> getMethods(Class c) { | ||||
|         ArrayList<WatcherMethod> methods = new ArrayList<>(); | ||||
|  | ||||
|         if (watcherMethods.containsKey(c)) { | ||||
|             methods.addAll(watcherMethods.get(c)); | ||||
| @@ -36,14 +47,6 @@ public class DisguiseMethods { | ||||
|         return methods; | ||||
|     } | ||||
|  | ||||
|     public ArrayList<Method> getMethods() { | ||||
|         ArrayList<Method> methods = new ArrayList<>(); | ||||
|  | ||||
|         this.watcherMethods.values().forEach(methods::addAll); | ||||
|  | ||||
|         return methods; | ||||
|     } | ||||
|  | ||||
|     public DisguiseMethods() { | ||||
|         loadMethods(); | ||||
|     } | ||||
| @@ -74,9 +77,13 @@ public class DisguiseMethods { | ||||
|             } | ||||
|  | ||||
|             for (String line : lines) { | ||||
|                 WatcherInfo info = new WatcherInfo(line); | ||||
|                 WatcherInfo info = new Gson().fromJson(line, WatcherInfo.class); | ||||
|  | ||||
|                 if (!info.isSupported() || info.getParam().isEmpty()) { | ||||
|                 if (!info.isSupported()) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 if (info.isDeprecated() && info.getRemoved() < 0) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
| @@ -86,33 +93,79 @@ public class DisguiseMethods { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 Class param = parseType(info.getParam()); | ||||
|                 Class returnType = parseType(info.getReturnType()); | ||||
|  | ||||
|                 String paramName = info.getParam(); | ||||
|                 Class param; | ||||
|  | ||||
|                 if (!paramName.contains(".")) { | ||||
|                     param = parseType(paramName); | ||||
|                 } else { | ||||
|                     param = Class.forName(paramName); | ||||
|                 } | ||||
|                 MethodType type = param == null || param == Void.TYPE ? MethodType.methodType(returnType) : MethodType.methodType(returnType, param); | ||||
|  | ||||
|                 Method method = watcher.getMethod(info.getMethod(), param); | ||||
|                 MethodHandle method = MethodHandles.publicLookup().findVirtual(watcher, info.getMethod(), type); | ||||
|  | ||||
|                 if (method.getParameterCount() != 1) { | ||||
|                     continue; | ||||
|                 } else if (method.getName().startsWith("get")) { | ||||
|                     continue; | ||||
|                 } else if (method.isAnnotationPresent(Deprecated.class) && | ||||
|                         !method.isAnnotationPresent(NmsRemovedIn.class)) { | ||||
|                     continue; | ||||
|                 } else if (!method.getReturnType().equals(Void.TYPE)) { | ||||
|                     continue; | ||||
|                 } else if (ParamInfoManager.getParamInfo(method) == null) { | ||||
|                 WatcherMethod m = new WatcherMethod(watcher, method, info.getMethod(), returnType, param, info.isRandomDefault()); | ||||
|  | ||||
|                 methods.add(m); | ||||
|  | ||||
|                 if (m.getName().startsWith("get") || m.getName().startsWith("has") || param == null || param == Void.TYPE || ParamInfoManager.getParamInfo(m) == null) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 watcherMethods.computeIfAbsent(watcher, (a) -> new ArrayList<>()).add(method); | ||||
|                 watcherMethods.computeIfAbsent(watcher, (a) -> new ArrayList<>()).add(m); | ||||
|             } | ||||
|         } catch (IOException | ClassNotFoundException | NoClassDefFoundError | NoSuchMethodException e) { | ||||
|  | ||||
|             PlayerDisguise disguise = new PlayerDisguise(""); | ||||
|  | ||||
|             // Add these last as it's what we want to present to be called the least | ||||
|             for (String methodName : new String[]{"setSelfDisguiseVisible", "setHideHeldItemFromSelf", "setHideArmorFromSelf", "setHearSelfDisguise", | ||||
|                     "setHidePlayer", "setExpires", "setNotifyBar", "setBossBarColor", "setBossBarStyle", "setTallDisguisesVisible", "setDynamicName", | ||||
|                     "setSoundGroup", "setDisguiseName", "setDeadmau5Ears"}) { | ||||
|                 try { | ||||
|                     Class cl = boolean.class; | ||||
|                     Class disguiseClass = Disguise.class; | ||||
|  | ||||
|                     switch (methodName) { | ||||
|                         case "setExpires": | ||||
|                             cl = long.class; | ||||
|                             break; | ||||
|                         case "setNotifyBar": | ||||
|                             cl = DisguiseConfig.NotifyBar.class; | ||||
|                             break; | ||||
|                         case "setBossBarColor": | ||||
|                             cl = BarColor.class; | ||||
|                             break; | ||||
|                         case "setBossBarStyle": | ||||
|                             cl = BarStyle.class; | ||||
|                             break; | ||||
|                         case "setSoundGroup": | ||||
|                         case "setDisguiseName": | ||||
|                             cl = String.class; | ||||
|                             break; | ||||
|                         case "setDeadmau5Ears": | ||||
|                             disguiseClass = PlayerDisguise.class; | ||||
|                             break; | ||||
|                         default: | ||||
|                             break; | ||||
|                     } | ||||
|  | ||||
|                     for (Class returnType : new Class[]{Void.TYPE, disguiseClass}) { | ||||
|                         try { | ||||
|                             WatcherMethod method = new WatcherMethod(disguiseClass, | ||||
|                                     MethodHandles.publicLookup().findVirtual(disguiseClass, methodName, MethodType.methodType(returnType, cl)), methodName, | ||||
|                                     null, cl, false); | ||||
|  | ||||
|                             methods.add(method); | ||||
|                             break; | ||||
|                         } catch (NoSuchMethodException ex) { | ||||
|                             if (returnType == disguiseClass) { | ||||
|                                 ex.printStackTrace(); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } catch (Exception ex) { | ||||
|                     ex.printStackTrace(); | ||||
|                 } | ||||
|             } | ||||
|         } catch (Throwable e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
| @@ -129,8 +182,18 @@ public class DisguiseMethods { | ||||
|      * @param className The class name, never `null` | ||||
|      * @throws IllegalArgumentException if no class can be loaded | ||||
|      */ | ||||
|     private Class<?> parseType(final String className) { | ||||
|     private Class<?> parseType(final String className) throws ClassNotFoundException { | ||||
|         if (className == null) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         if (className.contains(".")) { | ||||
|             return Class.forName(className); | ||||
|         } | ||||
|  | ||||
|         switch (className) { | ||||
|             case "void": | ||||
|                 return Void.TYPE; | ||||
|             case "boolean": | ||||
|                 return boolean.class; | ||||
|             case "byte": | ||||
| @@ -149,6 +212,8 @@ public class DisguiseMethods { | ||||
|                 return char.class; | ||||
|             case "[I": | ||||
|                 return int[].class; | ||||
|             case "[Z": | ||||
|                 return boolean[].class; | ||||
|             default: | ||||
|                 throw new IllegalArgumentException("Class not found: " + className); | ||||
|         } | ||||
|   | ||||
| @@ -2,13 +2,13 @@ package me.libraryaddict.disguise.disguisetypes; | ||||
|  | ||||
| import me.libraryaddict.disguise.utilities.DisguiseUtilities; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguiseParser; | ||||
| import me.libraryaddict.disguise.utilities.parser.WatcherMethod; | ||||
| import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; | ||||
| import org.bukkit.Material; | ||||
| import org.bukkit.inventory.ItemStack; | ||||
| import org.junit.Assert; | ||||
|  | ||||
| import java.lang.reflect.InvocationTargetException; | ||||
| import java.lang.reflect.Method; | ||||
| import java.lang.invoke.MethodHandle; | ||||
| import java.util.Map; | ||||
|  | ||||
| /** | ||||
| @@ -37,8 +37,7 @@ public class DisguiseCloneTest { | ||||
|                     disguise = new MiscDisguise(type); | ||||
|                 } | ||||
|  | ||||
|                 for (Map.Entry<Method, Map.Entry<Method, Object>> entry : DisguiseParser.getMethodDefaults() | ||||
|                         .entrySet()) { | ||||
|                 for (Map.Entry<WatcherMethod, Map.Entry<WatcherMethod, Object>> entry : DisguiseParser.getMethodDefaults().entrySet()) { | ||||
|                     Object dValue = entry.getValue().getValue(); | ||||
|  | ||||
|                     if (dValue instanceof String) { | ||||
| @@ -74,21 +73,19 @@ public class DisguiseCloneTest { | ||||
|                         continue; | ||||
|                     } | ||||
|  | ||||
|                     Method m = entry.getKey(); | ||||
|                     WatcherMethod m = entry.getKey(); | ||||
|  | ||||
|                     Object invokeWith = disguise; | ||||
|  | ||||
|                     if (FlagWatcher.class.isAssignableFrom(entry.getKey().getDeclaringClass())) { | ||||
|                     if (FlagWatcher.class.isAssignableFrom(entry.getKey().getWatcherClass())) { | ||||
|                         invokeWith = disguise.getWatcher(); | ||||
|                     } | ||||
|  | ||||
|                     try { | ||||
|                         entry.getKey().invoke(invokeWith, dValue); | ||||
|                     } | ||||
|                     catch (IllegalAccessException e) { | ||||
|                         e.printStackTrace(); | ||||
|                     } | ||||
|                     catch (InvocationTargetException e) { | ||||
|                         MethodHandle handle = entry.getKey().getMethod(); | ||||
|                         handle.bindTo(invokeWith); | ||||
|                         handle.invoke(dValue); | ||||
|                     } catch (Throwable e) { | ||||
|                         e.printStackTrace(); | ||||
|                     } | ||||
|                 } | ||||
| @@ -103,8 +100,7 @@ public class DisguiseCloneTest { | ||||
|                     Assert.fail("Cloned disguise is not the same!"); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) { | ||||
|         } catch (Exception ex) { | ||||
|             ex.printStackTrace(); | ||||
|  | ||||
|             if (ex.getCause() != null) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user