From c9aaaeed770efcc53992038c08ac188ee27d1671 Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Sun, 8 Sep 2024 20:51:26 +0200 Subject: Fix cit resewn --- build.gradle.kts | 6 +- citresewn-defaults-1.2.0+1.21.jar | Bin 0 -> 224043 bytes gradle/libs.versions.toml | 5 ++ .../firmament/mixins/MixinConditionComponents.java | 83 +++++++++++++++++++++ .../custommodels/PatchHeadFeatureRenderer.java | 4 +- src/main/kotlin/util/ConditionNBTMixin.kt | 58 ++++++++++++++ src/main/resources/firmament.accesswidener | 1 + 7 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 citresewn-defaults-1.2.0+1.21.jar create mode 100644 src/main/java/moe/nea/firmament/mixins/MixinConditionComponents.java create mode 100644 src/main/kotlin/util/ConditionNBTMixin.kt diff --git a/build.gradle.kts b/build.gradle.kts index 1df163e..cb31469 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -163,6 +163,9 @@ val nonModImplentation by configurations.creating { configurations.implementation.get().extendsFrom(this) } +loom { +} + dependencies { // Minecraft dependencies "minecraft"(libs.minecraft) @@ -213,7 +216,7 @@ dependencies { nonModImplentation(libs.repoparser) shadowMe(libs.repoparser) fun ktor(mod: String) = "io.ktor:ktor-$mod-jvm:${libs.versions.ktor.get()}" - + modCompileOnly(libs.citresewn) transInclude(nonModImplentation(ktor("client-core"))!!) transInclude(nonModImplentation(ktor("client-java"))!!) transInclude(nonModImplentation(ktor("serialization-kotlinx-json"))!!) @@ -224,6 +227,7 @@ dependencies { // Dev environment preinstalled mods modLocalRuntime(libs.bundles.runtime.required) modLocalRuntime(libs.bundles.runtime.optional) + modImplementation(modLocalRuntime(project.files("citresewn-defaults-1.2.0+1.21.jar"))!!) modLocalRuntime(libs.jarvis.fabric) transInclude.resolvedConfiguration.resolvedArtifacts.forEach { diff --git a/citresewn-defaults-1.2.0+1.21.jar b/citresewn-defaults-1.2.0+1.21.jar new file mode 100644 index 0000000..c613fa9 Binary files /dev/null and b/citresewn-defaults-1.2.0+1.21.jar differ diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dd735bf..2f3c7cc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -43,6 +43,9 @@ explosiveenhancement = "1.2.3-1.21.0" # Update from https://modrinth.com/mod/not-enough-animations/versions?l=fabric notenoughanimations = "BQ8qstAV" +# Update from https://modrinth.com/mod/cit-resewn/versions?l=fabric +citresewn = "1.2.0+1.21" + devauth = "1.2.0" # Update from https://ktor.io/ @@ -104,6 +107,7 @@ qolify = { module = "maven.modrinth:qolify", version.ref = "qolify" } ncr = { module = "maven.modrinth:no-chat-reports", version.ref = "ncr" } sodium = { module = "maven.modrinth:sodium", version.ref = "sodium" } freecammod = { module = "maven.modrinth:freecam", version.ref = "freecammod" } +citresewn = { module = "maven.modrinth:cit-resewn", version.ref = "citresewn" } femalegender = { module = "maven.modrinth:female-gender", version.ref = "femalegender" } [bundles] @@ -120,6 +124,7 @@ runtime_optional = [ "sodium", # "qolify", "ncr", + "citresewn", ] [plugins] diff --git a/src/main/java/moe/nea/firmament/mixins/MixinConditionComponents.java b/src/main/java/moe/nea/firmament/mixins/MixinConditionComponents.java new file mode 100644 index 0000000..8c33a6c --- /dev/null +++ b/src/main/java/moe/nea/firmament/mixins/MixinConditionComponents.java @@ -0,0 +1,83 @@ +package moe.nea.firmament.mixins; + +// People are complaining but this really is not my place to fix things + +import com.llamalad7.mixinextras.sugar.Local; +import moe.nea.firmament.util.ConditionNBTMixin; +import net.minecraft.component.ComponentType; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.nbt.NbtString; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import shcm.shsupercm.fabric.citresewn.cit.CITContext; +import shcm.shsupercm.fabric.citresewn.defaults.cit.conditions.ConditionComponents; +import shcm.shsupercm.fabric.citresewn.defaults.cit.conditions.ConditionNBT; +import shcm.shsupercm.fabric.citresewn.pack.format.PropertyGroup; +import shcm.shsupercm.fabric.citresewn.pack.format.PropertyKey; +import shcm.shsupercm.fabric.citresewn.pack.format.PropertyValue; + +@Mixin(ConditionComponents.class) +@Pseudo +public class MixinConditionComponents { + @Shadow + private ComponentType componentType; + + @Shadow(remap = false) + private ConditionNBT fallbackNBTCheck; + @Unique + private String[] pathCheck; + @Unique + private int loreInt = -1; + + @Inject(method = "load", + at = @At(value = "INVOKE", remap = false, target = "Lshcm/shsupercm/fabric/citresewn/defaults/cit/conditions/ConditionNBT;loadNbtCondition(Lshcm/shsupercm/fabric/citresewn/pack/format/PropertyValue;Lshcm/shsupercm/fabric/citresewn/pack/format/PropertyGroup;[Ljava/lang/String;Ljava/lang/String;)V"), + remap = false) + private void onLoadSavePath(PropertyKey key, PropertyValue value, PropertyGroup properties, CallbackInfo ci, + @Local String[] path) { + this.pathCheck = path; + this.loreInt = -1; + } + + private boolean matchStringDirect(String directString, CITContext context) { + return ConditionNBTMixin.invokeDirectConditionNBTStringMatch(fallbackNBTCheck, directString); + } + + @Inject(method = "test", at = @At("HEAD"), cancellable = true, remap = false) + void fastPathDisplayName(CITContext context, CallbackInfoReturnable cir) { + if (this.componentType == DataComponentTypes.CUSTOM_NAME && pathCheck.length == 0) { + var displayName = context.stack.getComponents().get(DataComponentTypes.CUSTOM_NAME); + if (displayName != null) { + cir.setReturnValue(matchStringDirect((displayName.getString()), context)); + } + } + if (this.componentType == DataComponentTypes.LORE && pathCheck.length == 1) { + var lore = context.stack.getComponents().get(DataComponentTypes.LORE); + if (lore != null) { + var loreLines = lore.lines(); + if (pathCheck[0].equals("*")) { + for (var loreLine : loreLines) { + if (matchStringDirect((loreLine.getString()), context)) { + cir.setReturnValue(true); + return; + } + } + cir.setReturnValue(false); + } else { + if (loreInt < 0) + loreInt = Integer.parseInt(pathCheck[0]); + cir.setReturnValue(0 <= loreInt && loreInt < loreLines.size() && + matchStringDirect((loreLines.get(loreInt).getString()), context)); + } + } + } + } + + +} diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchHeadFeatureRenderer.java b/src/main/java/moe/nea/firmament/mixins/custommodels/PatchHeadFeatureRenderer.java index f791b13..610a106 100644 --- a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchHeadFeatureRenderer.java +++ b/src/main/java/moe/nea/firmament/mixins/custommodels/PatchHeadFeatureRenderer.java @@ -28,11 +28,11 @@ public class PatchHeadFeatureRenderer original, @Local ItemStack itemStack) { + private Block replaceSkull(BlockItem instance, Operation original, @Local ItemStack itemStack, @Local(argsOnly = true) T entity) { var oldBlock = original.call(instance); if (oldBlock instanceof AbstractSkullBlock) { var bakedModel = this.heldItemRenderer.itemRenderer - .getModel(itemStack, null, null, 0); + .getModel(itemStack, entity.getWorld(), entity, 0); if (bakedModel instanceof BakedModelExtra extra && extra.getHeadModel_firmament() != null) return Blocks.ENCHANTING_TABLE; // Any non skull block. Let's choose the enchanting table because it is very distinct. } diff --git a/src/main/kotlin/util/ConditionNBTMixin.kt b/src/main/kotlin/util/ConditionNBTMixin.kt new file mode 100644 index 0000000..cbc1e66 --- /dev/null +++ b/src/main/kotlin/util/ConditionNBTMixin.kt @@ -0,0 +1,58 @@ +package moe.nea.firmament.util + +import java.lang.invoke.MethodHandles +import java.util.function.BiPredicate +import java.util.function.Function +import shcm.shsupercm.fabric.citresewn.defaults.cit.conditions.ConditionNBT + +object ConditionNBTMixin { + class Helper { + + val stringMatcherType = ConditionNBT::class.java.getDeclaredField("matchString").type + + val accessMatcher = run { + val matchStringF = ConditionNBT::class.java.getDeclaredField("matchString"); + matchStringF.isAccessible = true + val l = MethodHandles.privateLookupIn(ConditionNBT::class.java, MethodHandles.lookup()) +// val mt = MethodType.methodType(stringMatcherType, ConditionNBT::class.java) +// val callsite = LambdaMetafactory.metafactory( +// l, "apply", +// MethodType.methodType(Function::class.java), +// MethodType.methodType(java.lang.Object::class.java, java.lang.Object::class.java), +// l.unreflectGetter(matchStringF), +// mt +// ) + val getter = l.unreflectGetter(matchStringF) + Function { getter.invoke(it) as StringMatcher } + } + val directCaller = run { + val matchM = stringMatcherType.getDeclaredMethod("matches", String::class.java); + matchM.isAccessible = true + val l = MethodHandles.privateLookupIn(ConditionNBT::class.java, MethodHandles.lookup()) +// val mt = MethodType.methodType(java.lang.Boolean.TYPE, stringMatcherType, String::class.java) +// val callsite = LambdaMetafactory.metafactory( +// l, "test", +// MethodType.methodType(BiPredicate::class.java), +// mt, +// l.unreflect(matchM), +// mt +// ) + val func = l.unreflect(matchM) + BiPredicate { a, b -> func.invoke(a, b) as Boolean } + } + + fun test(condition: ConditionNBT, text: String): Boolean { + return directCaller.test(accessMatcher.apply(condition), text) as Boolean + } + } + + val helper = Helper() + + @JvmStatic + fun invokeDirectConditionNBTStringMatch( + nbt: ConditionNBT, + text: String, + ): Boolean { + return helper.test(nbt, text) + } +} diff --git a/src/main/resources/firmament.accesswidener b/src/main/resources/firmament.accesswidener index c69725f..49d4383 100644 --- a/src/main/resources/firmament.accesswidener +++ b/src/main/resources/firmament.accesswidener @@ -21,3 +21,4 @@ mutable field net/minecraft/screen/slot/Slot y I accessible field net/minecraft/entity/player/PlayerEntity PLAYER_MODEL_PARTS Lnet/minecraft/entity/data/TrackedData; accessible field net/minecraft/client/render/WorldRenderer chunks Lnet/minecraft/client/render/BuiltChunkStorage; + -- cgit