Change the use of the disguiseclone command to use references instead

This commit is contained in:
libraryaddict 2014-06-02 10:03:59 +12:00
parent 4b55a24444
commit 31a0b68bdc
7 changed files with 177 additions and 113 deletions

View File

@ -62,6 +62,8 @@ DisguiseEntityExpire: 10
# Another option to choose the same thing for DisguiseClone command # Another option to choose the same thing for DisguiseClone command
DisguiseCloneExpire: 10 DisguiseCloneExpire: 10
# Max disguises to store at a time with the DisguiseClone command
DisguiseCloneSize: 3
# This I don't really recommend turning on as it can make a memory leak.. # This I don't really recommend turning on as it can make a memory leak..
# These disguises, as normal will not persist after a server restart. # These disguises, as normal will not persist after a server restart.

View File

@ -19,6 +19,7 @@ public class DisguiseConfig {
private static boolean keepDisguiseEntityDespawn; private static boolean keepDisguiseEntityDespawn;
private static boolean keepDisguisePlayerDeath; private static boolean keepDisguisePlayerDeath;
private static boolean keepDisguisePlayerLogout; private static boolean keepDisguisePlayerLogout;
private static int maxClonedDisguises;
private static boolean maxHealthIsDisguisedEntity; private static boolean maxHealthIsDisguisedEntity;
private static boolean miscDisguisesForLivingEnabled; private static boolean miscDisguisesForLivingEnabled;
private static boolean modifyBoundingBox; private static boolean modifyBoundingBox;
@ -44,6 +45,10 @@ public class DisguiseConfig {
return disguiseEntityExpire; return disguiseEntityExpire;
} }
public static int getMaxClonedDisguises() {
return maxClonedDisguises;
}
public static boolean isAnimationPacketsEnabled() { public static boolean isAnimationPacketsEnabled() {
return animationEnabled; return animationEnabled;
} }
@ -263,6 +268,10 @@ public class DisguiseConfig {
keepDisguisePlayerLogout = keepDisguise; keepDisguisePlayerLogout = keepDisguise;
} }
public static void setMaxClonedDisguises(int newMax) {
maxClonedDisguises = newMax;
}
public static void setMaxHealthDeterminedByDisguisedEntity(boolean isDetermined) { public static void setMaxHealthDeterminedByDisguisedEntity(boolean isDetermined) {
maxHealthIsDisguisedEntity = isDetermined; maxHealthIsDisguisedEntity = isDetermined;
} }

View File

