Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Fabric API 0.86.0+ #1179

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ compileJava {
classes += ['net/minecraft/class_5944': 'net/minecraft/class_5944']
method 'net/minecraft/class_5944', '(Lnet/minecraft/class_5912;Lnet/minecraft/util/Identifier;Lnet/minecraft/client/render/VertexFormat;)V', '<init>', '<init>'
method 'net/minecraft/client/gui/screen/Screen', '(Lnet/minecraft/class_332;IIF)V', 'renderWithTooltip', 'method_47413'
classes += ['net/minecraft/client/render/model/Baker': 'net/minecraft/class_7775']
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package me.modmuss50.optifabric.compat.fabricmodelloadingapi;

import me.modmuss50.optifabric.compat.InterceptingMixinPlugin;
import me.modmuss50.optifabric.util.MixinUtils;
import me.modmuss50.optifabric.util.RemappingUtils;
import net.fabricmc.tinyremapper.IMappingProvider.Member;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.*;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import org.spongepowered.asm.mixin.transformer.ClassInfo;

public class ModelLoadingMixinPlugin extends InterceptingMixinPlugin {
@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
// not doing this will cause Mixin to have a stroke while trying to find where to put the fabric injectors
ClassInfo info = ClassInfo.forName(targetClassName);
MixinUtils.completeClassInfo(info, targetClass.methods);
String bakeDesc = "(Lnet/minecraft/class_2960;Lnet/minecraft/class_3665;)Lnet/minecraft/class_1087;";//(Identifier, ModelBakeSettings)BakedModel
String bake = RemappingUtils.getMethodName("class_7775", "method_45873", bakeDesc);//BakerImpl, bake
bakeDesc = RemappingUtils.mapMethodDescriptor(bakeDesc);
if ("ModelLoaderBakerImplMixin".equals(mixinInfo.getName())) {
for (MethodNode method : targetClass.methods) {
if (bake.equals(method.name) && bakeDesc.equals(method.desc)) {
//This is the @ModifyVariable
//target = "Lnet/minecraft/client/render/model/ModelLoader$BakerImpl;getOrLoadModel(Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/render/model/UnbakedModel;"
Member mfMixinTarget = RemappingUtils.mapMethod("class_1088$class_7778", "method_45872", "(Lnet/minecraft/class_2960;)Lnet/minecraft/class_1100;");
LabelNode fakeStart = new LabelNode();
LabelNode skip = new LabelNode();
InsnList extraFirst = new InsnList();

/*
The following line doesn't work because why would it work (it does in OriginMixinPlugin)
so I have to resort to using postApply and remove this trash code
*/
// extra.add(new JumpInsnNode(Opcodes.GOTO, skip));
extraFirst.add(fakeStart);
extraFirst.add(new InsnNode(Opcodes.ACONST_NULL));
extraFirst.add(new InsnNode(Opcodes.ACONST_NULL));
extraFirst.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, mfMixinTarget.owner, mfMixinTarget.name, mfMixinTarget.desc));
extraFirst.add(new VarInsnNode(Opcodes.ASTORE, 3));
extraFirst.add(skip);

method.localVariables.add(new LocalVariableNode("fakeUnbakedModel", "L" + RemappingUtils.getClassName("class_1087") + ";", null, fakeStart, skip, 3));
method.instructions.insertBefore(method.instructions.getFirst(), extraFirst);
method.maxLocals += 1;

//This part takes care of the two @Redirect
//target = "Lnet/minecraft/client/render/model/UnbakedModel;bake(Lnet/minecraft/client/render/model/Baker;Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/render/model/BakedModel;"
Member redirectMixinTarget1 = RemappingUtils.mapMethod("class_1100", "method_4753", "(Lnet/minecraft/class_7775;Ljava/util/function/Function;Lnet/minecraft/class_3665;Lnet/minecraft/class_2960;)Lnet/minecraft/class_1087;");
//target = "Lnet/minecraft/client/render/model/json/JsonUnbakedModel;bake(Lnet/minecraft/client/render/model/Baker;Lnet/minecraft/client/render/model/json/JsonUnbakedModel;Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;Lnet/minecraft/util/Identifier;Z)Lnet/minecraft/client/render/model/BakedModel;"
Member redirectMixinTarget2 = RemappingUtils.mapMethod("class_793", "method_3446", "(Lnet/minecraft/class_7775;Lnet/minecraft/class_793;Ljava/util/function/Function;Lnet/minecraft/class_3665;Lnet/minecraft/class_2960;Z)Lnet/minecraft/class_1087;");
LabelNode skipLast = new LabelNode();
InsnList extraLast = new InsnList();
// this works because funny (and because no local variable is involved)
extraLast.add(new JumpInsnNode(Opcodes.GOTO, skipLast));
extraLast.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, redirectMixinTarget1.owner, redirectMixinTarget1.name, redirectMixinTarget1.desc));
extraLast.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, redirectMixinTarget2.owner, redirectMixinTarget2.name, redirectMixinTarget2.desc));
extraLast.add(skipLast);
method.instructions.insertBefore(method.instructions.getLast(), extraLast);
break;
}
}
}

super.preApply(targetClassName, targetClass, mixinClassName, mixinInfo);
}

@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
String bakeDesc = "(Lnet/minecraft/class_2960;Lnet/minecraft/class_3665;)Lnet/minecraft/class_1087;";
String bake = RemappingUtils.getMethodName("class_7775", "method_45873", bakeDesc);
bakeDesc = RemappingUtils.mapMethodDescriptor(bakeDesc);

