Cleanup recipes for plugins in MC >= 1.12

This commit is contained in:
Frank van der Heijden 2020-06-07 12:40:14 +02:00
parent e9e7324e36
commit c0d76d77f5
No known key found for this signature in database
GPG key ID: 26DA56488D314D11
7 changed files with 248 additions and 0 deletions

View file

@ -47,6 +47,7 @@ public class PluginManager {
Bukkit.getPluginManager().disablePlugin(plugin); Bukkit.getPluginManager().disablePlugin(plugin);
RSimplePluginManager.getPlugins(Bukkit.getPluginManager()).remove(plugin); RSimplePluginManager.getPlugins(Bukkit.getPluginManager()).remove(plugin);
RSimplePluginManager.removeLookupName(Bukkit.getPluginManager(), plugin.getName()); RSimplePluginManager.removeLookupName(Bukkit.getPluginManager(), plugin.getName());
RCraftingManager.removeRecipesFor(plugin);
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
return Result.ERROR; return Result.ERROR;

View file

@ -0,0 +1,54 @@
package net.frankheijden.serverutils.reflection;
import net.frankheijden.serverutils.utils.MapUtils;
import org.bukkit.plugin.Plugin;
import java.lang.reflect.*;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.*;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.FieldParam.fieldOf;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.VersionParam.min;
public class RCraftingManager {
private static Class<?> craftingManagerClass;
private static Map<String, Field> fields;
static {
try {
craftingManagerClass = Class.forName(String.format("net.minecraft.server.%s.CraftingManager", ReflectionUtils.NMS));
fields = getAllFields(craftingManagerClass,
fieldOf("recipes", min(12)));
} catch (Exception ex) {
ex.printStackTrace();
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
public static void removeRecipesFor(Plugin plugin) throws IllegalAccessException, InvocationTargetException {
// Cleaning up recipes before MC 1.12 is not possible,
// as recipes are not associated to plugins.
if (MINOR < 12) return;
Field recipesField = fields.get("recipes");
if (MINOR == 12) {
Object recipes = get(fields, null, "recipes");
RRegistryMaterials.removeKeysFor(recipes, plugin);
} else {
Object server = invoke(RMinecraftServer.getMethods(), null, "getServer");
Object craftingManager = invoke(RMinecraftServer.getMethods(), server, "getCraftingManager");
Map recipes = (Map) recipesField.get(craftingManager);
if (MINOR == 13) {
MapUtils.removeKeys(recipes, RMinecraftKey.matchingPluginPredicate(new AtomicBoolean(false), plugin));
} else {
Collection<Map> list = (Collection<Map>) recipes.values();
list.forEach(map -> MapUtils.removeKeys(map, RMinecraftKey.matchingPluginPredicate(new AtomicBoolean(false), plugin)));
}
}
}
}

View file

@ -0,0 +1,57 @@
package net.frankheijden.serverutils.reflection;
import org.bukkit.plugin.Plugin;
import java.lang.reflect.Field;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.FieldParam.fieldOf;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.VersionParam.*;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.get;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.getAllFields;
public class RMinecraftKey {
private static Class<?> minecraftKeyClass;
private static Map<String, Field> fields;
static {
try {
minecraftKeyClass = Class.forName(String.format("net.minecraft.server.%s.MinecraftKey", ReflectionUtils.NMS));
fields = getAllFields(minecraftKeyClass,
fieldOf("a", max(13)),
fieldOf("namespace", min(14)));
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static String getNameSpace(Object instance) throws IllegalAccessException {
if (ReflectionUtils.MINOR <= 13) {
return (String) get(fields, instance, "a");
}
return (String) get(fields, instance, "namespace");
}
public static boolean isFrom(Object instance, Plugin plugin) throws IllegalAccessException {
String namespace = plugin.getName().toLowerCase(Locale.ROOT);
return namespace.equalsIgnoreCase(getNameSpace(instance));
}
public static Predicate<Object> matchingPluginPredicate(AtomicBoolean errorThrown, Plugin plugin) {
return o -> {
try {
return RMinecraftKey.isFrom(o, plugin);
} catch (IllegalAccessException ex) {
if (!errorThrown.get()) {
ex.printStackTrace();
errorThrown.set(true);
}
}
return false;
};
}
}

View file

@ -0,0 +1,29 @@
package net.frankheijden.serverutils.reflection;
import java.lang.reflect.Method;
import java.util.Map;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.MethodParam.methodOf;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.VersionParam.ALL_VERSIONS;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.getAllMethods;
public class RMinecraftServer {
private static Class<?> minecraftServerClass;
private static Map<String, Method> methods;
static {
try {
minecraftServerClass = Class.forName(String.format("net.minecraft.server.%s.MinecraftServer", ReflectionUtils.NMS));
methods = getAllMethods(minecraftServerClass,
methodOf("getServer", ALL_VERSIONS),
methodOf("getCraftingManager", ALL_VERSIONS));
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static Map<String, Method> getMethods() {
return methods;
}
}

View file

@ -0,0 +1,40 @@
package net.frankheijden.serverutils.reflection;
import net.frankheijden.serverutils.utils.MapUtils;
import org.bukkit.plugin.Plugin;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.FieldParam.fieldOf;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.VersionParam.ALL_VERSIONS;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.get;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.getAllFields;
public class RRegistryMaterials {
private static Class<?> registryMaterialsClass;
private static Map<String, Field> fields;
static {
try {
registryMaterialsClass = Class.forName(String.format("net.minecraft.server.%s.RegistryMaterials", ReflectionUtils.NMS));
fields = getAllFields(registryMaterialsClass,
fieldOf("b", ALL_VERSIONS));
} catch (Exception ex) {
ex.printStackTrace();
}
}
@SuppressWarnings("rawtypes")
public static void removeKeysFor(Object instance, Plugin plugin) throws IllegalAccessException {
Map map = (Map) get(fields, instance, "b");
if (map == null) throw new RuntimeException("Map object was null!");
AtomicBoolean errorThrown = new AtomicBoolean(false);
MapUtils.removeValues(map, RMinecraftKey.matchingPluginPredicate(errorThrown, plugin));
RRegistrySimple.removeKeyFor(instance, plugin);
}
}

View file

@ -0,0 +1,38 @@
package net.frankheijden.serverutils.reflection;
import net.frankheijden.serverutils.utils.MapUtils;
import org.bukkit.plugin.Plugin;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.FieldParam.fieldOf;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.VersionParam.ALL_VERSIONS;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.get;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.getAllFields;
public class RRegistrySimple {
private static Class<?> registrySimpleClass;
private static Map<String, Field> fields;
static {
try {
registrySimpleClass = Class.forName(String.format("net.minecraft.server.%s.RegistrySimple", ReflectionUtils.NMS));
fields = getAllFields(registrySimpleClass,
fieldOf("c", ALL_VERSIONS));
} catch (Exception ex) {
ex.printStackTrace();
}
}
@SuppressWarnings("rawtypes")
public static void removeKeyFor(Object instance, Plugin plugin) throws IllegalAccessException {
Map map = (Map) get(fields, instance, "c");
if (map == null) throw new RuntimeException("Map object was null!");
AtomicBoolean errorThrown = new AtomicBoolean(false);
MapUtils.removeKeys(map, RMinecraftKey.matchingPluginPredicate(errorThrown, plugin));
}
}

View file

@ -0,0 +1,29 @@
package net.frankheijden.serverutils.utils;
import java.util.*;
import java.util.function.Predicate;
public class MapUtils {
@SuppressWarnings({"unchecked", "rawtypes"})
public static void removeKeys(Map map, Predicate<Object> predicate) {
Set<Object> keysToRemove = new HashSet<>();
map.forEach((k, v) -> {
if (predicate.test(k)) {
keysToRemove.add(k);
}
});
keysToRemove.forEach(map::remove);
}
@SuppressWarnings({"unchecked", "rawtypes"})
public static void removeValues(Map map, Predicate<Object> predicate) {
Set<Object> keysToRemove = new HashSet<>();
map.forEach((k, v) -> {
if (predicate.test(v)) {
keysToRemove.add(k);
}
});
keysToRemove.forEach(map::remove);
}
}