@ -1,6 +1,7 @@
package me.libraryaddict.disguise; package me.libraryaddict.disguise;
import java.util.HashMap; import java.util.HashMap;
import java.util.Random;
import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
@ -127,7 +128,7 @@ public class DisguiseListener implements Listener {
disguiseRunnable.remove(p.getName()).cancel(); disguiseRunnable.remove(p.getName()).cancel();
Entity entity = event.getRightClicked(); Entity entity = event.getRightClicked();
String entityName = ""; String entityName = "";
if (entity instanceof Player) { if (entity instanceof Player && !disguiseClone.containsKey(p.getName())) {
entityName = ((Player) entity).getName(); entityName = ((Player) entity).getName();
} else { } else {
String[] split = entity.getType().name().split("_"); String[] split = entity.getType().name().split("_");
@ -138,62 +139,73 @@ public class DisguiseListener implements Listener {
} }
} }
} }
Disguise disguise = null;
Entity disguiseTarget = null;
if (disguiseClone.containsKey(p.getName())) { if (disguiseClone.containsKey(p.getName())) {
Boolean[] options = disguiseClone.remove(p.getName()); Boolean[] options = disguiseClone.remove(p.getName());
disguiseTarget = p; Disguise disguise = DisguiseAPI.getDisguise(p, entity);
disguise = DisguiseAPI.getDisguise(p, entity);
if (disguise == null) { if (disguise == null) {
disguise = DisguiseAPI.constructDisguise(entity, options[0], options[1], options[2]); disguise = DisguiseAPI.constructDisguise(entity, options[0], options[1], options[2]);
} else { } else {
disguise = disguise.clone(); disguise = disguise.clone();
} }
} else if (disguiseEntity.containsKey(p.getName())) { char[] alphabet = "abcdefghijklmnopqrstuvwxyz".toCharArray();
disguiseTarget = entity; String reference = null;
disguise = disguiseEntity.remove(p.getName()); int referenceLength = Math.max(2, (int) Math.ceil((0.1D + DisguiseConfig.getMaxClonedDisguises()) / 26D));
} int attempts = 0;
if (disguise != null) { while (reference == null && attempts++ < 1000) {
if (disguise.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled() reference = "@";
&& disguiseTarget instanceof LivingEntity) { for (int i = 0; i < referenceLength; i++) {
p.sendMessage(ChatColor.RED reference += alphabet[new Random().nextInt(alphabet.length)];
+ "Can't disguise a living entity as a misc disguise. This has been disabled in the config!"); }
if (DisguiseUtilities.getClonedDisguise(reference) != null) {
reference = null;
}
}
if (reference != null && DisguiseUtilities.addClonedDisguise(reference, disguise)) {
p.sendMessage(ChatColor.RED + "Constructed a " + entityName + " disguise! Your reference is " + reference);
p.sendMessage(ChatColor.RED + "Example usage: /disguise " + reference);
} else { } else {
if (disguiseTarget instanceof Player && DisguiseConfig.isNameOfPlayerShownAboveDisguise()) { p.sendMessage(ChatColor.RED
if (disguise.getWatcher() instanceof LivingWatcher) { + "Failed to store the reference due to lack of size. Please set this in the config");
((LivingWatcher) disguise.getWatcher()).setCustomName(((Player) disguiseTarget).getDisplayName()); }
if (DisguiseConfig.isNameAboveHeadAlwaysVisible()) { } else if (disguiseEntity.containsKey(p.getName())) {
((LivingWatcher) disguise.getWatcher()).setCustomNameVisible(true); Disguise disguise = disguiseEntity.remove(p.getName());
if (disguise != null) {
if (disguise.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled()
&& entity instanceof LivingEntity) {
p.sendMessage(ChatColor.RED
+ "Can't disguise a living entity as a misc disguise. This has been disabled in the config!");
} else {
if (entity instanceof Player && DisguiseConfig.isNameOfPlayerShownAboveDisguise()) {
if (disguise.getWatcher() instanceof LivingWatcher) {
((LivingWatcher) disguise.getWatcher()).setCustomName(((Player) entity).getDisplayName());
if (DisguiseConfig.isNameAboveHeadAlwaysVisible()) {
((LivingWatcher) disguise.getWatcher()).setCustomNameVisible(true);
}
} }
} }
} DisguiseAPI.disguiseToAll(entity, disguise);
DisguiseAPI.disguiseToAll(disguiseTarget, disguise); String disguiseName = "a ";
String disguiseName = "a "; if (disguise instanceof PlayerDisguise) {
if (disguise instanceof PlayerDisguise) { disguiseName = "the player " + ((PlayerDisguise) disguise).getName();
disguiseName = "the player " + ((PlayerDisguise) disguise).getName(); } else {
} else { String[] split = disguise.getType().name().split("_");
String[] split = disguise.getType().name().split("_"); for (int i = 0; i < split.length; i++) {
for (int i = 0; i < split.length; i++) { disguiseName += split[0].substring(0, 1) + split[0].substring(1).toLowerCase();
disguiseName += split[0].substring(0, 1) + split[0].substring(1).toLowerCase(); if (i + 1 < split.length) {
if (i + 1 < split.length) { disguiseName += " ";
disguiseName += " "; }
} }
} }
}
if (disguiseTarget == p) {
p.sendMessage(ChatColor.RED + "Disguised yourself" + " as " + (entity instanceof Player ? "" : "a ")
+ entityName + "!");
} else {
p.sendMessage(ChatColor.RED + "Disguised " + (entity instanceof Player ? "" : "the ") + entityName p.sendMessage(ChatColor.RED + "Disguised " + (entity instanceof Player ? "" : "the ") + entityName
+ " as " + disguiseName + "!"); + " as " + disguiseName + "!");
} }
} else {
if (DisguiseAPI.isDisguised(entity)) {
DisguiseAPI.undisguiseToAll(entity);
p.sendMessage(ChatColor.RED + "Undisguised " + (entity instanceof Player ? "" : "the ") + entityName);
} else
p.sendMessage(ChatColor.RED + (entity instanceof Player ? "" : "the") + entityName + " isn't disguised!");
} }
} else {
if (DisguiseAPI.isDisguised(entity)) {
DisguiseAPI.undisguiseToAll(entity);
p.sendMessage(ChatColor.RED + "Undisguised " + (entity instanceof Player ? "" : "the ") + entityName);
} else
p.sendMessage(ChatColor.RED + (entity instanceof Player ? "" : "the") + entityName + " isn't disguised!");
} }
} }
} }

