Add setExpires to disguise, disguises expire after a scheduled amount of time
This commit is contained in:
		| @@ -78,6 +78,15 @@ public class DisguiseConfig { | ||||
|     private static int uuidGeneratedVersion; | ||||
|     private static UpdatesBranch updatesBranch = UpdatesBranch.SAME_BUILDS; | ||||
|     private static int playerDisguisesTablistExpires; | ||||
|     private static boolean dynamicExpiry; | ||||
|  | ||||
|     public static boolean isDynamicExpiry() { | ||||
|         return dynamicExpiry; | ||||
|     } | ||||
|  | ||||
|     public static void setDynamicExpiry(boolean setDynamicExpiry) { | ||||
|         dynamicExpiry = setDynamicExpiry; | ||||
|     } | ||||
|  | ||||
|     public static int getPlayerDisguisesTablistExpires() { | ||||
|         return playerDisguisesTablistExpires; | ||||
| @@ -282,6 +291,7 @@ public class DisguiseConfig { | ||||
|         setExplicitDisguisePermissions(config.getBoolean("Permissions.ExplicitDisguises")); | ||||
|         setUUIDGeneratedVersion(config.getInt("UUIDVersion")); | ||||
|         setPlayerDisguisesTablistExpires(config.getInt("PlayerDisguisesTablistExpires")); | ||||
|         setDynamicExpiry(config.getBoolean("DynamicExpiry")); | ||||
|  | ||||
|         if (!LibsPremium.isPremium() && (isSavePlayerDisguises() || isSaveEntityDisguises())) { | ||||
|             DisguiseUtilities.getLogger().warning("You must purchase the plugin to use saved disguises!"); | ||||
|   | ||||
| @@ -20,6 +20,7 @@ import me.libraryaddict.disguise.events.DisguiseEvent; | ||||
| import me.libraryaddict.disguise.events.UndisguiseEvent; | ||||
| import me.libraryaddict.disguise.utilities.DisguiseUtilities; | ||||
| import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; | ||||
| import me.libraryaddict.disguise.utilities.translations.LibsMsg; | ||||
| import org.bukkit.Bukkit; | ||||
| import org.bukkit.Location; | ||||
| import org.bukkit.entity.Entity; | ||||
| @@ -59,6 +60,10 @@ public abstract class Disguise { | ||||
|     private boolean velocitySent = DisguiseConfig.isVelocitySent(); | ||||
|     private boolean viewSelfDisguise = DisguiseConfig.isViewDisguises(); | ||||
|     private FlagWatcher watcher; | ||||
|     /** | ||||
|      * If set, how long before disguise expires | ||||
|      */ | ||||
|     private long disguiseExpires; | ||||
|  | ||||
|     public Disguise(DisguiseType disguiseType) { | ||||
|         this.disguiseType = disguiseType; | ||||
| @@ -107,6 +112,23 @@ public abstract class Disguise { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public boolean isDisguiseExpired() { | ||||
|         return DisguiseConfig.isDynamicExpiry() ? disguiseExpires == 1 : | ||||
|                 disguiseExpires > 0 && disguiseExpires < System.currentTimeMillis(); | ||||
|     } | ||||
|  | ||||
|     public long getExpires() { | ||||
|         return disguiseExpires; | ||||
|     } | ||||
|  | ||||
|     public void setExpires(long timeToExpire) { | ||||
|         disguiseExpires = timeToExpire; | ||||
|  | ||||
|         if (isDisguiseExpired()) { | ||||
|             removeDisguise(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void createRunnable() { | ||||
|         final boolean alwaysSendVelocity; | ||||
|  | ||||
| @@ -149,6 +171,15 @@ public abstract class Disguise { | ||||
|                 // If entity is no longer valid. Remove it. | ||||
|                 if (getEntity() instanceof Player && !((Player) getEntity()).isOnline()) { | ||||
|                     removeDisguise(); | ||||
|                 } else if (disguiseExpires > 0 && (DisguiseConfig.isDynamicExpiry() ? --disguiseExpires == 1 : | ||||
|                         disguiseExpires < System.currentTimeMillis())) { // If disguise expired | ||||
|                     removeDisguise(); | ||||
|  | ||||
|                     String expired = LibsMsg.EXPIRED_DISGUISE.get(); | ||||
|  | ||||
|                     if (getEntity() instanceof Player && expired.length() > 0) { | ||||
|                         getEntity().sendMessage(expired); | ||||
|                     } | ||||
|                 } else if (!getEntity().isValid()) { | ||||
|                     // If it has been dead for 30+ ticks | ||||
|                     // This is to ensure that this disguise isn't removed while clients think its the real entity | ||||
| @@ -728,12 +759,12 @@ public abstract class Disguise { | ||||
|     } | ||||
|  | ||||
|     public boolean startDisguise() { | ||||
|         if (isDisguiseInUse()) { | ||||
|         if (isDisguiseInUse() || isDisguiseExpired()) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if (getEntity() == null) { | ||||
|             throw new RuntimeException("No entity is assigned to this disguise!"); | ||||
|             throw new IllegalStateException("No entity is assigned to this disguise!"); | ||||
|         } | ||||
|  | ||||
|         DisguiseUtilities.setPluginsUsed(); | ||||
| @@ -741,8 +772,7 @@ public abstract class Disguise { | ||||
|         // Fire a disguise event | ||||
|         DisguiseEvent event = new DisguiseEvent(entity, this); | ||||
|  | ||||
|         Bukkit.getPluginManager(). | ||||
|                 callEvent(event); | ||||
|         Bukkit.getPluginManager().callEvent(event); | ||||
|  | ||||
|         // If they cancelled this disguise event. No idea why. | ||||
|         // Just return. | ||||
|   | ||||
| @@ -20,6 +20,7 @@ import java.lang.reflect.InvocationTargetException; | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.*; | ||||
| import java.util.Map.Entry; | ||||
| import java.util.concurrent.TimeUnit; | ||||
|  | ||||
| public class DisguiseParser { | ||||
|     private static void doCheck(CommandSender sender, DisguisePermissions permissions, DisguisePerm disguisePerm, | ||||
| @@ -204,6 +205,43 @@ public class DisguiseParser { | ||||
|         return args; | ||||
|     } | ||||
|  | ||||
|     public static long parseStringToTime(String string) throws DisguiseParseException { | ||||
|         string = string.toLowerCase(); | ||||
|  | ||||
|         if (!string.matches("([0-9]+[a-z]+)+")) { | ||||
|             throw new DisguiseParseException(LibsMsg.PARSE_INVALID_TIME_SEQUENCE, string); | ||||
|         } | ||||
|  | ||||
|         String[] split = string.split("((?<=[a-zA-Z])(?=[0-9]))|((?<=[0-9])(?=[a-zA-Z]))"); | ||||
|  | ||||
|         long time = 0; | ||||
|  | ||||
|         for (int i = 0; i < split.length; i += 2) { | ||||
|             String t = split[i + 1]; | ||||
|             long v = Long.parseLong(split[i]); | ||||
|  | ||||
|             if (t.equals("s") || t.equals("sec") || t.equals("secs") || t.equals("seconds")) { | ||||
|                 time += v; | ||||
|             } else if (t.equals("m") || t.equals("min") || t.equals("minute") || t.equals("minutes")) { | ||||
|                 time += TimeUnit.MINUTES.toSeconds(v); | ||||
|             } else if (t.equals("h") || t.equals("hour") || t.equals("hours")) { | ||||
|                 time += TimeUnit.HOURS.toSeconds(v); | ||||
|             } else if (t.equals("d") || t.equals("day") || t.equals("days")) { | ||||
|                 time += TimeUnit.DAYS.toSeconds(v); | ||||
|             } else if (t.equals("w") || t.equals("week") || t.equals("weeks")) { | ||||
|                 time += TimeUnit.DAYS.toSeconds(v) * 7; | ||||
|             } else if (t.equals("mon") || t.equals("month") || t.equals("months")) { | ||||
|                 time += TimeUnit.DAYS.toSeconds(v) * 31; | ||||
|             } else if (t.equals("y") || t.equals("year") || t.equals("years")) { | ||||
|                 time += TimeUnit.DAYS.toSeconds(v) * 365; | ||||
|             } else { | ||||
|                 throw new DisguiseParseException(LibsMsg.PARSE_INVALID_TIME, t); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return time; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Experimentally parses the arguments to test if this is a valid disguise | ||||
|      * | ||||
|   | ||||
| @@ -4,7 +4,6 @@ import me.libraryaddict.disguise.disguisetypes.Disguise; | ||||
| import me.libraryaddict.disguise.disguisetypes.DisguiseType; | ||||
| import me.libraryaddict.disguise.disguisetypes.FlagWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguisePerm; | ||||
| import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; | ||||
| import me.libraryaddict.disguise.utilities.parser.params.ParamInfoTypes; | ||||
| import org.bukkit.ChatColor; | ||||
| @@ -104,9 +103,10 @@ public class ParamInfoManager { | ||||
|  | ||||
|         // Add these last as it's what we want to present to be called the least | ||||
|         for (String methodName : new String[]{"setViewSelfDisguise", "setHideHeldItemFromSelf", "setHideArmorFromSelf", | ||||
|                 "setHearSelfDisguise", "setHidePlayer"}) { | ||||
|                 "setHearSelfDisguise", "setHidePlayer", "setExpires"}) { | ||||
|             try { | ||||
|                 methods.add(Disguise.class.getMethod(methodName, boolean.class)); | ||||
|                 methods.add(Disguise.class | ||||
|                         .getMethod(methodName, methodName.equals("setExpires") ? long.class : boolean.class)); | ||||
|             } | ||||
|             catch (Exception ex) { | ||||
|                 ex.printStackTrace(); | ||||
| @@ -117,7 +117,7 @@ public class ParamInfoManager { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Value of the method, used namely for displaying the more unique methods to a disguise | ||||
|      * 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; | ||||
|   | ||||
| @@ -82,6 +82,9 @@ public class ParamInfoTypes { | ||||
|         paramInfos.add(new ParamInfoGameProfile(WrappedGameProfile.class, "GameProfile", | ||||
|                 "Get the gameprofile here https://sessionserver.mojang" + | ||||
|                         ".com/session/minecraft/profile/PLAYER_UUID_GOES_HERE?unsigned=false")); | ||||
|         paramInfos.add(new ParamInfoTime(long.class, "Expiry Time", | ||||
|                 "Set how long the disguise lasts, <Num><Time><Num>... where <Time> is (s/sec)(m/min)(h/hour)(d/day) " + | ||||
|                         "etc. 30m20secs = 30 minutes, 20 seconds")); | ||||
|  | ||||
|         // Register base types | ||||
|         Map<String, Object> booleanMap = new HashMap<>(); | ||||
|   | ||||
| @@ -0,0 +1,30 @@ | ||||
| package me.libraryaddict.disguise.utilities.parser.params.types.custom; | ||||
|  | ||||
| import me.libraryaddict.disguise.DisguiseConfig; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguiseParseException; | ||||
| import me.libraryaddict.disguise.utilities.parser.DisguiseParser; | ||||
| import me.libraryaddict.disguise.utilities.parser.params.ParamInfo; | ||||
|  | ||||
| /** | ||||
|  * Created by libraryaddict on 6/03/2019. | ||||
|  */ | ||||
| public class ParamInfoTime extends ParamInfo { | ||||
|     public ParamInfoTime(Class paramClass, String name, String description) { | ||||
|         super(paramClass, name, description); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected Object fromString(String string) throws DisguiseParseException { | ||||
|         long time = DisguiseParser.parseStringToTime(string); | ||||
|  | ||||
|         // If disguise expires X ticks afterwards | ||||
|         if (DisguiseConfig.isDynamicExpiry()) { | ||||
|             time *= 20; | ||||
|         } else if (!DisguiseConfig.isDynamicExpiry()) { // If disguise expires at a set time | ||||
|             time *= 1000; // Multiply for milliseconds | ||||
|             time += System.currentTimeMillis(); // Add current time to expiry time | ||||
|         } | ||||
|  | ||||
|         return time; | ||||
|     } | ||||
| } | ||||
| @@ -9,6 +9,7 @@ import org.bukkit.ChatColor; | ||||
|  */ | ||||
| public enum LibsMsg { | ||||
|     BLOWN_DISGUISE(ChatColor.RED + "Your disguise was blown!"), | ||||
|     EXPIRED_DISGUISE(ChatColor.RED + "Your disguise has expired!"), | ||||
|     CAN_USE_DISGS(ChatColor.DARK_GREEN + "You can use the disguises: %s"), | ||||
|     CANNOT_FIND_PLAYER(ChatColor.RED + "Cannot find the player/uuid '%s'"), | ||||
|     CLICK_TIMER(ChatColor.RED + "Right click a entity in the next %s seconds to grab the disguise reference!"), | ||||
| @@ -155,6 +156,9 @@ public enum LibsMsg { | ||||
|     PARSE_OPTION_NA(ChatColor.RED + "Cannot find the option %s"), | ||||
|     PARSE_SUPPLY_PLAYER(ChatColor.RED + "Error! You need to give a player name!"), | ||||
|     PARSE_TOO_MANY_ARGS(ChatColor.RED + "Error! %s doesn't know what to do with %s!"), | ||||
|     PARSE_INVALID_TIME(ChatColor.RED + "Error! %s is not a valid time! Use s,m,h,d or secs,mins,hours,days"), | ||||
|     PARSE_INVALID_TIME_SEQUENCE( | ||||
|             ChatColor.RED + "Error! %s is not a valid time! Do amount then time, eg. 4min10sec"), | ||||
|     PARSE_USE_SECOND_NUM(ChatColor.RED + "Error! Only the disguises %s and %s uses a second number!"), | ||||
|     REF_TOO_MANY(ChatColor.RED + | ||||
|             "Failed to store the reference, too many cloned disguises. Please raise the maximum cloned disguises, or " + | ||||
| @@ -170,9 +174,9 @@ public enum LibsMsg { | ||||
|             "There is a update ready to be downloaded! You are using " + ChatColor.RED + "v%s" + ChatColor.DARK_RED + | ||||
|             ", the new version is " + ChatColor.RED + "v%s" + ChatColor.DARK_RED + "!"), | ||||
|     UPDATE_READY_SNAPSHOT(ChatColor.RED + "[LibsDisguises] " + ChatColor.DARK_RED + | ||||
|             "There is a new build of Lib's Disguises! You are using " + ChatColor.RED + "#%s" + | ||||
|             ChatColor.DARK_RED + ", the latest build is " + ChatColor.RED + "#%s" + ChatColor.DARK_RED + "!" + | ||||
|             ChatColor.RED + "\nhttps://ci.md-5.net/job/LibsDisguises/lastSuccessfulBuild/"), | ||||
|             "There is a new build of Lib's Disguises! You are using " + ChatColor.RED + "#%s" + ChatColor.DARK_RED + | ||||
|             ", the latest build is " + ChatColor.RED + "#%s" + ChatColor.DARK_RED + "!" + ChatColor.RED + | ||||
|             "\nhttps://ci.md-5.net/job/LibsDisguises/lastSuccessfulBuild/"), | ||||
|     VIEW_SELF_ON(ChatColor.GREEN + "Toggled viewing own disguise on!"), | ||||
|     VIEW_SELF_OFF(ChatColor.GREEN + "Toggled viewing own disguise off!"); | ||||
|  | ||||
| @@ -201,5 +205,4 @@ public enum LibsMsg { | ||||
|  | ||||
|     public String toString() { | ||||
|         throw new RuntimeException("Dont call this"); | ||||
|     } | ||||
| } | ||||
|     }} | ||||
|   | ||||
| @@ -135,8 +135,10 @@ NameAboveHeadAlwaysVisible: true | ||||
| # If you turn this to true, arrows will act like they hit the disguise in the right place! | ||||
| # So someone disguised as a enderdragon will easily get shot down by arrows! | ||||
| # This WILL conflict with NoCheatPlus. Other plugins may also get problems. | ||||
| # This shouldn't really be enabled for players as it also interferes with their movement because the server thinks the player is larger than he really is. | ||||
| # That makes the player unable to approach this building because the server thinks he is trying to glitch inside blocks. | ||||
| # This shouldn't really be enabled for players as it also interferes with their movement because the server thinks | ||||
| # the player is larger than they really are. | ||||
| # That makes the player unable to approach this building because the server thinks they are trying to glitch inside | ||||
| # blocks. | ||||
| # This feature is highly experimental and is guaranteed to cause problems for players who are disguised | ||||
| ModifyBoundingBox: false | ||||
|  | ||||
| @@ -146,9 +148,12 @@ ModifyBoundingBox: false | ||||
| MonstersIgnoreDisguises: false | ||||
|  | ||||
| # This works only for players, disguised monsters and the like will not be undisguised | ||||
| # Should the player's disguises be removed if he attacks something? | ||||
| # Should the player's disguises be removed if they attacks something? | ||||
| # Blown Disguise message can be changed in translations | ||||
| # Message can be hidden with an empty translation | ||||
| BlowDisguisesWhenAttacking: false | ||||
| # Should the player's disguises be removed if he's attacked by something? | ||||
|  | ||||
| # Should the player's disguises be removed if they're attacked by something? | ||||
| BlowDisguisesWhenAttacked: false | ||||
|  | ||||
| #Stop shulker disguises from moving, they're weird. This option only effects PLAYERS that are disguised, other entities disguised as shulkers will NOT be effected! | ||||
| @@ -164,7 +169,7 @@ DisguiseCloneSize: 3 | ||||
|  | ||||
| # This controls if a entity's max health is determined by the entity, or by the disguise. | ||||
| # Wither is 200, a player is 20. With this enabled, a player disguised as a wither will have the boss bar health accurate to the players health. | ||||
| # Else it will be 1/20 of the boss bar when he is full health. | ||||
| # Else it will be 1/20 of the boss bar when they are full health. | ||||
| # Setting this in LivingWatcher overrides both values. | ||||
| MaxHealthDeterminedByEntity: true | ||||
|  | ||||
| @@ -196,6 +201,12 @@ PlayerDisguisesTablistExpires: 40 | ||||
| # Don't like players able to set themselves invisible when using the disguise commands? Toggle this to true and no one can use setInvisible! Plugins can still use this however. | ||||
| DisableInvisibility: false | ||||
|  | ||||
| # Disguises have a 'setExpires' option which removes the disguise after a set amount of time | ||||
| # By default, this is set to false which means it expires 9 minutes afterwards, even if they logged off. | ||||
| # If true, it means they will experience the full 9 minutes, even if they log on for just a minute per day | ||||
| # Expired message can be hidden with an empty translation message | ||||
| DynamicExpiry: false | ||||
|  | ||||
| # This will help performance, especially with CPU | ||||
| # Due to safety reasons, self disguises can never have their packets disabled. | ||||
| PacketsEnabled: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user