Read for information...
Now using ASM manipulation to remove invalid methods on load Fixed imports Fixed Chat Components being used in 1.12 Fixed tab complete showing args for disguise options you can't use Disguise option permissions now demand a parameter to be the method name Falling block disguises are now only usable with blocks LibsDisguises command now tab completes the new options Libs Disguises command lets you create a vanilla compatible item string If a vehicle is disguised as a vehicle, don't give no gravity Fixed horse disguise using almost random values for its flagwatcher settings Renamed horse disguise setMouthOpen to setEating Slightly better string for premium info jar location Skip attributes packets if using older ProtocolLib jar Don't cancel entity death if entity is dead Improved disguise permissions checking Fixed time parameter not being attributed properly
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
package me.libraryaddict.disguise.utilities.watchers;
|
||||
|
||||
import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseSound;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseSoundEnums;
|
||||
import me.libraryaddict.disguise.utilities.LibsPremium;
|
||||
import me.libraryaddict.disguise.utilities.reflection.ClassGetter;
|
||||
import me.libraryaddict.disguise.utilities.reflection.NmsAddedIn;
|
||||
import me.libraryaddict.disguise.utilities.reflection.NmsRemovedIn;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Sound;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Created by libraryaddict on 13/02/2020.
|
||||
*/
|
||||
public class CompileMethods {
|
||||
public static void main(String[] args) {
|
||||
doMethods();
|
||||
doSounds();
|
||||
}
|
||||
|
||||
private static void doSounds() {
|
||||
List<String> list = new ArrayList<>();
|
||||
|
||||
for (DisguiseSoundEnums s : DisguiseSoundEnums.values()) {
|
||||
StringBuilder sound = new StringBuilder(s.name());
|
||||
|
||||
for (DisguiseSound.SoundType type : DisguiseSound.SoundType.values()) {
|
||||
sound.append(":");
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (Map.Entry<Sound, DisguiseSound.SoundType> values : s.getDisguiseSounds().entrySet()) {
|
||||
if (values.getValue() != type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i++ > 0) {
|
||||
sound.append(",");
|
||||
}
|
||||
|
||||
sound.append(values.getKey().name());
|
||||
}
|
||||
}
|
||||
|
||||
list.add(sound.toString());
|
||||
}
|
||||
|
||||
File soundsFile = new File("target/classes/ANTI_PIRACY_ENCODED_WITH_SOUNDS");
|
||||
|
||||
try (PrintWriter writer = new PrintWriter(soundsFile, "UTF-8")) {
|
||||
writer.write(StringUtils.join(list, "\n"));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void doMethods() {
|
||||
ArrayList<Class<?>> classes = ClassGetter
|
||||
.getClassesForPackage(FlagWatcher.class, "me.libraryaddict.disguise.disguisetypes.watchers");
|
||||
classes.add(FlagWatcher.class);
|
||||
classes.sort((c1, c2) -> c1.isAssignableFrom(c2) ? -1 : 1);
|
||||
|
||||
ArrayList<String> methods = new ArrayList<>();
|
||||
|
||||
for (Class c : classes) {
|
||||
for (Method method : c.getMethods()) {
|
||||
if (!FlagWatcher.class.isAssignableFrom(method.getDeclaringClass())) {
|
||||
continue;
|
||||
} else if (method.getParameterCount() > 1 && !method.isAnnotationPresent(NmsAddedIn.class) &&
|
||||
!method.isAnnotationPresent(NmsRemovedIn.class)) {
|
||||
continue;
|
||||
} else if (!(method.getName().startsWith("set") && method.getParameterCount() == 1) &&
|
||||
!method.getName().startsWith("get") && !method.getName().startsWith("has") &&
|
||||
!method.getName().startsWith("is")) {
|
||||
continue;
|
||||
} else if (method.getName().equals("removePotionEffect")) {
|
||||
continue;
|
||||
} else if (LibsPremium.isPremium() && new Random().nextBoolean()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int added = -1;
|
||||
int removed = -1;
|
||||
|
||||
if (method.isAnnotationPresent(NmsAddedIn.class)) {
|
||||
added = method.getAnnotation(NmsAddedIn.class).val().ordinal();
|
||||
} else if (method.getDeclaringClass().isAnnotationPresent(NmsAddedIn.class)) {
|
||||
added = method.getDeclaringClass().getAnnotation(NmsAddedIn.class).val().ordinal();
|
||||
}
|
||||
|
||||
if (method.isAnnotationPresent(NmsRemovedIn.class)) {
|
||||
removed = method.getAnnotation(NmsRemovedIn.class).val().ordinal();
|
||||
} else if (method.getDeclaringClass().isAnnotationPresent(NmsRemovedIn.class)) {
|
||||
removed = method.getDeclaringClass().getAnnotation(NmsRemovedIn.class).val().ordinal();
|
||||
}
|
||||
|
||||
String param = method.getParameterCount() == 1 ? method.getParameterTypes()[0].getName() : "";
|
||||
String descriptor = "";
|
||||
|
||||
if (added >= 0 || removed >= 0) {
|
||||
descriptor = ":" + getMethodDescriptor(method) + ":" + added + ":" + removed;
|
||||
}
|
||||
|
||||
String s =
|
||||
method.getDeclaringClass().getSimpleName() + ":" + method.getName() + ":" + param + descriptor;
|
||||
|
||||
if (methods.contains(s)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
methods.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
File methodsFile = new File("target/classes/ANTI_PIRACY_ENCRYPTION");
|
||||
|
||||
try (PrintWriter writer = new PrintWriter(methodsFile, "UTF-8")) {
|
||||
writer.write(StringUtils.join(methods, "\n"));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
static String getDescriptorForClass(final Class c) {
|
||||
if (c.isPrimitive()) {
|
||||
if (c == byte.class)
|
||||
return "B";
|
||||
if (c == char.class)
|
||||
return "C";
|
||||
if (c == double.class)
|
||||
return "D";
|
||||
if (c == float.class)
|
||||
return "F";
|
||||
if (c == int.class)
|
||||
return "I";
|
||||
if (c == long.class)
|
||||
return "J";
|
||||
if (c == short.class)
|
||||
return "S";
|
||||
if (c == boolean.class)
|
||||
return "Z";
|
||||
if (c == void.class)
|
||||
return "V";
|
||||
|
||||
throw new RuntimeException("Unrecognized primitive " + c);
|
||||
}
|
||||
|
||||
if (c.isArray())
|
||||
return c.getName().replace('.', '/');
|
||||
|
||||
return ('L' + c.getName() + ';').replace('.', '/');
|
||||
}
|
||||
|
||||
static String getMethodDescriptor(Method m) {
|
||||
StringBuilder s = new StringBuilder("(");
|
||||
|
||||
for (final Class c : (m.getParameterTypes())) {
|
||||
s.append(getDescriptorForClass(c));
|
||||
}
|
||||
|
||||
return s.append(")") + getDescriptorForClass(m.getReturnType());
|
||||
}
|
||||
}
|
@@ -0,0 +1,150 @@
|
||||
package me.libraryaddict.disguise.utilities.watchers;
|
||||
|
||||
import me.libraryaddict.disguise.LibsDisguises;
|
||||
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
|
||||
import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
|
||||
import me.libraryaddict.disguise.utilities.params.ParamInfoManager;
|
||||
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
|
||||
import me.libraryaddict.disguise.utilities.reflection.asm.WatcherInfo;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Created by libraryaddict on 13/02/2020.
|
||||
*/
|
||||
public class DisguiseMethods {
|
||||
private HashMap<Class<? extends FlagWatcher>, List<Method>> watcherMethods = new HashMap<>();
|
||||
|
||||
public ArrayList<Method> getMethods(Class c) {
|
||||
ArrayList<Method> methods = new ArrayList<>();
|
||||
|
||||
if (watcherMethods.containsKey(c)) {
|
||||
methods.addAll(watcherMethods.get(c));
|
||||
}
|
||||
|
||||
if (c != FlagWatcher.class) {
|
||||
methods.addAll(getMethods(c.getSuperclass()));
|
||||
}
|
||||
|
||||
return methods;
|
||||
}
|
||||
|
||||
public ArrayList<Method> getMethods() {
|
||||
ArrayList<Method> methods = new ArrayList<>();
|
||||
|
||||
this.watcherMethods.values().forEach(methods::addAll);
|
||||
|
||||
return methods;
|
||||
}
|
||||
|
||||
public DisguiseMethods() {
|
||||
try (InputStream stream = LibsDisguises.getInstance().getResource("ANTI_PIRACY_ENCRYPTION")) {
|
||||
List<String> lines = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)).lines()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
HashMap<String, Class<? extends FlagWatcher>> classes = new HashMap<>();
|
||||
classes.put(FlagWatcher.class.getSimpleName(), FlagWatcher.class);
|
||||
|
||||
for (DisguiseType t : DisguiseType.values()) {
|
||||
if (t.getWatcherClass() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class c = t.getWatcherClass();
|
||||
|
||||
while (!classes.containsKey(c.getSimpleName())) {
|
||||
classes.put(c.getSimpleName(), c);
|
||||
c = ReflectionManager.getSuperClass(c);
|
||||
}
|
||||
}
|
||||
|
||||
for (String line : lines) {
|
||||
WatcherInfo info = new WatcherInfo(line);
|
||||
|
||||
if (!info.isSupported() || info.getParam().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<? extends FlagWatcher> watcher = classes.get(info.getWatcher());
|
||||
|
||||
if (watcher == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String paramName = info.getParam();
|
||||
Class param;
|
||||
|
||||
if (!paramName.contains(".")) {
|
||||
param = parseType(paramName);
|
||||
} else {
|
||||
param = Class.forName(paramName);
|
||||
}
|
||||
|
||||
Method method = watcher.getMethod(info.getMethod(), param);
|
||||
|
||||
if (method.getParameterCount() != 1) {
|
||||
continue;
|
||||
} else if (method.getName().startsWith("get")) {
|
||||
continue;
|
||||
} else if (method.isAnnotationPresent(Deprecated.class)) {
|
||||
continue;
|
||||
} else if (!method.getReturnType().equals(Void.TYPE)) {
|
||||
continue;
|
||||
} else if (ParamInfoManager.getParamInfo(method) == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
watcherMethods.computeIfAbsent(watcher, (a) -> new ArrayList<>()).add(method);
|
||||
}
|
||||
}
|
||||
catch (IOException | ClassNotFoundException | NoClassDefFoundError | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the java {@link java.lang.Class} object with the specified class name.
|
||||
* <p>
|
||||
* This is an "extended" {@link java.lang.Class#forName(java.lang.String) } operation.
|
||||
* <p>
|
||||
* + It is able to return Class objects for primitive types
|
||||
* + Classes in name space `java.lang` do not need the fully qualified name
|
||||
* + It does not throw a checked Exception
|
||||
*
|
||||
* @param className The class name, never `null`
|
||||
* @throws IllegalArgumentException if no class can be loaded
|
||||
*/
|
||||
private Class<?> parseType(final String className) {
|
||||
switch (className) {
|
||||
case "boolean":
|
||||
return boolean.class;
|
||||
case "byte":
|
||||
return byte.class;
|
||||
case "short":
|
||||
return short.class;
|
||||
case "int":
|
||||
return int.class;
|
||||
case "long":
|
||||
return long.class;
|
||||
case "float":
|
||||
return float.class;
|
||||
case "double":
|
||||
return double.class;
|
||||
case "char":
|
||||
return char.class;
|
||||
case "[I":
|
||||
return int[].class;
|
||||
default:
|
||||
throw new IllegalArgumentException("Class not found: " + className);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user