View File

@ -119,6 +119,7 @@ public class LibsDisguises extends JavaPlugin {
DisguiseConfig.setMaxHealthDeterminedByDisguisedEntity(getConfig().getBoolean("MaxHealthDeterminedByEntity")); DisguiseConfig.setMaxHealthDeterminedByDisguisedEntity(getConfig().getBoolean("MaxHealthDeterminedByEntity"));
DisguiseConfig.setDisguiseEntityExpire(getConfig().getInt("DisguiseEntityExpire")); DisguiseConfig.setDisguiseEntityExpire(getConfig().getInt("DisguiseEntityExpire"));
DisguiseConfig.setDisguiseCloneExpire(getConfig().getInt("DisguiseCloneExpire")); DisguiseConfig.setDisguiseCloneExpire(getConfig().getInt("DisguiseCloneExpire"));
DisguiseConfig.setMaxClonedDisguises(getConfig().getInt("DisguiseCloneSize"));
try { try {
// Here I use reflection to set the plugin for Disguise.. // Here I use reflection to set the plugin for Disguise..
// Kind of stupid but I don't want open API calls for a commonly used object. // Kind of stupid but I don't want open API calls for a commonly used object.

View File

@ -45,7 +45,7 @@ public class DisguiseCloneCommand extends BaseDisguiseCommand {
} }
listener.setDisguiseClone(sender.getName(), new Boolean[] { doEnquipment, doSneak, doSprint }); listener.setDisguiseClone(sender.getName(), new Boolean[] { doEnquipment, doSneak, doSprint });
sender.sendMessage(ChatColor.RED + "Right click a entity in the next " + DisguiseConfig.getDisguiseCloneExpire() sender.sendMessage(ChatColor.RED + "Right click a entity in the next " + DisguiseConfig.getDisguiseCloneExpire()
+ " seconds to disguise as it!"); + " seconds to grab the disguise reference!");
} else { } else {
sender.sendMessage(ChatColor.RED + "You are forbidden to use this command."); sender.sendMessage(ChatColor.RED + "You are forbidden to use this command.");
} }
@ -56,7 +56,9 @@ public class DisguiseCloneCommand extends BaseDisguiseCommand {
* Send the player the information * Send the player the information
*/ */
protected void sendCommandUsage(CommandSender sender) { protected void sendCommandUsage(CommandSender sender) {
sender.sendMessage(ChatColor.DARK_GREEN + "Disguise as the entity you right click! Or as their disguise!"); sender.sendMessage(ChatColor.DARK_GREEN
+ "Right click a entity to get a disguise reference you can pass to other disguise commands!");
sender.sendMessage(ChatColor.DARK_GREEN + "Beware however, the reference bypasses all permissions checks");
sender.sendMessage(ChatColor.DARK_GREEN + "/disguiseclone IgnoreEnquipment" + ChatColor.DARK_GREEN + "(" sender.sendMessage(ChatColor.DARK_GREEN + "/disguiseclone IgnoreEnquipment" + ChatColor.DARK_GREEN + "("
+ ChatColor.GREEN + "Optional" + ChatColor.DARK_GREEN + ")"); + ChatColor.GREEN + "Optional" + ChatColor.DARK_GREEN + ")");
} }

View File

@ -166,89 +166,101 @@ public abstract class BaseDisguiseCommand implements CommandExecutor {
sendCommandUsage(sender); sendCommandUsage(sender);
throw new Exception(); throw new Exception();
} }
DisguiseType disguiseType = null;
if (args[0].equalsIgnoreCase("p")) {
disguiseType = DisguiseType.PLAYER;
} else {
for (DisguiseType type : DisguiseType.values()) {
if (type.getEntityType() == null) {
continue;
}
if (args[0].equalsIgnoreCase(type.name()) || args[0].equalsIgnoreCase(type.name().replace("_", ""))) {
disguiseType = type;
break;
}
}
}
if (disguiseType == null) {
throw new Exception(ChatColor.RED + "Error! The disguise " + ChatColor.GREEN + args[0] + ChatColor.RED
+ " doesn't exist!");
}
if (!allowedDisguises.contains(disguiseType.name().toLowerCase())) {
throw new Exception(ChatColor.RED + "You are forbidden to use this disguise.");
}
ArrayList<String> usedOptions = new ArrayList<String>();
Disguise disguise = null;
// How many args to skip due to the disugise being constructed // How many args to skip due to the disugise being constructed
int toSkip = 1;
// Time to start constructing the disguise. // Time to start constructing the disguise.
// We will need to check between all 3 kinds of disguises // We will need to check between all 3 kinds of disguises
int toSkip = 1;
HashSet<HashSet<String>> optionPermissions = this.getPermissions(sender, disguiseType.name().toLowerCase()); ArrayList<String> usedOptions = new ArrayList<String>();
if (disguiseType.isPlayer()) {// If he is doing a player disguise Disguise disguise = null;
if (args.length == 1) { HashSet<HashSet<String>> optionPermissions;
// He needs to give the player name if (args[0].startsWith("@")) {
throw new Exception(ChatColor.RED + "Error! You need to give a player name!"); if (sender.hasPermission("libsdisguises.disguise.disguiseclone")) {
disguise = DisguiseUtilities.getClonedDisguise(args[0].toLowerCase());
if (disguise == null) {
throw new Exception(ChatColor.RED + "Cannot find a disguise under the reference " + args[0]);
}
} else { } else {
// Construct the player disguise throw new Exception(ChatColor.RED + "You do not have perimssion to use disguise references!");
disguise = new PlayerDisguise(ChatColor.translateAlternateColorCodes('&', args[1]));
toSkip++;
} }
optionPermissions = this.getPermissions(sender, disguise.getType().name().toLowerCase());
} else { } else {
if (disguiseType.isMob()) { // Its a mob, use the mob constructor DisguiseType disguiseType = null;
boolean adult = true; if (args[0].equalsIgnoreCase("p")) {
if (args.length > 1) { disguiseType = DisguiseType.PLAYER;
if (args[1].equalsIgnoreCase("baby") || args[1].equalsIgnoreCase("adult")) { } else {
usedOptions.add("setbaby"); for (DisguiseType type : DisguiseType.values()) {
doCheck(optionPermissions, usedOptions); if (type.getEntityType() == null) {
adult = args[1].equalsIgnoreCase("adult"); continue;
toSkip++; }
if (args[0].equalsIgnoreCase(type.name()) || args[0].equalsIgnoreCase(type.name().replace("_", ""))) {
disguiseType = type;
break;
} }
} }
disguise = new MobDisguise(disguiseType, adult); }
} else if (disguiseType.isMisc()) { if (disguiseType == null) {
// Its a misc, we are going to use the MiscDisguise constructor. throw new Exception(ChatColor.RED + "Error! The disguise " + ChatColor.GREEN + args[0] + ChatColor.RED
int miscId = -1; + " doesn't exist!");
int miscData = -1; }
if (args.length > 1) { if (!allowedDisguises.contains(disguiseType.name().toLowerCase())) {
// They have defined more arguements! throw new Exception(ChatColor.RED + "You are forbidden to use this disguise.");
// If the first arg is a number }
if (isNumeric(args[1])) { optionPermissions = this.getPermissions(sender, disguiseType.name().toLowerCase());
miscId = Integer.parseInt(args[1]); if (disguiseType.isPlayer()) {// If he is doing a player disguise
toSkip++; if (args.length == 1) {
// If they also defined a data value // He needs to give the player name
if (args.length > 2) { throw new Exception(ChatColor.RED + "Error! You need to give a player name!");
if (isNumeric(args[2])) { } else {
miscData = Integer.parseInt(args[2]); // Construct the player disguise
toSkip++; disguise = new PlayerDisguise(ChatColor.translateAlternateColorCodes('&', args[1]));
toSkip++;
}
} else {
if (disguiseType.isMob()) { // Its a mob, use the mob constructor
boolean adult = true;
if (args.length > 1) {
if (args[1].equalsIgnoreCase("baby") || args[1].equalsIgnoreCase("adult")) {
usedOptions.add("setbaby");
doCheck(optionPermissions, usedOptions);
adult = args[1].equalsIgnoreCase("adult");
toSkip++;
}
}
disguise = new MobDisguise(disguiseType, adult);
} else if (disguiseType.isMisc()) {
// Its a misc, we are going to use the MiscDisguise constructor.
int miscId = -1;
int miscData = -1;
if (args.length > 1) {
// They have defined more arguements!
// If the first arg is a number
if (isNumeric(args[1])) {
miscId = Integer.parseInt(args[1]);
toSkip++;
// If they also defined a data value
if (args.length > 2) {
if (isNumeric(args[2])) {
miscData = Integer.parseInt(args[2]);
toSkip++;
}
} }
} }
} }
} if (miscId != -1) {
if (miscId != -1) { if (disguiseType == DisguiseType.FALLING_BLOCK) {
if (disguiseType == DisguiseType.FALLING_BLOCK) { usedOptions.add("setblock");
usedOptions.add("setblock"); doCheck(optionPermissions, usedOptions);
doCheck(optionPermissions, usedOptions); } else if (disguiseType == DisguiseType.PAINTING) {
} else if (disguiseType == DisguiseType.PAINTING) { usedOptions.add("setpainting");
usedOptions.add("setpainting"); doCheck(optionPermissions, usedOptions);
doCheck(optionPermissions, usedOptions); } else if (disguiseType == DisguiseType.SPLASH_POTION) {
} else if (disguiseType == DisguiseType.SPLASH_POTION) { usedOptions.add("setpotionid");
usedOptions.add("setpotionid"); doCheck(optionPermissions, usedOptions);
doCheck(optionPermissions, usedOptions); }
} }
// Construct the disguise
disguise = new MiscDisguise(disguiseType, miscId, miscData);
} }
// Construct the disguise
disguise = new MiscDisguise(disguiseType, miscId, miscData);
} }
} }
// Copy strings to their new range // Copy strings to their new range

