Refactor after-processor

This commit is contained in:
libraryaddict 2025-02-01 21:19:52 +13:00
parent d6ff57c718
commit 49f5083585
6 changed files with 254 additions and 224 deletions

View File

@ -223,110 +223,114 @@ public class ReflectionManager {
}
try {
// Authlib renamed it to "name()/value()/signature()" in later versions
propertyName = Property.class.getMethod("getName");
propertyValue = Property.class.getMethod("getValue");
propertySignature = Property.class.getMethod("getSignature");
} catch (Exception ignored) {
}
if (nmsReflection != null) {
return;
if (nmsReflection == null) {
// I should probably seperate the code into its own reflection class
loadLegacyReflection();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static void loadLegacyReflection() throws InvocationTargetException, IllegalAccessException {
getServerMethod = getCraftMethod("CraftServer", "getServer");
Object minecraftServer = getMinecraftServer();
for (Method method : getNmsClass("MinecraftServer").getMethods()) {
if (!method.getReturnType().getSimpleName().equals("MinecraftSessionService")) {
continue;
}
getServerMethod = getCraftMethod("CraftServer", "getServer");
sessionService = (MinecraftSessionService) method.invoke(minecraftServer);
break;
}
Object minecraftServer = getMinecraftServer();
if (DisguiseUtilities.isRunningPaper() && !NmsVersion.v1_17.isSupported()) {
// Uses a private field
trackedPlayersMap = getNmsField("EntityTrackerEntry", "trackedPlayerMap");
}
for (Method method : getNmsClass("MinecraftServer").getMethods()) {
if (!method.getReturnType().getSimpleName().equals("MinecraftSessionService")) {
continue;
}
// In 1.12 to 1.13, it's all in EntityTrackerEntry
// In 1.14+, we have it in EntityTracker in PlayerChunkMap
if (NmsVersion.v1_14.isSupported()) {
clearEntityTracker =
getNmsMethod("PlayerChunkMap$EntityTracker", NmsVersion.v1_18.isSupported() ? "a" : "clear", getNmsClass("EntityPlayer"));
addEntityTracker = getNmsMethod("PlayerChunkMap$EntityTracker", NmsVersion.v1_18.isSupported() ? "b" : "updatePlayer",
getNmsClass("EntityPlayer"));
} else {
clearEntityTracker = getNmsMethod("EntityTrackerEntry", "clear", getNmsClass("EntityPlayer"));
addEntityTracker = getNmsMethod("EntityTrackerEntry", "updatePlayer", getNmsClass("EntityPlayer"));
}
sessionService = (MinecraftSessionService) method.invoke(minecraftServer);
break;
getGameProfile = getCraftMethod("CraftPlayer", "getProfile");
boundingBoxConstructor =
getNmsConstructor("AxisAlignedBB", double.class, double.class, double.class, double.class, double.class, double.class);
setBoundingBoxMethod = getNmsMethod("Entity", "a", getNmsClass("AxisAlignedBB"));
entityCountField = getNmsField("Entity", "entityCount");
boundingBoxMethod = getNmsMethod("Entity", "getBoundingBox");
bukkitEntityMethod = getNmsMethod("Entity", "getBukkitEntity");
Class<?> craftItemClass = getCraftClass("CraftItemStack");
itemAsCraftCopyMethod = getCraftMethod(craftItemClass, "asCraftCopy", ItemStack.class);
itemAsBukkitMethod = getCraftMethod(craftItemClass, "asBukkitCopy", getNmsClass("ItemStack"));
getNmsEntityMethod = getCraftMethod("CraftEntity", "getHandle");
Class craftSound = getCraftClass("CraftSound");
try {
soundGetMethod = craftSound.getMethod("getSound", Sound.class);
} catch (Exception ex) {
soundEffectGetMethod = getCraftMethod("CraftSound", "getSoundEffect", Sound.class);
soundEffectGetKey = getNmsField("SoundEffect", "b");
}
getBlockData = getNmsMethod(getNmsClass("Block"), "getBlockData");
if (NmsVersion.v1_13.isSupported()) {
craftBlockDataGetState = getCraftMethod("CraftBlockData", "getState");
magicGetBlock = getCraftMethod("CraftMagicNumbers", "getBlock", Material.class);
magicGetMaterial = getCraftMethod("CraftMagicNumbers", "getMaterial", getNmsClass("Block"));
entityTypesAMethod = getNmsMethod("EntityTypes", "a", String.class);
}
getBlockDataAsId = getNmsMethod("Block", "getCombinedId", getNmsClass("IBlockData"));
getNmsWorld = getCraftMethod("CraftWorld", "getHandle");
deserializedItemMeta = getCraftMethod(getCraftClass("CraftMetaItem$SerializableMeta"), "deserialize", Map.class);
noDamageTicks = getNmsField("Entity", "noDamageTicks");
isInvul = getNmsMethod("Entity", "isInvulnerable", getNmsClass("DamageSource"));
for (Field f : getNmsClass("DamageSource").getFields()) {
if (!Modifier.isStatic(f.getModifiers())) {
continue;
}
if (DisguiseUtilities.isRunningPaper() && !NmsVersion.v1_17.isSupported()) {
// Uses a private field
trackedPlayersMap = getNmsField("EntityTrackerEntry", "trackedPlayerMap");
Object obj = f.get(null);
if (obj == null) {
continue;
}
// In 1.12 to 1.13, it's all in EntityTrackerEntry
// In 1.14+, we have it in EntityTracker in PlayerChunkMap
if (NmsVersion.v1_14.isSupported()) {
clearEntityTracker = getNmsMethod("PlayerChunkMap$EntityTracker", NmsVersion.v1_18.isSupported() ? "a" : "clear",
getNmsClass("EntityPlayer"));
addEntityTracker = getNmsMethod("PlayerChunkMap$EntityTracker", NmsVersion.v1_18.isSupported() ? "b" : "updatePlayer",
getNmsClass("EntityPlayer"));
} else {
clearEntityTracker = getNmsMethod("EntityTrackerEntry", "clear", getNmsClass("EntityPlayer"));
addEntityTracker = getNmsMethod("EntityTrackerEntry", "updatePlayer", getNmsClass("EntityPlayer"));
if (!obj.toString().contains("(generic)")) {
continue;
}
getGameProfile = getCraftMethod("CraftPlayer", "getProfile");
boundingBoxConstructor =
getNmsConstructor("AxisAlignedBB", double.class, double.class, double.class, double.class, double.class, double.class);
setBoundingBoxMethod = getNmsMethod("Entity", "a", getNmsClass("AxisAlignedBB"));
entityCountField = getNmsField("Entity", "entityCount");
boundingBoxMethod = getNmsMethod("Entity", "getBoundingBox");
bukkitEntityMethod = getNmsMethod("Entity", "getBukkitEntity");
Class<?> craftItemClass = getCraftClass("CraftItemStack");
itemAsCraftCopyMethod = getCraftMethod(craftItemClass, "asCraftCopy", ItemStack.class);
itemAsBukkitMethod = getCraftMethod(craftItemClass, "asBukkitCopy", getNmsClass("ItemStack"));
getNmsEntityMethod = getCraftMethod("CraftEntity", "getHandle");
Class craftSound = getCraftClass("CraftSound");
try {
soundGetMethod = craftSound.getMethod("getSound", Sound.class);
} catch (Exception ex) {
soundEffectGetMethod = getCraftMethod("CraftSound", "getSoundEffect", Sound.class);
soundEffectGetKey = getNmsField("SoundEffect", "b");
}
getBlockData = getNmsMethod(getNmsClass("Block"), "getBlockData");
if (NmsVersion.v1_13.isSupported()) {
craftBlockDataGetState = getCraftMethod("CraftBlockData", "getState");
magicGetBlock = getCraftMethod("CraftMagicNumbers", "getBlock", Material.class);
magicGetMaterial = getCraftMethod("CraftMagicNumbers", "getMaterial", getNmsClass("Block"));
entityTypesAMethod = getNmsMethod("EntityTypes", "a", String.class);
}
getBlockDataAsId = getNmsMethod("Block", "getCombinedId", getNmsClass("IBlockData"));
getNmsWorld = getCraftMethod("CraftWorld", "getHandle");
deserializedItemMeta = getCraftMethod(getCraftClass("CraftMetaItem$SerializableMeta"), "deserialize", Map.class);
noDamageTicks = getNmsField("Entity", "noDamageTicks");
isInvul = getNmsMethod("Entity", "isInvulnerable", getNmsClass("DamageSource"));
for (Field f : getNmsClass("DamageSource").getFields()) {
if (!Modifier.isStatic(f.getModifiers())) {
continue;
}
Object obj = f.get(null);
if (obj == null) {
continue;
}
if (!obj.toString().contains("(generic)")) {
continue;
}
genericDamage = obj;
break;
}
} catch (Exception e) {
e.printStackTrace();
genericDamage = obj;
break;
}
try {

View File

@ -21,7 +21,7 @@ tasks {
shadowJar {
configurations = listOf(project.configurations.shadow.get())
exclude("**/CompileMethods.class")
exclude("me/libraryaddict/disguise/utilities/compiler/**")
}
getByName("run") {
@ -57,7 +57,7 @@ tasks {
}
application {
mainClass = "me.libraryaddict.disguise.utilities.watchers.CompileMethods"
mainClass = "me.libraryaddict.disguise.utilities.compiler.CompileShadedFiles"
applicationDefaultJvmArgs = listOf(
"-Djar.path=" + tasks.named<ShadowJar>("shadowJar").get().archiveFile.get().asFile.absolutePath
)

View File

@ -0,0 +1,27 @@
package me.libraryaddict.disguise.utilities.compiler;
import me.libraryaddict.disguise.utilities.compiler.tasks.CompileJarFileCount;
import me.libraryaddict.disguise.utilities.compiler.tasks.CompileMethods;
import me.libraryaddict.disguise.utilities.compiler.tasks.CompileSounds;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class CompileShadedFiles {
public static void main(String[] args) {
Path zipFilePath = Paths.get(System.getProperty("jar.path"));
try (FileSystem fs = FileSystems.newFileSystem(zipFilePath, (ClassLoader) null)) {
Files.write(fs.getPath("/METHOD_MAPPINGS.txt"), new CompileMethods().doMethods());
Files.write(fs.getPath("/SOUND_MAPPINGS.txt"), new CompileSounds().doSounds());
// Count after we write the mappings
Files.write(fs.getPath("/plugin.yml"), new CompileJarFileCount().doFileCount());
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,56 @@
package me.libraryaddict.disguise.utilities.compiler.tasks;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class CompileJarFileCount {
private int getJarFileCount(File file, String... skipFiles) {
try (JarFile jar = new JarFile(file)) {
int count = 0;
Enumeration<JarEntry> entries = jar.entries();
loop:
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (entry.isDirectory()) {
continue;
}
for (String skipFile : skipFiles) {
if (!skipFile.equals(entry.getName())) {
continue;
}
continue loop;
}
count++;
}
return count;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public byte[] doFileCount() {
int totalCount = getJarFileCount(new File(System.getProperty("jar.path")), "METHOD_MAPPINGS.txt", "SOUND_MAPPINGS.txt") + 2;
try {
Path path = new File(new File("build/resources/main"), "plugin.yml").toPath();
String pluginYaml =
Files.readString(path, StandardCharsets.UTF_8).replaceFirst("file-count: -?\\d+", "file-count: " + totalCount);
return pluginYaml.getBytes(StandardCharsets.UTF_8);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,4 +1,4 @@
package me.libraryaddict.disguise.utilities.watchers;
package me.libraryaddict.disguise.utilities.compiler.tasks;
import com.google.gson.Gson;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
@ -14,148 +14,18 @@ import me.libraryaddict.disguise.utilities.reflection.annotations.MethodMappedAs
import me.libraryaddict.disguise.utilities.reflection.annotations.MethodOnlyUsedBy;
import me.libraryaddict.disguise.utilities.reflection.annotations.NmsAddedIn;
import me.libraryaddict.disguise.utilities.reflection.annotations.NmsRemovedIn;
import me.libraryaddict.disguise.utilities.sounds.DisguiseSoundEnums;
import me.libraryaddict.disguise.utilities.sounds.SoundGroup;
import org.bukkit.Sound;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class CompileMethods {
public static void main(String[] args) {
Path zipFilePath = Paths.get(System.getProperty("jar.path"));
try (FileSystem fs = FileSystems.newFileSystem(zipFilePath, (ClassLoader) null)) {
Files.write(fs.getPath("/METHOD_MAPPINGS.txt"), doMethods());
Files.write(fs.getPath("/SOUND_MAPPINGS.txt"), doSounds());
// Count after we write the mappings
Files.write(fs.getPath("/plugin.yml"), doFileCount());
} catch (IOException e) {
e.printStackTrace();
}
}
private static int getJarFileCount(File file, String... skipFiles) {
try (JarFile jar = new JarFile(file)) {
int count = 0;
Enumeration<JarEntry> entries = jar.entries();
loop:
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (entry.isDirectory()) {
continue;
}
for (String skipFile : skipFiles) {
if (!skipFile.equals(entry.getName())) {
continue;
}
continue loop;
}
count++;
}
return count;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static byte[] doFileCount() {
int totalCount = getJarFileCount(new File(System.getProperty("jar.path")), "METHOD_MAPPINGS.txt", "SOUND_MAPPINGS.txt") + 2;
try {
Path path = new File(new File("build/resources/main"), "plugin.yml").toPath();
String pluginYaml =
Files.readString(path, StandardCharsets.UTF_8).replaceFirst("file-count: -?\\d+", "file-count: " + totalCount);
return pluginYaml.getBytes(StandardCharsets.UTF_8);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static byte[] doSounds() {
List<String> list = new ArrayList<>();
for (DisguiseSoundEnums e : DisguiseSoundEnums.values()) {
StringBuilder sound = getSoundAsString(e);
list.add(sound.toString());
}
return String.join("\n", list).getBytes(StandardCharsets.UTF_8);
}
private static List<String> getMatchingFields(String pattern) {
List<String> matches = new ArrayList<>();
for (Field field : Sound.class.getFields()) {
if (!Modifier.isStatic(field.getModifiers()) || field.getType() != Sound.class) {
continue;
}
if (!field.getName().matches(pattern)) {
continue;
}
matches.add(field.getName());
}
return matches;
}
private static StringBuilder getSoundAsString(DisguiseSoundEnums e) {
StringBuilder sound = new StringBuilder(e.name());
for (SoundGroup.SoundType type : SoundGroup.SoundType.values()) {
sound.append("/");
int i = 0;
for (Map.Entry<String, SoundGroup.SoundType> entry : e.getSounds().entrySet()) {
if (entry.getValue() != type) {
continue;
}
String soundValue = entry.getKey();
if (soundValue.contains("*")) {
soundValue = String.join(",", getMatchingFields(soundValue));
}
if (i++ > 0) {
sound.append(",");
}
sound.append(soundValue);
}
}
return sound;
}
private static void addClass(ArrayList<Class> classes, Class c) {
private void addClass(ArrayList<Class> classes, Class c) {
if (classes.contains(c)) {
return;
}
@ -167,7 +37,7 @@ public class CompileMethods {
classes.add(c);
}
private static byte[] doMethods() {
public byte[] doMethods() {
ArrayList<Class<?>> classes =
ClassGetter.getClassesForPackage(FlagWatcher.class, "me.libraryaddict.disguise.disguisetypes.watchers");
@ -306,7 +176,7 @@ public class CompileMethods {
return new Gson().toJson(methods).getBytes(StandardCharsets.UTF_8);
}
static String getDescriptorForClass(final Class c) {
private String getDescriptorForClass(final Class c) {
if (c.isPrimitive()) {
if (c == byte.class) {
return "B";
@ -346,7 +216,7 @@ public class CompileMethods {
return ('L' + c.getName() + ';').replace('.', '/');
}
static String getMethodDescriptor(Method m) {
private String getMethodDescriptor(Method m) {
StringBuilder s = new StringBuilder("(");
for (final Class c : (m.getParameterTypes())) {

View File

@ -0,0 +1,73 @@
package me.libraryaddict.disguise.utilities.compiler.tasks;
import me.libraryaddict.disguise.utilities.sounds.DisguiseSoundEnums;
import me.libraryaddict.disguise.utilities.sounds.SoundGroup;
import org.bukkit.Sound;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class CompileSounds {
public byte[] doSounds() {
List<String> list = new ArrayList<>();
for (DisguiseSoundEnums e : DisguiseSoundEnums.values()) {
StringBuilder sound = getSoundAsString(e);
list.add(sound.toString());
}
return String.join("\n", list).getBytes(StandardCharsets.UTF_8);
}
private StringBuilder getSoundAsString(DisguiseSoundEnums e) {
StringBuilder sound = new StringBuilder(e.name());
for (SoundGroup.SoundType type : SoundGroup.SoundType.values()) {
sound.append("/");
int i = 0;
for (Map.Entry<String, SoundGroup.SoundType> entry : e.getSounds().entrySet()) {
if (entry.getValue() != type) {
continue;
}
String soundValue = entry.getKey();
if (soundValue.contains("*")) {
soundValue = String.join(",", getMatchingFields(soundValue));
}
if (i++ > 0) {
sound.append(",");
}
sound.append(soundValue);
}
}
return sound;
}
private List<String> getMatchingFields(String pattern) {
List<String> matches = new ArrayList<>();
for (Field field : Sound.class.getFields()) {
if (!Modifier.isStatic(field.getModifiers()) || field.getType() != Sound.class) {
continue;
}
if (!field.getName().matches(pattern)) {
continue;
}
matches.add(field.getName());
}
return matches;
}
}