if ("ModelLoaderBakerImplMixin".equals(mixinInfo.getName())) {
out: for (MethodNode method : targetClass.methods) {
if (bake.equals(method.name) && bakeDesc.equals(method.desc)) {
LocalVariableNode fakeUnbakedModel = method.localVariables.get(3);
method.localVariables.remove(fakeUnbakedModel);
method.maxLocals -= 1;
// remove trash
for (AbstractInsnNode insn : method.instructions) {
method.instructions.remove(insn);
System.out.println(insn);
if (fakeUnbakedModel.end.equals(insn)) {
break out;
}
}
}
}
}
super.postApply(targetClassName, targetClass, mixinClassName, mixinInfo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package me.modmuss50.optifabric.compat.fabricmodelloadingapi.mixin;

import me.modmuss50.optifabric.compat.InterceptingMixin;
import me.modmuss50.optifabric.compat.Shim;
import net.minecraft.class_7775;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.render.model.json.JsonUnbakedModel;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.Redirect;

import java.util.function.Function;

@Mixin(targets = "net/minecraft/class_1088$class_7778")
@InterceptingMixin("net/fabricmc/fabric/mixin/client/model/loading/ModelLoaderBakerImplMixin")
abstract class ModelLoaderBakerImplMixin {
@Shim private native UnbakedModel invokeModifyBeforeBake(UnbakedModel model, Identifier id, ModelBakeSettings settings);

@ModifyVariable(method = "bake", remap = false,
at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/class_1088$class_7778;method_45872(Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/render/model/UnbakedModel;", remap = true))
private UnbakedModel invokeModifyBeforeBake(UnbakedModel model, Identifier id, ModelBakeSettings settings, Function<?, ?> sprites) {
return invokeModifyBeforeBake(model, id, settings);
}

@Shim
private native BakedModel invokeModifyAfterBake(UnbakedModel unbakedModel, class_7775 baker, Function<SpriteIdentifier, Sprite> textureGetter, ModelBakeSettings settings, Identifier id);

@Redirect(method = "bake", remap = false,
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/UnbakedModel;method_4753(Lnet/minecraft/client/render/model/Baker;Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/render/model/BakedModel;", remap = true))
private BakedModel optifabric_invokeModifyAfterBake(UnbakedModel unbakedModel, class_7775 baker, Function<SpriteIdentifier, Sprite> textureGetter, ModelBakeSettings settings, Identifier id) {
return invokeModifyAfterBake(unbakedModel, baker, textureGetter, settings, id);
}


@Shim private native BakedModel invokeModifyAfterBake(JsonUnbakedModel unbakedModel, class_7775 baker, JsonUnbakedModel parent, Function<SpriteIdentifier, Sprite> textureGetter, ModelBakeSettings settings, Identifier id, boolean hasDepth);

@Redirect(method = "bake", remap = false,
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/json/JsonUnbakedModel;method_3446(Lnet/minecraft/client/render/model/Baker;Lnet/minecraft/client/render/model/json/JsonUnbakedModel;Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;Lnet/minecraft/util/Identifier;Z)Lnet/minecraft/client/render/model/BakedModel;", remap = true))
private BakedModel optifabric_invokeModifyAfterBake(JsonUnbakedModel unbakedModel, class_7775 baker, JsonUnbakedModel parent, Function<SpriteIdentifier, Sprite> textureGetter, ModelBakeSettings settings, Identifier id, boolean hasDepth) {
return invokeModifyAfterBake(unbakedModel, baker, parent, textureGetter, settings, id, hasDepth);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ protected boolean isPresent() {
Mixins.addConfiguration("optifabric.compat.fabric-lifecycle-events.new-mixins.json");
}

if (isPresent("fabric-model-loading-api-v1")) {
Mixins.addConfiguration("optifabric.compat.fabric-model-loading-api.mixins.json");
}

Mixins.addConfiguration("optifabric.optifine.mixins.json");
if (OptifabricSetup.isPresent("minecraft", "<=1.19.2")) {
Mixins.addConfiguration("optifabric.optifine.old-mixins.json");
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/me/modmuss50/optifabric/mod/OptifineSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,12 @@ private static IMappingProvider createMappings(String from, String to, IMappingP
ClassDef builtChunk = nameToClass.get("net/minecraft/class_846$class_851");
extraFields.put(new Member(rebuildTask.getName(from), "this$1", 'L' + builtChunk.getName(from) + ';'), "field_20839");

ClassDef bakerImpl = nameToClass.get("net/minecraft/class_1088$class_7778");
if (bakerImpl != null) {//Only present in 1.19.3+
ClassDef modelLoader = nameToClass.get("net/minecraft/class_1088");
extraFields.put(new Member(bakerImpl.getName(from), "this$0", 'L' + modelLoader.getName(from) + ';'), "field_40571");
}

ClassDef particleManager = nameToClass.get("net/minecraft/class_702");
particleManager.getFields().stream().filter(field -> "field_3835".equals(field.getName("intermediary"))).forEach(field -> {
extraFields.put(new Member(particleManager.getName(from), field.getName(from), "Ljava/util/Map;"), field.getName(to));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"parent": "optifabric.mixins.json",
"package": "me.modmuss50.optifabric.compat.fabricmodelloadingapi.mixin",
"plugin": "me.modmuss50.optifabric.compat.fabricmodelloadingapi.ModelLoadingMixinPlugin",
"mixins": [
"ModelLoaderBakerImplMixin"
]
}
4 changes: 4 additions & 0 deletions src/shim/java/net/minecraft/class_7775.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package net.minecraft;

public interface class_7775 {
}
Loading