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:
@@ -1,129 +0,0 @@
|
||||
package me.libraryaddict.disguise.utilities.reflection;
|
||||
|
||||
import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
|
||||
import me.libraryaddict.disguise.disguisetypes.watchers.MushroomCowWatcher;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseSound;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseSoundEnums;
|
||||
import me.libraryaddict.disguise.utilities.LibsPremium;
|
||||
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.add(MushroomCowWatcher.class);
|
||||
|
||||
ArrayList<String> methods = new ArrayList<>();
|
||||
|
||||
for (Class c : classes) {
|
||||
for (Method method : c.getMethods()) {
|
||||
if (method.getParameterTypes().length != 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 (method.getName().equals("removePotionEffect")) {
|
||||
continue;
|
||||
} else if (!FlagWatcher.class.isAssignableFrom(method.getDeclaringClass())) {
|
||||
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();
|
||||
}
|
||||
|
||||
Class<?> param = method.getParameterTypes()[0];
|
||||
|
||||
String s = ((added >= 0 || removed >= 0) ? added + ":" + removed + ":" : "") +
|
||||
method.getDeclaringClass().getSimpleName() + ":" + method.getName() + ":" + param.getName();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,133 +0,0 @@
|
||||
package me.libraryaddict.disguise.utilities.reflection;
|
||||
|
||||
import me.libraryaddict.disguise.LibsDisguises;
|
||||
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
|
||||
import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
|
||||
import org.apache.commons.lang.ClassUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
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 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) {
|
||||
String[] split = line.split(":");
|
||||
|
||||
if (split.length > 3) {
|
||||
int added = Integer.parseInt(split[0]);
|
||||
int removed = Integer.parseInt(split[1]);
|
||||
|
||||
if (added >= 0 && added > ReflectionManager.getVersion().ordinal()) {
|
||||
continue;
|
||||
} else if (removed >= 0 && removed <= ReflectionManager.getVersion().ordinal()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Class<? extends FlagWatcher> watcher = classes.get(split[split.length - 3]);
|
||||
|
||||
if (watcher == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String paramName = split[split.length - 1];
|
||||
Class param;
|
||||
|
||||
if (!paramName.contains(".")) {
|
||||
param = parseType(paramName);
|
||||
} else {
|
||||
param = Class.forName(paramName);
|
||||
}
|
||||
|
||||
Method method = watcher.getMethod(split[split.length - 2], param);
|
||||
|
||||
watcherMethods.computeIfAbsent(watcher, (a) -> new ArrayList<>()).add(method);
|
||||
}
|
||||
}
|
||||
catch (IOException | ClassNotFoundException | 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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,54 +0,0 @@
|
||||
package me.libraryaddict.disguise.utilities.reflection;
|
||||
|
||||
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class DisguiseValues {
|
||||
|
||||
private static HashMap<DisguiseType, DisguiseValues> values = new HashMap<>();
|
||||
|
||||
public static DisguiseValues getDisguiseValues(DisguiseType type) {
|
||||
return values.get(type);
|
||||
}
|
||||
|
||||
public static Class getNmsEntityClass(DisguiseType type) {
|
||||
return getDisguiseValues(type).getNmsEntityClass();
|
||||
}
|
||||
|
||||
private FakeBoundingBox adultBox;
|
||||
private FakeBoundingBox babyBox;
|
||||
private float[] entitySize;
|
||||
private double maxHealth;
|
||||
private Class nmsEntityClass;
|
||||
|
||||
public DisguiseValues(DisguiseType type, Class classType, int entitySize, double maxHealth) {
|
||||
values.put(type, this);
|
||||
nmsEntityClass = classType;
|
||||
this.maxHealth = maxHealth;
|
||||
}
|
||||
|
||||
public FakeBoundingBox getAdultBox() {
|
||||
return adultBox;
|
||||
}
|
||||
|
||||
public FakeBoundingBox getBabyBox() {
|
||||
return babyBox;
|
||||
}
|
||||
|
||||
public double getMaxHealth() {
|
||||
return maxHealth;
|
||||
}
|
||||
|
||||
public Class getNmsEntityClass() {
|
||||
return nmsEntityClass;
|
||||
}
|
||||
|
||||
public void setAdultBox(FakeBoundingBox newBox) {
|
||||
adultBox = newBox;
|
||||
}
|
||||
|
||||
public void setBabyBox(FakeBoundingBox newBox) {
|
||||
babyBox = newBox;
|
||||
}
|
||||
}
|
@@ -10,15 +10,12 @@ import me.libraryaddict.disguise.DisguiseConfig;
|
||||
import me.libraryaddict.disguise.LibsDisguises;
|
||||
import me.libraryaddict.disguise.disguisetypes.*;
|
||||
import me.libraryaddict.disguise.disguisetypes.watchers.*;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseSound;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.LibsPremium;
|
||||
import me.libraryaddict.disguise.utilities.*;
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -1013,7 +1010,7 @@ public class ReflectionManager {
|
||||
Object obj = ((WrappedChatComponent) val).getHandle();
|
||||
|
||||
return NmsVersion.v1_13.isSupported() ? Optional.of(obj) : com.google.common.base.Optional.of(obj);
|
||||
}else if (!NmsVersion.v1_13.isSupported()) {
|
||||
} else if (!NmsVersion.v1_13.isSupported()) {
|
||||
return com.google.common.base.Optional.of(val);
|
||||
}
|
||||
} else if (value instanceof Vector3F) {
|
||||
@@ -1063,6 +1060,71 @@ public class ReflectionManager {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Material getMaterial(String name) {
|
||||
try {
|
||||
if (!NmsVersion.v1_13.isSupported()) {
|
||||
Method toMinecraft = getCraftMethod("util.CraftMagicNumbers", "getMaterialFromInternalName",
|
||||
String.class);
|
||||
|
||||
return (Material) toMinecraft.invoke(null, name);
|
||||
}
|
||||
|
||||
Object mcKey = getNmsConstructor("MinecraftKey", String.class).newInstance(name);
|
||||
|
||||
Object registry = getNmsField("IRegistry", "ITEM").get(null);
|
||||
|
||||
Method getMethod = getNmsMethod(getNmsClass("RegistryMaterials"), "get", mcKey.getClass());
|
||||
Object item = getMethod.invoke(registry, mcKey);
|
||||
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Method getMaterial = getCraftMethod("util.CraftMagicNumbers", "getMaterial", getNmsClass("Item"));
|
||||
|
||||
return (Material) getMaterial.invoke(null, item);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getItemName(Material material) {
|
||||
try {
|
||||
Object item = getCraftMethod("util.CraftMagicNumbers", "getItem", Material.class).invoke(null, material);
|
||||
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Object registry;
|
||||
|
||||
if (NmsVersion.v1_13.isSupported()) {
|
||||
registry = getNmsField("IRegistry", "ITEM").get(null);
|
||||
} else {
|
||||
registry = getNmsField("Item", "REGISTRY").get(null);
|
||||
}
|
||||
|
||||
Method getMethod = getNmsMethod(registry.getClass(), NmsVersion.v1_13.isSupported() ? "getKey" : "b",
|
||||
Object.class);
|
||||
|
||||
Object mcKey = getMethod.invoke(registry, item);
|
||||
|
||||
if (mcKey == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (String) getNmsMethod("MinecraftKey", "getKey").invoke(mcKey);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object getNmsVillagerData(VillagerData data) {
|
||||
Object type = getVillagerType(data.getType());
|
||||
Object profession = getVillagerProfession(data.getProfession());
|
||||
|
@@ -0,0 +1,61 @@
|
||||
package me.libraryaddict.disguise.utilities.reflection.asm;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by libraryaddict on 17/02/2020.
|
||||
*/
|
||||
public class Asm13 implements IAsm {
|
||||
public Class<?> createClassWithoutMethods(String className,
|
||||
ArrayList<Map.Entry<String, String>> illegalMethods) throws IOException, InvocationTargetException,
|
||||
IllegalAccessException, NoSuchMethodException, NoSuchFieldException {
|
||||
ClassReader cr = new ClassReader(
|
||||
getClass().getClassLoader().getResourceAsStream(className.replace(".", "/") + ".class"));
|
||||
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);
|
||||
|
||||
byte[] bytes = writer.toByteArray();
|
||||
|
||||
ClassLoader loader = getClass().getClassLoader();
|
||||
Field field = loader.getClass().getDeclaredField("classes");
|
||||
field.setAccessible(true);
|
||||
Map<String, Class<?>> map = (Map<String, Class<?>>) field.get(loader);
|
||||
Class newClass =
|
||||
|
||||
(Class<?>) getDefineClassMethod()
|
||||
.invoke(getClass().getClassLoader(), className, bytes, 0, bytes.length);
|
||||
|
||||
map.put(className, newClass);
|
||||
return newClass;
|
||||
}
|
||||
|
||||
private static Method getDefineClassMethod() throws NoSuchMethodException {
|
||||
Method defineClass = ClassLoader.class
|
||||
.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);
|
||||
defineClass.setAccessible(true);
|
||||
|
||||
return defineClass;
|
||||
}
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
package me.libraryaddict.disguise.utilities.reflection.asm;
|
||||
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by libraryaddict on 17/02/2020.
|
||||
*/
|
||||
public class Asm14 implements IAsm {
|
||||
public Class<?> createClassWithoutMethods(String className,
|
||||
ArrayList<Map.Entry<String, String>> illegalMethods) throws IOException, InvocationTargetException,
|
||||
IllegalAccessException, NoSuchMethodException, NoSuchFieldException {
|
||||
ClassReader cr = new ClassReader(
|
||||
getClass().getClassLoader().getResourceAsStream(className.replace(".", "/") + ".class"));
|
||||
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);
|
||||
|
||||
byte[] bytes = writer.toByteArray();
|
||||
|
||||
ClassLoader loader = getClass().getClassLoader();
|
||||
Field field = loader.getClass().getDeclaredField("classes");
|
||||
field.setAccessible(true);
|
||||
Map<String, Class<?>> map = (Map<String, Class<?>>) field.get(loader);
|
||||
Class newClass =
|
||||
|
||||
(Class<?>) getDefineClassMethod()
|
||||
.invoke(getClass().getClassLoader(), className, bytes, 0, bytes.length);
|
||||
|
||||
map.put(className, newClass);
|
||||
return newClass;
|
||||
}
|
||||
|
||||
private static Method getDefineClassMethod() throws NoSuchMethodException {
|
||||
Method defineClass = ClassLoader.class
|
||||
.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);
|
||||
defineClass.setAccessible(true);
|
||||
|
||||
return defineClass;
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
package me.libraryaddict.disguise.utilities.reflection.asm;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by libraryaddict on 17/02/2020.
|
||||
*/
|
||||
public interface IAsm {
|
||||
public Class<?> createClassWithoutMethods(String className, ArrayList<Map.Entry<String, String>> illegalMethods) throws IOException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, NoSuchFieldException;
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,41 @@
|
||||
package me.libraryaddict.disguise.utilities.reflection.asm;
|
||||
|
||||
import lombok.Getter;
|
||||
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Created by libraryaddict on 17/02/2020.
|
||||
*/
|
||||
@Getter
|
||||
public class WatcherInfo {
|
||||
private int added = -1;
|
||||
private int removed = -1;
|
||||
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;
|
||||
}
|
||||
|
||||
return getRemoved() < 0 || removed > ReflectionManager.getVersion().ordinal();
|
||||
}
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
package me.libraryaddict.disguise.utilities.reflection.asm;
|
||||
|
||||
import me.libraryaddict.disguise.LibsDisguises;
|
||||
import me.libraryaddict.disguise.utilities.reflection.NmsVersion;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Created by libraryaddict on 17/02/2020.
|
||||
*/
|
||||
public class WatcherSanitizer {
|
||||
|
||||
public static void init() {
|
||||
IAsm asm;
|
||||
|
||||
if (NmsVersion.v1_14.isSupported()) {
|
||||
asm = new Asm14();
|
||||
} else {
|
||||
asm = new Asm13();
|
||||
}
|
||||
|
||||
try (InputStream stream = LibsDisguises.getInstance().getResource("ANTI_PIRACY_ENCRYPTION")) {
|
||||
List<String> lines = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)).lines()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
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()));
|
||||
}
|
||||
|
||||
for (Map.Entry<String, ArrayList<Map.Entry<String, String>>> entry : toRemove.entrySet()) {
|
||||
Class result = asm.createClassWithoutMethods(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
catch (IOException | NoClassDefFoundError | IllegalAccessException | InvocationTargetException | NoSuchMethodException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user