View File

@ -7,10 +7,12 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.DisguiseType;
@ -19,6 +21,7 @@ import me.libraryaddict.disguise.disguisetypes.TargetedDisguise;
import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher; import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher; import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher;
import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType; import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -42,6 +45,7 @@ public class DisguiseUtilities {
* the plugin to do that. * the plugin to do that.
*/ */
private static HashSet<String> addedByPlugins = new HashSet<String>(); private static HashSet<String> addedByPlugins = new HashSet<String>();
private static LinkedHashMap<String, Disguise> clonedDisguises = new LinkedHashMap<String, Disguise>();
/** /**
* A hashmap of the uuid's of entitys, alive and dead. And their disguises in use * A hashmap of the uuid's of entitys, alive and dead. And their disguises in use
**/ **/
@ -63,6 +67,21 @@ public class DisguiseUtilities {
**/ **/
private static HashMap<UUID, Integer> selfDisguisesIds = new HashMap<UUID, Integer>(); private static HashMap<UUID, Integer> selfDisguisesIds = new HashMap<UUID, Integer>();
public static boolean addClonedDisguise(String key, Disguise disguise) {
if (DisguiseConfig.getMaxClonedDisguises() > 0) {
if (clonedDisguises.containsKey(key)) {
clonedDisguises.remove(key);
} else if (DisguiseConfig.getMaxClonedDisguises() == clonedDisguises.size()) {
clonedDisguises.remove(clonedDisguises.keySet().iterator().next());
}
if (DisguiseConfig.getMaxClonedDisguises() > clonedDisguises.size()) {
clonedDisguises.put(key, disguise);
return true;
}
}
return false;
}
public static void addDisguise(UUID entityId, TargetedDisguise disguise) { public static void addDisguise(UUID entityId, TargetedDisguise disguise) {
if (!getDisguises().containsKey(entityId)) { if (!getDisguises().containsKey(entityId)) {
getDisguises().put(entityId, new HashSet<TargetedDisguise>()); getDisguises().put(entityId, new HashSet<TargetedDisguise>());
@ -217,6 +236,13 @@ public class DisguiseUtilities {
return addedByPlugins; return addedByPlugins;
} }
public static Disguise getClonedDisguise(String key) {
if (clonedDisguises.containsKey(key)) {
return clonedDisguises.get(key);
}
return null;
}
public static TargetedDisguise getDisguise(Player observer, Entity entity) { public static TargetedDisguise getDisguise(Player observer, Entity entity) {
UUID entityId = entity.getUniqueId(); UUID entityId = entity.getUniqueId();
if (futureDisguises.containsKey(entity.getEntityId())) { if (futureDisguises.containsKey(entity.getEntityId())) {