From d2132e696402191993193bf77d1bdcc50f7fe843 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Wed, 17 Apr 2024 01:41:44 +0700 Subject: [PATCH] Use TinyRemapper to remap fields and methods to mojmap. --- CHANGELOG.md | 2 - build.gradle | 1 + gradle.properties | 1 + .../melontini/commander/impl/Commander.java | 17 ++++- .../impl/util/mappings/MappingKeeper.java | 74 +++++++++++++++---- 5 files changed, 77 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 657ab40..828beda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,8 +16,6 @@ New: ``` /say hi ${{this_entity.getX}} -/say hi ${{this_entity.server.getModStatus.confidence}} - /say hi ${{round(sqrt(abs(world.getSeed)), 0)}} ``` diff --git a/build.gradle b/build.gradle index ffb016d..001540c 100644 --- a/build.gradle +++ b/build.gradle @@ -71,6 +71,7 @@ dependencies { implementation shade("com.ezylang:EvalEx:${project.evalex_version}") implementation shade("net.fabricmc:mapping-io:${project.mappingio_version}") + implementation shade("net.fabricmc:tiny-remapper:${tiny_remapper_version}") } loom { diff --git a/gradle.properties b/gradle.properties index 446a344..a6fe33a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,4 +14,5 @@ archives_base_name=commander fabric_version=0.92.0+1.20.1 dark_matter=4.0.0-1.20.1-build.481 evalex_version=3.2.0 +tiny_remapper_version=0.9.0 mappingio_version=0.6.0 diff --git a/src/main/java/me/melontini/commander/impl/Commander.java b/src/main/java/me/melontini/commander/impl/Commander.java index c23599a..f01cb9d 100644 --- a/src/main/java/me/melontini/commander/impl/Commander.java +++ b/src/main/java/me/melontini/commander/impl/Commander.java @@ -2,6 +2,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import lombok.Getter; import lombok.extern.log4j.Log4j2; import me.melontini.commander.api.expression.Arithmetica; import me.melontini.commander.api.expression.LootContextParameterRegistry; @@ -20,13 +21,14 @@ import me.melontini.dark_matter.api.data.loading.ServerReloadersEvent; import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.tinyremapper.IMappingProvider; +import net.fabricmc.tinyremapper.TinyRemapper; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.entity.damage.DamageSource; import net.minecraft.item.ItemStack; import net.minecraft.loot.provider.number.LootNumberProviderType; import net.minecraft.loot.provider.number.LootNumberProviderTypes; -import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; @@ -54,6 +56,9 @@ public class Commander implements ModInitializer { public static final Path COMMANDER_PATH = FabricLoader.getInstance().getGameDir().resolve(".commander"); public static final String MINECRAFT_VERSION = getVersion(); + @Getter + private static TinyRemapper remapper; + public static Identifier id(String path) { return new Identifier("commander", path); } @@ -73,7 +78,13 @@ public void onInitialize() { ServerReloadersEvent.EVENT.register(context -> context.register(new DynamicEventManager())); EvalUtils.init(); MinecraftDownloader.downloadMappings(); - MappingKeeper.getMojmapTarget(); + + IMappingProvider provider = MappingKeeper.create(MappingKeeper.getMojmapTarget(), MappingKeeper.NAMESPACE, "mojang"); + remapper = TinyRemapper.newRemapper() + .renameInvalidLocals(false) + .withMappings(provider) + .build(); + remapper.readInputs(remapper.createInputTag(), FabricLoader.getInstance().getModContainer("minecraft").orElseThrow().getOrigin().getPaths().toArray(Path[]::new)); log.info("Scanning common context classes!"); Util.getMainWorkerExecutor().submit(() -> { @@ -82,7 +93,7 @@ public void onInitialize() { Vec3d.class, BlockPos.class, BlockState.class, BlockEntity.class, ItemStack.class, DamageSource.class, - ServerWorld.class, MinecraftServer.class + ServerWorld.class ).forEach(aClass -> { do { ReflectiveMapStructure.getAccessors(aClass); diff --git a/src/main/java/me/melontini/commander/impl/util/mappings/MappingKeeper.java b/src/main/java/me/melontini/commander/impl/util/mappings/MappingKeeper.java index 9d04ce3..863e2ab 100644 --- a/src/main/java/me/melontini/commander/impl/util/mappings/MappingKeeper.java +++ b/src/main/java/me/melontini/commander/impl/util/mappings/MappingKeeper.java @@ -7,7 +7,10 @@ import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.mappingio.MappingReader; import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; +import net.fabricmc.mappingio.tree.MappingTree; +import net.fabricmc.mappingio.tree.MappingTreeView; import net.fabricmc.mappingio.tree.MemoryMappingTree; +import net.fabricmc.tinyremapper.IMappingProvider; import org.objectweb.asm.Type; import java.io.InputStreamReader; @@ -19,7 +22,7 @@ @Log4j2 public final class MappingKeeper { - private static final String NAMESPACE = FabricLoader.getInstance().getMappingResolver().getCurrentRuntimeNamespace(); + public static final String NAMESPACE = FabricLoader.getInstance().getMappingResolver().getCurrentRuntimeNamespace(); @Getter(lazy = true) private static final MemoryMappingTree offMojmap = loadOffMojmap(); @@ -60,20 +63,65 @@ public static MemoryMappingTree loadOffTarget() { } public static String toNamed(Field field) { - int id = getMojmapTarget().getNamespaceId(NAMESPACE); - var cls = getMojmapTarget().getClass(Type.getInternalName(field.getDeclaringClass()), id); - if (cls == null) return field.getName(); - var fld = cls.getField(field.getName(), Type.getDescriptor(field.getType()), id); - if (fld == null) return field.getName(); - return fld.getName("mojang"); + return Commander.getRemapper().getEnvironment().getRemapper().mapFieldName(Type.getInternalName(field.getDeclaringClass()), field.getName(), Type.getDescriptor(field.getType())); } public static String toNamed(Method method) { - int id = getMojmapTarget().getNamespaceId(NAMESPACE); - var cls = getMojmapTarget().getClass(Type.getInternalName(method.getDeclaringClass()), id); - if (cls == null) return method.getName(); - var mthd = cls.getMethod(method.getName(), Type.getMethodDescriptor(method), id); - if (mthd == null) return method.getName(); - return mthd.getName("mojang"); + return Commander.getRemapper().getEnvironment().getRemapper().mapMethodName(Type.getInternalName(method.getDeclaringClass()), method.getName(), Type.getMethodDescriptor(method)); + } + + private static IMappingProvider.Member memberOf(String className, String memberName, String descriptor) { + return new IMappingProvider.Member(className, memberName, descriptor); + } + + public static IMappingProvider create(MappingTree first, String from, String to) { + return (acceptor) -> { + int fromId = first.getNamespaceId(from); + int toId = first.getNamespaceId(to); + + for (MappingTree.ClassMapping classDef : first.getClasses()) { + String className = classDef.getName(fromId); + if (className == null) continue; + + String dstName = getName(classDef, toId, fromId); + + acceptor.acceptClass(className, dstName); + for (MappingTree.FieldMapping field : classDef.getFields()) { + var fieldId = memberOf(className, field.getName(fromId), field.getDesc(fromId)); + if (fieldId.name == null) continue; + + try { + acceptor.acceptField(fieldId, getName(field, toId, fromId)); + } catch (Exception e) { + throw new RuntimeException("from: %s to:%s cls:%s dstCls:%s field:%s fieldMth:%s" + .formatted(from, to, className, dstName, fieldId.name, getName(field, toId, fromId))); + } + } + + for (MappingTree.MethodMapping method : classDef.getMethods()) { + var methodIdentifier = memberOf(className, method.getName(fromId), method.getDesc(fromId)); + if (methodIdentifier.name == null) continue; + + try { + acceptor.acceptMethod(methodIdentifier, getName(method, toId, fromId)); + } catch (Exception e) { + throw new RuntimeException("from: %s to:%s cls:%s dstCls:%s mth:%s dstMth:%s" + .formatted(from, to, className, dstName, methodIdentifier.name, getName(method, toId, fromId))); + } + } + } + }; + } + + private static String getName(MappingTree.ClassMapping classDef, int id, int fallback) { + var s = classDef.getName(id); + if (s != null) return s; + return classDef.getName(fallback); + } + + public static String getName(MappingTreeView.MemberMappingView method, int id, int fallback) { + var s = method.getName(id); + if (s != null) return s; + return method.getName(fallback); } }