diff options
Diffstat (limited to 'src/main/java/moe/nea')
3 files changed, 129 insertions, 0 deletions
diff --git a/src/main/java/moe/nea/firmament/init/EarlyRiser.java b/src/main/java/moe/nea/firmament/init/EarlyRiser.java new file mode 100644 index 0000000..268e3f3 --- /dev/null +++ b/src/main/java/moe/nea/firmament/init/EarlyRiser.java @@ -0,0 +1,78 @@ +/* + * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe> + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package moe.nea.firmament.init; + +import me.shedaniel.mm.api.ClassTinkerers; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.MappingResolver; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import java.lang.reflect.Modifier; +import java.util.Objects; + +public class EarlyRiser implements Runnable { + MappingResolver remapper = FabricLoader.getInstance().getMappingResolver(); + String PlayerEntity = remapper.mapClassName("intermediary", "net.minecraft.class_1657"); + String World = remapper.mapClassName("intermediary", "net.minecraft.class_1937"); + String GameProfile = "com.mojang.authlib.GameProfile"; + String BlockPos = remapper.mapClassName("intermediary", "net.minecraft.class_2338"); + String AbstractClientPlayerEntity = remapper.mapClassName("intermediary", "net.minecraft.class_742"); + String GuiPlayer = "moe.nea.firmament.gui.entity.GuiPlayer"; + // World world, BlockPos pos, float yaw, GameProfile gameProfile + Type constructorDescriptor = Type.getMethodType(Type.VOID_TYPE, getTypeForClassName(World), getTypeForClassName(BlockPos), Type.FLOAT_TYPE, getTypeForClassName(GameProfile)); + + @Override + public void run() { + ClassTinkerers.addTransformation(AbstractClientPlayerEntity, it -> mapClassNode(it, getTypeForClassName(PlayerEntity))); + ClassTinkerers.addTransformation(GuiPlayer, it -> mapClassNode(it, getTypeForClassName(AbstractClientPlayerEntity))); + } + + private void mapClassNode(ClassNode classNode, Type superClass) { + for (MethodNode method : classNode.methods) { + if (Objects.equals(method.name, "<init>") && Type.getMethodType(method.desc).equals(constructorDescriptor)) { + modifyConstructor(method, superClass); + return; + } + } + var node = new MethodNode(Opcodes.ASM9, "<init>", constructorDescriptor.getDescriptor(), null, null); + classNode.methods.add(node); + modifyConstructor(node, superClass); + } + + private Type getTypeForClassName(String className) { + return Type.getObjectType(className.replace('.', '/')); + } + + private void modifyConstructor(MethodNode method, Type superClass) { + method.access = (method.access | Modifier.PUBLIC) & ~Modifier.PRIVATE & ~Modifier.PROTECTED; + if (method.instructions.size() != 0) return; // Some other mod has already made a constructor here + + // World world, BlockPos pos, float yaw, GameProfile gameProfile + // ALOAD this + method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); + + // ALOAD World + method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); + + // ALOAD BlockPos + method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 2)); + + // ALOAD yaw + method.instructions.add(new VarInsnNode(Opcodes.FLOAD, 3)); + + // ALOAD gameProfile + method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 4)); + + // Call super + method.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, superClass.getInternalName(), "<init>", constructorDescriptor.getDescriptor(), false)); + + // Return + method.instructions.add(new InsnNode(Opcodes.RETURN)); + } +} diff --git a/src/main/java/moe/nea/firmament/mixins/AppendRepoAsResourcePack.java b/src/main/java/moe/nea/firmament/mixins/AppendRepoAsResourcePack.java new file mode 100644 index 0000000..729b9b8 --- /dev/null +++ b/src/main/java/moe/nea/firmament/mixins/AppendRepoAsResourcePack.java @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe> + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package moe.nea.firmament.mixins; + +import moe.nea.firmament.repo.RepoModResourcePack; +import net.fabricmc.fabric.api.resource.ModResourcePack; +import net.fabricmc.fabric.impl.resource.loader.ModResourcePackUtil; +import net.minecraft.resource.ResourceType; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; + +@Mixin(ModResourcePackUtil.class) +public class AppendRepoAsResourcePack { + @Inject(method = "appendModResourcePacks", at = @At("TAIL")) + private static void onAppendModResourcePack( + List<ModResourcePack> packs, + ResourceType type, + @Nullable String subPath, + CallbackInfo ci + ) { + RepoModResourcePack.Companion.append(packs); + } + +} diff --git a/src/main/java/moe/nea/firmament/mixins/accessor/AccessorAbstractClientPlayerEntity.java b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorAbstractClientPlayerEntity.java new file mode 100644 index 0000000..efa4a56 --- /dev/null +++ b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorAbstractClientPlayerEntity.java @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe> + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package moe.nea.firmament.mixins.accessor; + +import net.minecraft.client.network.AbstractClientPlayerEntity; +import net.minecraft.client.network.PlayerListEntry; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(AbstractClientPlayerEntity.class) +public interface AccessorAbstractClientPlayerEntity { + @Accessor("playerListEntry") + void setPlayerListEntry_firmament(PlayerListEntry playerListEntry); +} |