diff options
author | DeDiamondPro <67508414+DeDiamondPro@users.noreply.github.com> | 2022-06-05 17:43:23 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-05 17:43:23 +0200 |
commit | ab7256dff5d6d37488081ba7a01b36d3ee9ef563 (patch) | |
tree | 8207341e6c402848cdbe7b2f2297f5f975e0e083 /src/main/java/cc/polyfrost/oneconfig/internal/plugin | |
parent | a903cfc4d3f76cf3db24749b65156d126fa714e7 (diff) | |
download | OneConfig-ab7256dff5d6d37488081ba7a01b36d3ee9ef563.tar.gz OneConfig-ab7256dff5d6d37488081ba7a01b36d3ee9ef563.tar.bz2 OneConfig-ab7256dff5d6d37488081ba7a01b36d3ee9ef563.zip |
refactor (#36)
* refactor
* fix vig compat
* fix nanovg thingy
* e
* finalize
* gui utils package thingy
Diffstat (limited to 'src/main/java/cc/polyfrost/oneconfig/internal/plugin')
7 files changed, 365 insertions, 0 deletions
diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/plugin/LoadingPlugin.java b/src/main/java/cc/polyfrost/oneconfig/internal/plugin/LoadingPlugin.java new file mode 100644 index 0000000..b819f24 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/internal/plugin/LoadingPlugin.java @@ -0,0 +1,53 @@ +package cc.polyfrost.oneconfig.internal.plugin; + +import cc.polyfrost.oneconfig.internal.init.OneConfigInit; +import net.minecraft.launchwrapper.Launch; +import net.minecraft.launchwrapper.LaunchClassLoader; +import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; + +import java.lang.reflect.Field; +import java.util.Map; +import java.util.Set; + +public class LoadingPlugin implements IFMLLoadingPlugin { + + /** + * Taken from LWJGLTwoPointFive under The Unlicense + * <a href="https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/">https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/</a> + */ + public LoadingPlugin() { + try { + Field f_exceptions = LaunchClassLoader.class.getDeclaredField("classLoaderExceptions"); + f_exceptions.setAccessible(true); + Set<String> exceptions = (Set<String>) f_exceptions.get(Launch.classLoader); + exceptions.remove("org.lwjgl."); + OneConfigInit.initialize(new String[]{}); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public String[] getASMTransformerClass() { + return new String[]{"cc.polyfrost.oneconfig.internal.plugin.asm.ClassTransformer"}; + } + + @Override + public String getModContainerClass() { + return null; + } + + @Override + public String getSetupClass() { + return null; + } + + @Override + public void injectData(Map<String, Object> data) { + } + + @Override + public String getAccessTransformerClass() { + return null; + } +}
\ No newline at end of file diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/plugin/Lwjgl2FunctionProvider.java b/src/main/java/cc/polyfrost/oneconfig/internal/plugin/Lwjgl2FunctionProvider.java new file mode 100644 index 0000000..105afa2 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/internal/plugin/Lwjgl2FunctionProvider.java @@ -0,0 +1,39 @@ +package cc.polyfrost.oneconfig.internal.plugin; + +import org.lwjgl.opengl.GLContext; +import org.lwjgl.system.FunctionProvider; + +import java.lang.reflect.Method; +import java.nio.ByteBuffer; + +/** + * Taken from LWJGLTwoPointFive under The Unlicense + * <a href="https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/">https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/</a> + */ +public class Lwjgl2FunctionProvider implements FunctionProvider { + + private final Method m_getFunctionAddress; + + public Lwjgl2FunctionProvider() { + try { + m_getFunctionAddress = GLContext.class.getDeclaredMethod("getFunctionAddress", String.class); + m_getFunctionAddress.setAccessible(true); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public long getFunctionAddress(CharSequence functionName) { + try { + return (long) m_getFunctionAddress.invoke(null, functionName.toString()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public long getFunctionAddress(ByteBuffer byteBuffer) { + throw new UnsupportedOperationException(); + } +}
\ No newline at end of file diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/plugin/OneConfigMixinPlugin.java b/src/main/java/cc/polyfrost/oneconfig/internal/plugin/OneConfigMixinPlugin.java new file mode 100644 index 0000000..c55febc --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/internal/plugin/OneConfigMixinPlugin.java @@ -0,0 +1,52 @@ +package cc.polyfrost.oneconfig.internal.plugin; + +import org.spongepowered.asm.lib.tree.ClassNode; +import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; +import org.spongepowered.asm.mixin.extensibility.IMixinInfo; + +import java.util.List; +import java.util.Set; + +public class OneConfigMixinPlugin implements IMixinConfigPlugin { + public static boolean isVigilance = false; + + @Override + public void onLoad(String mixinPackage) { + try { + Class.forName("gg.essential.vigilance.Vigilant"); + isVigilance = true; + } catch (Exception e) { + isVigilance = false; + } + } + + @Override + public String getRefMapperConfig() { + return null; + } + + @Override + public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { + return !targetClassName.contains("vigilance") || isVigilance; + } + + @Override + public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) { + + } + + @Override + public List<String> getMixins() { + return null; + } + + @Override + public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { + + } + + @Override + public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { + + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/ClassTransformer.java b/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/ClassTransformer.java new file mode 100644 index 0000000..1a2766f --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/ClassTransformer.java @@ -0,0 +1,64 @@ +package cc.polyfrost.oneconfig.internal.plugin.asm; + +import cc.polyfrost.oneconfig.internal.plugin.asm.tweakers.NanoVGGLConfigTransformer; +import cc.polyfrost.oneconfig.internal.plugin.asm.tweakers.VigilantTransformer; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import net.minecraft.launchwrapper.IClassTransformer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.tree.ClassNode; + +import java.util.Collection; + +/** + * Taken from LWJGLTwoPointFive under The Unlicense + * <a href="https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/">https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/</a> + * <p>also half taken from asmworkspace by asbyth ty</p> + */ +@SuppressWarnings("unused") +public class ClassTransformer implements IClassTransformer { + private static final Logger logger = LogManager.getLogger("OneConfig ASM"); + private final Multimap<String, ITransformer> transformerMap = ArrayListMultimap.create(); + + public ClassTransformer() { + registerTransformer(new NanoVGGLConfigTransformer()); + registerTransformer(new VigilantTransformer()); + } + + private void registerTransformer(ITransformer transformer) { + // loop through names of classes + for (String cls : transformer.getClassName()) { + // put the classes into the transformer map + transformerMap.put(cls, transformer); + } + } + + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) { + if (basicClass == null) return null; + + Collection<ITransformer> transformers = transformerMap.get(transformedName); + if (transformers.isEmpty()) return basicClass; + + + ClassReader reader = new ClassReader(basicClass); + ClassNode node = new ClassNode(); + reader.accept(node, ClassReader.EXPAND_FRAMES); + + for (ITransformer transformer : transformers) { + transformer.transform(transformedName, node); + } + + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + try { + node.accept(cw); + } catch (Throwable t) { + logger.error("Exception when transforming " + transformedName + " : " + t.getClass().getSimpleName()); + t.printStackTrace(); + } + return cw.toByteArray(); + } +}
\ No newline at end of file diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/ITransformer.java b/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/ITransformer.java new file mode 100644 index 0000000..482a310 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/ITransformer.java @@ -0,0 +1,9 @@ +package cc.polyfrost.oneconfig.internal.plugin.asm; + +import org.objectweb.asm.tree.ClassNode; + +public interface ITransformer { + String[] getClassName(); + + void transform(String transformedName, ClassNode node); +} diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/tweakers/NanoVGGLConfigTransformer.java b/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/tweakers/NanoVGGLConfigTransformer.java new file mode 100644 index 0000000..4d7a5cc --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/tweakers/NanoVGGLConfigTransformer.java @@ -0,0 +1,43 @@ +package cc.polyfrost.oneconfig.internal.plugin.asm.tweakers; + +import cc.polyfrost.oneconfig.internal.plugin.asm.ITransformer; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.*; + +public class NanoVGGLConfigTransformer implements ITransformer { + @Override + public String[] getClassName() { + return new String[]{"org.lwjgl.nanovg.NanoVGGLConfig"}; + } + + @Override + public void transform(String transformedName, ClassNode node) { + for (MethodNode method : node.methods) { + if (method.name.equals("configGL")) { + InsnList list = new InsnList(); + + list.add(new VarInsnNode(Opcodes.LLOAD, 0)); + list.add(new TypeInsnNode(Opcodes.NEW, "cc/polyfrost/oneconfig/internal/plugin/Lwjgl2FunctionProvider")); + list.add(new InsnNode(Opcodes.DUP)); + list.add(new MethodInsnNode( + Opcodes.INVOKESPECIAL, + "cc/polyfrost/oneconfig/internal/plugin/Lwjgl2FunctionProvider", + "<init>", + "()V", + false + )); + list.add(new MethodInsnNode( + Opcodes.INVOKESTATIC, + "org/lwjgl/nanovg/NanoVGGLConfig", + "config", + "(JLorg/lwjgl/system/FunctionProvider;)V", + false + )); + list.add(new InsnNode(Opcodes.RETURN)); + + method.instructions.clear(); + method.instructions.insert(list); + } + } + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/tweakers/VigilantTransformer.java b/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/tweakers/VigilantTransformer.java new file mode 100644 index 0000000..f241c74 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/internal/plugin/asm/tweakers/VigilantTransformer.java @@ -0,0 +1,105 @@ +package cc.polyfrost.oneconfig.internal.plugin.asm.tweakers; + +import cc.polyfrost.oneconfig.config.compatibility.vigilance.VigilanceConfig; +import cc.polyfrost.oneconfig.config.core.ConfigCore; +import cc.polyfrost.oneconfig.config.data.Mod; +import cc.polyfrost.oneconfig.config.data.ModType; +import cc.polyfrost.oneconfig.internal.plugin.asm.ITransformer; +import gg.essential.vigilance.Vigilant; +import gg.essential.vigilance.data.PropertyCollector; +import net.minecraft.client.Minecraft; +import net.minecraftforge.fml.common.Loader; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import java.io.File; + +public class VigilantTransformer implements ITransformer { + @SuppressWarnings("unused") + public static VigilanceConfig returnNewConfig(Vigilant vigilant, File file) { + if (vigilant != null && Minecraft.getMinecraft().isCallingFromMinecraftThread()) { + String name = !vigilant.getGuiTitle().equals("Settings") ? vigilant.getGuiTitle() : Loader.instance().activeModContainer() == null ? "Unknown" : Loader.instance().activeModContainer().getName(); + if (name.equals("OneConfig")) name = "Essential"; + String finalName = name; + // duplicate fix + if (ConfigCore.oneConfigMods.stream().anyMatch(mod -> mod.name.equals(finalName))) return null; + return new VigilanceConfig(new Mod(name, ModType.THIRD_PARTY), file.getAbsolutePath(), vigilant); + } else { + return null; + } + } + + @Override + public String[] getClassName() { + return new String[]{"gg.essential.vigilance.Vigilant"}; + } + + @Override + public void transform(String transformedName, ClassNode node) { + node.fields.add(new FieldNode(Opcodes.ACC_PUBLIC, "oneconfig$config", Type.getDescriptor(VigilanceConfig.class), null, null)); + node.fields.add(new FieldNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "oneconfig$file", Type.getDescriptor(File.class), null, null)); + + node.interfaces.add("cc/polyfrost/oneconfig/config/compatibility/vigilance/VigilantAccessor"); + MethodNode methodNode = new MethodNode(Opcodes.ACC_PUBLIC, "getPropertyCollector", "()Lgg/essential/vigilance/data/PropertyCollector;", null, null); + LabelNode labelNode = new LabelNode(); + methodNode.instructions.add(labelNode); + methodNode.instructions.add(new LineNumberNode(421421, labelNode)); + methodNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); + methodNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, "gg/essential/vigilance/Vigilant", "propertyCollector", Type.getDescriptor(PropertyCollector.class))); + methodNode.instructions.add(new InsnNode(Opcodes.ARETURN)); + node.methods.add(methodNode); + + MethodNode methodNode2 = new MethodNode(Opcodes.ACC_PUBLIC, "handleOneConfigDependency", "(Lgg/essential/vigilance/data/PropertyData;Lgg/essential/vigilance/data/PropertyData;)V", null, null); + LabelNode labelNode2 = new LabelNode(); + LabelNode labelNode3 = new LabelNode(); + LabelNode labelNode4 = new LabelNode(); + methodNode2.instructions.add(labelNode2); + methodNode2.instructions.add(new LineNumberNode(15636436, labelNode2)); + methodNode2.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); + methodNode2.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, "gg/essential/vigilance/Vigilant", "oneconfig$config", Type.getDescriptor(VigilanceConfig.class))); + + methodNode2.instructions.add(new JumpInsnNode(Opcodes.IFNULL, labelNode4)); + + methodNode2.instructions.add(labelNode3); + methodNode2.instructions.add(new LineNumberNode(15636437, labelNode3)); + methodNode2.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); + methodNode2.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, "gg/essential/vigilance/Vigilant", "oneconfig$config", Type.getDescriptor(VigilanceConfig.class))); + methodNode2.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); + methodNode2.instructions.add(new VarInsnNode(Opcodes.ALOAD, 2)); + methodNode2.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, Type.getInternalName(VigilanceConfig.class), "addDependency", "(Lgg/essential/vigilance/data/PropertyData;Lgg/essential/vigilance/data/PropertyData;)V", false)); + + methodNode2.instructions.add(labelNode4); + methodNode2.instructions.add(new LineNumberNode(15636438, labelNode4)); + methodNode2.instructions.add(new InsnNode(Opcodes.RETURN)); + node.methods.add(methodNode2); + + for (MethodNode method : node.methods) { + if (method.name.equals("initialize")) { + InsnList list = new InsnList(); + list.add(new VarInsnNode(Opcodes.ALOAD, 0)); + list.add(new VarInsnNode(Opcodes.ALOAD, 0)); + list.add(new VarInsnNode(Opcodes.ALOAD, 0)); + list.add(new FieldInsnNode(Opcodes.GETFIELD, "gg/essential/vigilance/Vigilant", "oneconfig$file", Type.getDescriptor(File.class))); + list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(getClass()), "returnNewConfig", "(Lgg/essential/vigilance/Vigilant;Ljava/io/File;)Lcc/polyfrost/oneconfig/config/compatibility/vigilance/VigilanceConfig;", false)); + list.add(new FieldInsnNode(Opcodes.PUTFIELD, "gg/essential/vigilance/Vigilant", "oneconfig$config", Type.getDescriptor(VigilanceConfig.class))); + method.instructions.insertBefore(method.instructions.getLast().getPrevious(), list); + } else if (method.name.equals("addDependency") && method.desc.equals("(Lgg/essential/vigilance/data/PropertyData;Lgg/essential/vigilance/data/PropertyData;)V")) { + InsnList list = new InsnList(); + + list.add(new VarInsnNode(Opcodes.ALOAD, 0)); + list.add(new VarInsnNode(Opcodes.ALOAD, 1)); + list.add(new VarInsnNode(Opcodes.ALOAD, 2)); + list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "gg/essential/vigilance/Vigilant", "handleOneConfigDependency", "(Lgg/essential/vigilance/data/PropertyData;Lgg/essential/vigilance/data/PropertyData;)V", false)); + + method.instructions.insertBefore(method.instructions.getLast().getPrevious(), list); + } else if (method.name.equals("<init>") && method.desc.equals("(Ljava/io/File;Ljava/lang/String;Lgg/essential/vigilance/data/PropertyCollector;Lgg/essential/vigilance/data/SortingBehavior;)V")) { + InsnList list = new InsnList(); + list.add(new VarInsnNode(Opcodes.ALOAD, 0)); + list.add(new VarInsnNode(Opcodes.ALOAD, 1)); + list.add(new FieldInsnNode(Opcodes.PUTFIELD, "gg/essential/vigilance/Vigilant", "oneconfig$file", Type.getDescriptor(File.class))); + method.instructions.insertBefore(method.instructions.getLast().getPrevious(), list); + } + } + } +} |