Fixed typos, added DisguiseParser.parsetoString(Disguise)

This commit is contained in:
libraryaddict
2019-12-31 19:35:21 +13:00
parent ce1472eaf7
commit 7aa3a8a2ef
54 changed files with 555 additions and 114 deletions

View File

@@ -1,6 +1,7 @@
package me.libraryaddict.disguise.utilities.parser;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.google.gson.Gson;
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.disguisetypes.*;
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
@@ -17,6 +18,7 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.potion.PotionEffectType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -25,6 +27,185 @@ import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
public class DisguiseParser {
private static HashMap<Method, Map.Entry<Method, Object>> defaultWatcherValues = new HashMap<>();
public static void createDefaultMethods() {
try {
for (DisguiseType type : DisguiseType.values()) {
Disguise disguise;
if (type.isMisc()) {
disguise = new MiscDisguise(type);
} else if (type.isMob()) {
disguise = new MobDisguise(type);
} else {
disguise = new PlayerDisguise("Foobar");
}
FlagWatcher watcher = type.getWatcherClass().getConstructor(Disguise.class).newInstance(disguise);
Method[] methods = ParamInfoManager.getDisguiseWatcherMethods(watcher.getClass());
for (Method setMethod : methods) {
// Invalidate methods that can't be handled normally
if (setMethod.getName().equals("addPotionEffect") || (setMethod.getName().equals("setSkin") &&
setMethod.getParameterTypes()[0] == String.class) ||
(setMethod.getName().equals("setTarget") &&
setMethod.getParameterTypes()[0] != int.class) ||
(setMethod.getName().equals("setItemInMainHand") &&
setMethod.getParameterTypes()[0] == Material.class)) {
continue;
}
String getName = setMethod.getName().substring(3); // Remove 'set'
if (getName.equals("HasNectar")) {
getName = "hasNectar";
} else if (getName.equals("HasStung")) {
getName = "hasStung";
} else if (setMethod.getParameterTypes()[0].isAssignableFrom(boolean.class)) {
getName = "is" + getName;
} else {
getName = "get" + getName;
}
Method getMethod = null;
for (Method m : setMethod.getDeclaringClass().getDeclaredMethods()) {
if (!m.getName().equals(getName)) {
continue;
}
if (m.getParameterTypes().length > 0 || m.getReturnType() != setMethod.getParameterTypes()[0]) {
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()));
continue;
}
Object defaultValue = null;
// Value is randomish so shouldn't be checked, should always specify value when setting
if (!setMethod.isAnnotationPresent(RandomDefaultValue.class)) {
Object invokeWith = watcher;
if (!FlagWatcher.class.isAssignableFrom(getMethod.getDeclaringClass())) {
invokeWith = disguise;
}
defaultValue = getMethod.invoke(invokeWith);
}
addWatcherDefault(setMethod, getMethod, defaultValue);
}
}
}
catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
}
public static String parseToString(Disguise disguise) {
try {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(disguise.getType().name());
if (disguise.isPlayerDisguise()) {
stringBuilder.append(" ").append(((PlayerDisguise) disguise).getName());
}
for (Method m : ParamInfoManager.getDisguiseWatcherMethods(disguise.getType().getWatcherClass())) {
// Special handling for this method
if (m.getName().equals("addPotionEffect")) {
PotionEffectType[] types = (PotionEffectType[]) m.getDeclaringClass().getMethod("getPotionEffects")
.invoke(disguise.getWatcher());
for (PotionEffectType type : types) {
if (type == null) {
continue;
}
stringBuilder.append(" ").append(m.getName()).append(" ").append(type.getName());
}
} else {
Entry<Method, Object> entry = defaultWatcherValues.get(m);
if (entry == null) {
continue;
}
Object invokeWith = m.getDeclaringClass().isInstance(disguise) ? disguise : disguise.getWatcher();
Object ourValue = entry.getKey().invoke(invokeWith);
// 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.
if ("".equals(ourValue) && m.getName().equals("setCustomName")) {
ourValue = null;
}
// If its the same as default, continue
if (!m.isAnnotationPresent(RandomDefaultValue.class) &&
Objects.deepEquals(entry.getValue(), ourValue)) {
continue;
}
stringBuilder.append(" ").append(m.getName());
if (ourValue instanceof Boolean && (Boolean) ourValue) {
continue;
}
String valueString;
if (ourValue != null) {
valueString = ParamInfoManager.getParamInfo(ourValue.getClass()).toString(ourValue);
if (valueString.contains(" ") || valueString.contains("\"")) {
valueString = "\"" + valueString.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
}
} else {
valueString = "null";
}
stringBuilder.append(" ").append(valueString);
}
}
return stringBuilder.toString();
}
catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
private static void addWatcherDefault(Method setMethod, Method getMethod, Object object) {
Map.Entry<Method, Object> entry = new HashMap.SimpleEntry<>(getMethod, object);
if (defaultWatcherValues.containsKey(setMethod)) {
Object dObj = defaultWatcherValues.get(setMethod);
if (!Objects.deepEquals(defaultWatcherValues.get(setMethod).getValue(), object)) {
throw new IllegalStateException(String.format("%s has conflicting values!", setMethod.getName()));
}
return;
}
defaultWatcherValues.put(setMethod, entry);
}
private static void doCheck(CommandSender sender, DisguisePermissions permissions, DisguisePerm disguisePerm,
Collection<String> usedOptions) throws DisguiseParseException {