From ae73bc2b43bb55e90266a98ceae9ce0348faf350 Mon Sep 17 00:00:00 2001 From: Cat Core <34719527+arthurbambou@users.noreply.github.com> Date: Mon, 21 Aug 2023 17:49:03 +0200 Subject: [PATCH] Rework some String remapper --- .../DescriptorMappingMixin.java | 38 --- .../FeatureHackTransformerMixin.java | 58 ++++- .../TweakTransformerMixin.java | 163 +++++++++++++ .../fabricated-forge.mods.mixins.json | 1 + .../asm/transformers/AccessTransformer.java | 4 +- .../fr/catcore/fabricatedforge/Constants.java | 226 ++++++++++++++---- 6 files changed, 391 insertions(+), 99 deletions(-) create mode 100644 mod-compat/src/main/java/fr/catcore/fabricatedforge/compat/mixin/codechickencore/TweakTransformerMixin.java diff --git a/mod-compat/src/main/java/fr/catcore/fabricatedforge/compat/mixin/codechickencore/DescriptorMappingMixin.java b/mod-compat/src/main/java/fr/catcore/fabricatedforge/compat/mixin/codechickencore/DescriptorMappingMixin.java index a1fcf457..26176b29 100644 --- a/mod-compat/src/main/java/fr/catcore/fabricatedforge/compat/mixin/codechickencore/DescriptorMappingMixin.java +++ b/mod-compat/src/main/java/fr/catcore/fabricatedforge/compat/mixin/codechickencore/DescriptorMappingMixin.java @@ -47,42 +47,4 @@ private void remap() { this.s_desc = Constants.remapIndividualType(pair.second()); } } - -// /** -// * @author CatCore -// * @reason fix match because of the way methods are added to classes -// */ -// @Overwrite(remap = false) -// public boolean matches(MethodNode node) { -// String className = this.getClassNameForMethod(); -// -// System.out.println(this.s_owner + " -> " + className); -// -// return this.s_name.equals(node.name) && this.s_desc.equals(node.desc); -// } -// -// /** -// * @author CatCore -// * @reason fix match because of the way methods are added to classes -// */ -// @Overwrite(remap = false) -// public boolean matches(MethodInsnNode node) { -// String className = this.getClassNameForMethod(); -// -// System.out.println(this.s_name + " -> " + className + " : " + node.owner); -// -// return className.equals(node.owner) && this.s_name.equals(node.name) && this.s_desc.equals(node.desc); -// } -// -// @Unique -// private String getClassNameForMethod() { -// if (this.s_owner.equals("net/minecraft/class_197") && ( -// this.s_name.equals("canBeReplacedByLeaves") -// || this.s_name.equals("isAirBlock") -// )) { -// return "fr/catcore/fabricatedforge/mixininterface/IBlock"; -// } -// -// return this.s_name; -// } } diff --git a/mod-compat/src/main/java/fr/catcore/fabricatedforge/compat/mixin/codechickencore/FeatureHackTransformerMixin.java b/mod-compat/src/main/java/fr/catcore/fabricatedforge/compat/mixin/codechickencore/FeatureHackTransformerMixin.java index 9cb82104..40ad8bb7 100644 --- a/mod-compat/src/main/java/fr/catcore/fabricatedforge/compat/mixin/codechickencore/FeatureHackTransformerMixin.java +++ b/mod-compat/src/main/java/fr/catcore/fabricatedforge/compat/mixin/codechickencore/FeatureHackTransformerMixin.java @@ -1,18 +1,62 @@ package fr.catcore.fabricatedforge.compat.mixin.codechickencore; +import codechicken.core.asm.ASMHelper; import codechicken.core.asm.FeatureHackTransformer; +import codechicken.core.asm.InstructionComparator; +import codechicken.core.asm.ObfuscationMappings; +import org.objectweb.asm.tree.*; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; +import java.util.List; + @Mixin(FeatureHackTransformer.class) public class FeatureHackTransformerMixin { - @ModifyArg(method = "", index = 2, - remap = false, - at = @At(value = "INVOKE", - remap = false, - target = "Lcodechicken/core/asm/ObfuscationMappings$DescriptorMapping;(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", ordinal = 0)) - private String fixMethodArg(String arg) { - return "(Lnet/minecraft/class_1069;)V"; + @Shadow(remap = false) + ObfuscationMappings.DescriptorMapping f_lastBrightness; + + /** + * @author CatCore + * @reason fix mappings + */ + @Overwrite(remap = false) + private byte[] transformer002(String name, byte[] bytes) { + ClassNode cnode = ASMHelper.createClassNode(bytes); + FieldNode fnode = ASMHelper.findField(this.f_lastBrightness, cnode); + if (fnode == null) { + cnode.fields.add(new FieldNode(9, this.f_lastBrightness.s_name, this.f_lastBrightness.s_desc, null, null)); + MethodNode mlightmap = ASMHelper.findMethod(new ObfuscationMappings.DescriptorMapping("bfe", "a", "(IFF)V"), cnode); + InsnList hook = new InsnList(); + LabelNode lend = new LabelNode(); + hook.add(new VarInsnNode(21, 0)); + hook.add(new ObfuscationMappings.DescriptorMapping("bfe", "b", "I").toFieldInsn(178)); + hook.add(new JumpInsnNode(160, lend)); + hook.add(new VarInsnNode(23, 2)); + hook.add(new InsnNode(139)); + hook.add(new IntInsnNode(16, 16)); + hook.add(new InsnNode(120)); + hook.add(new VarInsnNode(23, 1)); + hook.add(new InsnNode(139)); + hook.add(new InsnNode(128)); + hook.add(this.f_lastBrightness.toFieldInsn(179)); + hook.add(lend); + InsnList needle = new InsnList(); + needle.add(new InsnNode(177)); + List ret = InstructionComparator.insnListFindEnd(mlightmap.instructions, needle); + if (ret.size() != 1) { + throw new RuntimeException( + "Needle not found in Haystack: " + ASMHelper.printInsnList(mlightmap.instructions) + "\n" + ASMHelper.printInsnList(needle) + ); + } + + mlightmap.instructions.insertBefore((AbstractInsnNode)ret.get(0), hook); + bytes = ASMHelper.createBytes(cnode, 3); + System.out.println("Brightness hook injected"); + } + + return bytes; } } diff --git a/mod-compat/src/main/java/fr/catcore/fabricatedforge/compat/mixin/codechickencore/TweakTransformerMixin.java b/mod-compat/src/main/java/fr/catcore/fabricatedforge/compat/mixin/codechickencore/TweakTransformerMixin.java new file mode 100644 index 00000000..d2a40c60 --- /dev/null +++ b/mod-compat/src/main/java/fr/catcore/fabricatedforge/compat/mixin/codechickencore/TweakTransformerMixin.java @@ -0,0 +1,163 @@ +package fr.catcore.fabricatedforge.compat.mixin.codechickencore; + +import codechicken.core.asm.*; +import codechicken.core.config.ConfigFile; +import codechicken.core.config.ConfigTag; +import org.objectweb.asm.tree.*; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.io.File; +import java.util.List; + +@Mixin(TweakTransformer.class) +public abstract class TweakTransformerMixin { + + @Shadow(remap = false) public static ConfigTag tweaks; + + @Shadow(remap = false) + private static void alterMethod(ASMHelper.MethodAltercator ma) { + } + + /** + * @author CatCore + * @reason fix mappings + */ + @Overwrite(remap = false) + public static void load() { + File cfgDir = new File(CodeChickenCorePlugin.minecraftDir + "/config"); + if (!cfgDir.exists()) { + cfgDir.mkdirs(); + } + + ConfigFile config = new ConfigFile(new File(cfgDir, "CodeChickenCore.cfg")).setComment("CodeChickenCore configuration file."); + tweaks = config.getTag("tweaks").setComment("Various tweaks that can be applied to game mechanics.").useBraces(); + if (!tweaks.getTag("persistantLava") + .setComment("Set to false to make lava fade away like water if all the source blocks are destroyed") + .getBooleanValue(true)) { + ObfuscationMappings.ClassMapping blockFlowing = new ObfuscationMappings.ClassMapping("aky"); + alterMethod( + new ASMHelper.MethodAltercator(new ObfuscationMappings.DescriptorMapping(blockFlowing.s_class, new ObfuscationMappings.DescriptorMapping("amq", "b", "(Lyc;IIILjava/util/Random;)V"))) { + public void alter(MethodNode mv) { + InsnList needle = new InsnList(); + needle.add(new VarInsnNode(21, 6)); + needle.add(new VarInsnNode(54, -1)); + needle.add(new InsnNode(3)); + needle.add(new VarInsnNode(54, 8)); + List lists = InstructionComparator.insnListFindL(mv.instructions, needle); + if (lists.size() != 1) { + throw new RuntimeException( + "Needle found " + lists.size() + " times in Haystack: " + mv.instructions + "\n" + ASMHelper.printInsnList(needle) + ); + } else { + InstructionComparator.InsnListSection subsection = (InstructionComparator.InsnListSection)lists.get(0); + AbstractInsnNode insn = subsection.first; + + while(true) { + AbstractInsnNode next = insn.getNext(); + mv.instructions.remove(insn); + if (insn == subsection.last) { + return; + } + + insn = next; + } + } + } + } + ); + } + + if (tweaks.getTag("environmentallyFriendlyCreepers") + .setComment("If set to true, creepers will not destroy landscape. (A version of mobGreifing setting just for creepers)") + .getBooleanValue(false)) { + final ObfuscationMappings.ClassMapping entityCreeper = new ObfuscationMappings.ClassMapping("qc"); + alterMethod( + new ASMHelper.MethodAltercator(new ObfuscationMappings.DescriptorMapping(entityCreeper.s_class, new ObfuscationMappings.DescriptorMapping("lq", "j_", "()V"))) { + public void alter(MethodNode mv) { + InsnList needle = new InsnList(); + needle.add(new VarInsnNode(25, 0)); + needle.add(new ObfuscationMappings.DescriptorMapping(entityCreeper.s_class, new ObfuscationMappings.DescriptorMapping("lq", "p", "Lyc;")).toFieldInsn(180)); + needle.add(new ObfuscationMappings.DescriptorMapping("yc", "L", "()Lxz;").toInsn(182)); + needle.add(new LdcInsnNode("mobGriefing")); + needle.add(new ObfuscationMappings.DescriptorMapping("xz", "b", "(Ljava/lang/String;)Z").toInsn(182)); + List lists = InstructionComparator.insnListFindL(mv.instructions, needle); + if (lists.size() != 1) { + throw new RuntimeException( + "Needle found " + lists.size() + " times in Haystack: " + mv.instructions + "\n" + ASMHelper.printInsnList(needle) + ); + } else { + InstructionComparator.InsnListSection subsection = (InstructionComparator.InsnListSection)lists.get(0); + mv.instructions.insertBefore(subsection.first, new InsnNode(3)); + AbstractInsnNode insn = subsection.first; + + while(true) { + AbstractInsnNode next = insn.getNext(); + mv.instructions.remove(insn); + if (insn == subsection.last) { + return; + } + + insn = next; + } + } + } + } + ); + } + + if (!tweaks.getTag("softLeafReplace").setComment("If set to false, leaves will only replace air when growing").getBooleanValue(false)) { + alterMethod(new ASMHelper.MethodAltercator(new ObfuscationMappings.DescriptorMapping("amq", "canBeReplacedByLeaves", "(Lyc;III)Z")) { + public void alter(MethodNode mv) { + InsnList replacement = new InsnList(); + replacement.add(new VarInsnNode(25, 0)); + replacement.add(new VarInsnNode(25, 1)); + replacement.add(new VarInsnNode(21, 2)); + replacement.add(new VarInsnNode(21, 3)); + replacement.add(new VarInsnNode(21, 4)); + replacement.add(new ObfuscationMappings.DescriptorMapping("amq", "isAirBlock", "(Lyc;III)Z").toInsn(182)); + replacement.add(new InsnNode(172)); + mv.instructions = replacement; + } + }); + } + + if (tweaks.getTag("doFireTickOut") + .setComment("If set to true and doFireTick is disabed in the game rules, fire will still dissipate if it's not over a fire source") + .getBooleanValue(true)) { + alterMethod( + new ASMHelper.MethodAltercator(new ObfuscationMappings.DescriptorMapping("akf", "b", "(Lyc;IIILjava/util/Random;)V")) { + public void alter(MethodNode mv) { + InsnList needle = new InsnList(); + needle.add(new LdcInsnNode("doFireTick")); + needle.add(new ObfuscationMappings.DescriptorMapping("xz", "b", "(Ljava/lang/String;)Z").toInsn(182)); + needle.add(new JumpInsnNode(153, new LabelNode())); + List lists = InstructionComparator.insnListFindL(mv.instructions, needle); + if (lists.size() != 1) { + throw new RuntimeException( + "Needle found " + lists.size() + " times in Haystack: " + mv.instructions + "\n" + ASMHelper.printInsnList(needle) + ); + } else { + InstructionComparator.InsnListSection subsection = (InstructionComparator.InsnListSection)lists.get(0); + LabelNode jlabel = ((JumpInsnNode)subsection.last).label; + LabelNode ret = new LabelNode(); + mv.instructions.insertBefore(jlabel, new JumpInsnNode(167, ret)); + InsnList inject = new InsnList(); + inject.add(new VarInsnNode(25, 1)); + inject.add(new VarInsnNode(21, 2)); + inject.add(new VarInsnNode(21, 3)); + inject.add(new VarInsnNode(21, 4)); + inject.add(new VarInsnNode(25, 5)); + inject.add( + new ObfuscationMappings.DescriptorMapping("codechicken/core/featurehack/TweakTransformerHelper", "quenchFireTick", "(Lyc;IIILjava/util/Random;)V").toInsn(184) + ); + inject.add(ret); + mv.instructions.insert(jlabel, inject); + } + } + } + ); + } + } +} diff --git a/mod-compat/src/main/resources/fabricated-forge.mods.mixins.json b/mod-compat/src/main/resources/fabricated-forge.mods.mixins.json index 0cca9ded..b1a01d82 100644 --- a/mod-compat/src/main/resources/fabricated-forge.mods.mixins.json +++ b/mod-compat/src/main/resources/fabricated-forge.mods.mixins.json @@ -11,6 +11,7 @@ "codechickencore.ClassOverriderMixin", "codechickencore.DescriptorMappingMixin", "codechickencore.FeatureHackTransformerMixin", + "codechickencore.TweakTransformerMixin", "nei.FurnaceRecipeHandlerMixin", "nei.NEITransformerMixin", "nei.TMIUninstallerMixin" diff --git a/src/main/java/cpw/mods/fml/common/asm/transformers/AccessTransformer.java b/src/main/java/cpw/mods/fml/common/asm/transformers/AccessTransformer.java index 4eb39723..a3af727d 100644 --- a/src/main/java/cpw/mods/fml/common/asm/transformers/AccessTransformer.java +++ b/src/main/java/cpw/mods/fml/common/asm/transformers/AccessTransformer.java @@ -96,12 +96,12 @@ public boolean processLine(String input) throws IOException { String nameReference = descriptor.get(1); int parenIdx = nameReference.indexOf(40); if (parenIdx > 0) { - Pair o = Constants.getRemappedMethodNameNative(className, + Pair o = Constants.getRemappedMethodName(className, nameReference.substring(0, parenIdx), nameReference.substring(parenIdx)); m.desc = o.second(); m.name = o.first(); } else { - m.name = Constants.getRemappedFieldNameNative(className, nameReference); + m.name = Constants.getRemappedFieldName(className, nameReference); } } diff --git a/src/main/java/fr/catcore/fabricatedforge/Constants.java b/src/main/java/fr/catcore/fabricatedforge/Constants.java index 3d9061ce..6b8e748d 100644 --- a/src/main/java/fr/catcore/fabricatedforge/Constants.java +++ b/src/main/java/fr/catcore/fabricatedforge/Constants.java @@ -1,19 +1,13 @@ package fr.catcore.fabricatedforge; -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.MappingResolver; -import net.fabricmc.loader.impl.launch.FabricLauncherBase; -import net.fabricmc.mapping.tree.ClassDef; -import net.fabricmc.mapping.tree.FieldDef; -import net.fabricmc.mapping.tree.MethodDef; +import fr.catcore.modremapperapi.impl.lib.mappingio.tree.MappingTreeView; +import fr.catcore.modremapperapi.utils.MappingsUtils; import net.fabricmc.tinyremapper.extension.mixin.common.data.Pair; import org.objectweb.asm.Type; import java.io.File; import java.util.Objects; -import static fr.catcore.modremapperapi.remapping.RemapUtil.getNativeNamespace; - public class Constants { public static final String FORGE_URL = "https://maven.minecraftforge.net/net/minecraftforge/forge/1.4.6-6.5.0.489/forge-1.4.6-6.5.0.489-universal.zip"; @@ -26,85 +20,213 @@ public class Constants { } public static Pair getRemappedMethodNameNative(String owner, String methodName, String argDesc) { - MappingResolver resolver = FabricLoader.getInstance().getMappingResolver(); - - for(ClassDef def : FabricLauncherBase.getLauncher().getMappingConfiguration().getMappings().getClasses()) { - if (def.getName(getNativeNamespace()).replace(".", "/").equals(owner.replace(".", "/"))) { - for(MethodDef methodDef : def.getMethods()) { - if (Objects.equals(methodDef.getName(getNativeNamespace()), methodName)) { - String methodDescriptor = methodDef.getDescriptor(getNativeNamespace()); - if (methodDescriptor.startsWith(argDesc)) { - return Pair.of(methodDef.getName(resolver.getCurrentRuntimeNamespace()), methodDef.getDescriptor(resolver.getCurrentRuntimeNamespace())); + return getRemappedMethodName( + getRemappedClassName(owner), + methodName, argDesc + ); + } + + public static Pair getRemappedMethodName(String owner, String methodName, String argDesc) { + try { + return getRemappedMethodName( + Class.forName(owner.replace("/", "."), false, Constants.class.getClassLoader()), + methodName, argDesc + ); + } catch (Exception e) { + MappingTreeView.ClassMappingView classView = MappingsUtils.getMinecraftMappings().getClass(owner.replace(".", "/"), getTargetNamespace()); + + if (classView != null) { + MappingTreeView.MethodMappingView methodView = classView.getMethod(methodName, argDesc, getSrcNamespace()); + + if (methodView != null) { + return Pair.of(methodView.getName(getTargetNamespace()), methodView.getDesc(getTargetNamespace())); + } + + for (MappingTreeView.MethodMappingView methodViews : classView.getMethods()) { + if (methodViews.getName(getSrcNamespace()).equals(methodName)) { + if (methodViews.getDesc(getSrcNamespace()).equals(argDesc)) { + return Pair.of(methodViews.getName(getTargetNamespace()), methodViews.getDesc(getTargetNamespace())); } } } } - } - return Pair.of(methodName, argDesc); + return Pair.of(methodName, argDesc); + } } - public static Pair getRemappedMethodName(String owner, String methodName, String argDesc) { - MappingResolver resolver = FabricLoader.getInstance().getMappingResolver(); - - for(ClassDef def : FabricLauncherBase.getLauncher().getMappingConfiguration().getMappings().getClasses()) { - if (def.getName(resolver.getCurrentRuntimeNamespace()).replace(".", "/").equals(owner.replace(".", "/"))) { - for(MethodDef methodDef : def.getMethods()) { - if (Objects.equals(methodDef.getName(getNativeNamespace()), methodName)) { - String methodDescriptor = methodDef.getDescriptor(getNativeNamespace()); - if (methodDescriptor.startsWith(argDesc)) { - return Pair.of(methodDef.getName(resolver.getCurrentRuntimeNamespace()), methodDef.getDescriptor(resolver.getCurrentRuntimeNamespace())); - } + public static Pair getRemappedMethodName(Class cl, String methodName, String argDesc) { + MappingTreeView.ClassMappingView classView = MappingsUtils.getMinecraftMappings().getClass(cl.getName().replace(".", "/"), getTargetNamespace()); + + if (classView != null) { + MappingTreeView.MethodMappingView methodView = classView.getMethod(methodName, argDesc, getSrcNamespace()); + + if (methodView != null) { + return Pair.of(methodView.getName(getTargetNamespace()), methodView.getDesc(getTargetNamespace())); + } + + for (MappingTreeView.MethodMappingView methodViews : classView.getMethods()) { + if (methodViews.getName(getSrcNamespace()).equals(methodName)) { + if (methodViews.getDesc(getSrcNamespace()).equals(argDesc)) { + return Pair.of(methodViews.getName(getTargetNamespace()), methodViews.getDesc(getTargetNamespace())); } } } } + for (Class interfaces : cl.getInterfaces()) { + Pair result = getRemappedMethodName(interfaces, methodName, argDesc); + + if (!methodName.equals(result.first()) || !argDesc.equals(result.second())) { + return result; + } + } + + if (cl.getSuperclass() != null) { + Pair result = getRemappedMethodName(cl.getSuperclass(), methodName, argDesc); + + if (!methodName.equals(result.first()) || !argDesc.equals(result.second())) { + return result; + } + } + return Pair.of(methodName, argDesc); } public static String getRemappedClassName(String name) { - MappingResolver resolver = FabricLoader.getInstance().getMappingResolver(); + return MappingsUtils.getMinecraftMappings() + .mapClassName(name.replace(".", "/"), getSrcNamespace(), getTargetNamespace()) + .replace("/", "."); + } - for(ClassDef def : FabricLauncherBase.getLauncher().getMappingConfiguration().getMappings().getClasses()) { - if (def.getName(getNativeNamespace()).replace(".", "/").equals(name.replace(".", "/"))) { - return def.getName(resolver.getCurrentRuntimeNamespace()).replace("/", "."); - } - } + public static int getSrcNamespace() { + return MappingsUtils.getMinecraftMappings().getNamespaceId(MappingsUtils.getNativeNamespace()); + } - return name.replace("/", "."); + public static int getTargetNamespace() { + return MappingsUtils.getMinecraftMappings().getNamespaceId(MappingsUtils.getTargetNamespace()); } public static String getRemappedFieldNameNative(String owner, String fieldName) { - MappingResolver resolver = FabricLoader.getInstance().getMappingResolver(); + return getRemappedFieldName(getRemappedClassName(owner), fieldName); + } - for(ClassDef def : FabricLauncherBase.getLauncher().getMappingConfiguration().getMappings().getClasses()) { - if (def.getName(getNativeNamespace()).replace(".", "/").equals(owner.replace(".", "/"))) { - for(FieldDef fieldDef : def.getFields()) { - if (Objects.equals(fieldDef.getName(getNativeNamespace()), fieldName)) { - return fieldDef.getName(resolver.getCurrentRuntimeNamespace()); + public static String getRemappedFieldName(String owner, String fieldName) { + try { + return getRemappedField( + Class.forName(owner.replace("/", "."), false, Constants.class.getClassLoader()), + fieldName + ); + } catch (Exception e) { + MappingTreeView.ClassMappingView classView = MappingsUtils.getMinecraftMappings().getClass(owner.replace(".", "/"), getTargetNamespace()); + + if (classView != null) { + for (MappingTreeView.FieldMappingView fieldViews : classView.getFields()) { + if (fieldViews.getName(getSrcNamespace()).equals(fieldName)) { + return fieldViews.getName(getTargetNamespace()); } } } - } - return fieldName; + return fieldName; + } } public static Pair getRemappedFieldName(String owner, String fieldName, String fieldDesc) { - MappingResolver resolver = FabricLoader.getInstance().getMappingResolver(); + try { + return getRemappedField( + Class.forName(owner.replace("/", "."), false, Constants.class.getClassLoader()), + fieldName, fieldDesc + ); + } catch (Exception e) { + MappingTreeView.ClassMappingView classView = MappingsUtils.getMinecraftMappings().getClass(owner.replace(".", "/"), getTargetNamespace()); + + if (classView != null) { + MappingTreeView.FieldMappingView methodView = classView.getField(fieldName, fieldDesc, getSrcNamespace()); + + if (methodView != null) { + return Pair.of(methodView.getName(getTargetNamespace()), methodView.getDesc(getTargetNamespace())); + } + + for (MappingTreeView.FieldMappingView fieldViews : classView.getFields()) { + if (fieldViews.getName(getSrcNamespace()).equals(fieldName)) { + if (fieldViews.getDesc(getSrcNamespace()).equals(fieldDesc)) { + return Pair.of(fieldViews.getName(getTargetNamespace()), fieldViews.getDesc(getTargetNamespace())); + } + } + } + } - for(ClassDef def : FabricLauncherBase.getLauncher().getMappingConfiguration().getMappings().getClasses()) { - if (def.getName(resolver.getCurrentRuntimeNamespace()).replace(".", "/").equals(owner.replace(".", "/"))) { - for(FieldDef fieldDef : def.getFields()) { - if (Objects.equals(fieldDef.getName(getNativeNamespace()), fieldName)) { - return Pair.of(fieldDef.getName(resolver.getCurrentRuntimeNamespace()), fieldDef.getDescriptor(resolver.getCurrentRuntimeNamespace())); + return Pair.of(fieldName, fieldDesc); + } + } + + public static Pair getRemappedField(Class cl, String fieldName, String argDesc) { + MappingTreeView.ClassMappingView classView = MappingsUtils.getMinecraftMappings().getClass(cl.getName().replace(".", "/"), getTargetNamespace()); + + if (classView != null) { + MappingTreeView.FieldMappingView methodView = classView.getField(fieldName, argDesc, getSrcNamespace()); + + if (methodView != null) { + return Pair.of(methodView.getName(getTargetNamespace()), methodView.getDesc(getTargetNamespace())); + } + + for (MappingTreeView.FieldMappingView fieldViews : classView.getFields()) { + if (fieldViews.getName(getSrcNamespace()).equals(fieldName)) { + if (fieldViews.getDesc(getSrcNamespace()).equals(argDesc)) { + return Pair.of(fieldViews.getName(getTargetNamespace()), fieldViews.getDesc(getTargetNamespace())); } } } } - return Pair.of(fieldName, fieldDesc); + for (Class interfaces : cl.getInterfaces()) { + Pair result = getRemappedField(interfaces, fieldName, argDesc); + + if (!fieldName.equals(result.first()) || !argDesc.equals(result.second())) { + return result; + } + } + + if (cl.getSuperclass() != null) { + Pair result = getRemappedField(cl.getSuperclass(), fieldName, argDesc); + + if (!fieldName.equals(result.first()) || !argDesc.equals(result.second())) { + return result; + } + } + + return Pair.of(fieldName, argDesc); + } + + public static String getRemappedField(Class cl, String fieldName) { + MappingTreeView.ClassMappingView classView = MappingsUtils.getMinecraftMappings().getClass(cl.getName().replace(".", "/"), getTargetNamespace()); + + if (classView != null) { + for (MappingTreeView.FieldMappingView fieldViews : classView.getFields()) { + if (fieldViews.getName(getSrcNamespace()).equals(fieldName)) { + return fieldViews.getName(getTargetNamespace()); + } + } + } + + for (Class interfaces : cl.getInterfaces()) { + String result = getRemappedField(cl.getSuperclass(), fieldName); + + if (!fieldName.equals(result)) { + return result; + } + } + + if (cl.getSuperclass() != null) { + String result = getRemappedField(cl.getSuperclass(), fieldName); + + if (!fieldName.equals(result)) { + return result; + } + } + + return fieldName; } public static String remapMethodDescriptor(String desc) {