diff --git a/common/src/main/java/com/copycatsplus/copycats/foundation/annotation/ModMixin.java b/common/src/main/java/com/copycatsplus/copycats/foundation/annotation/ModMixin.java new file mode 100644 index 000000000..53b4ccb4a --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/foundation/annotation/ModMixin.java @@ -0,0 +1,21 @@ +package com.copycatsplus.copycats.foundation.annotation; + +import com.copycatsplus.copycats.compat.Mods; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/* +* This annotation is used to make mixins only enable themselves if the required mod(s) are installed +*/ + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface ModMixin { + + Mods[] requiredMods(); + + boolean applyIfPresent() default true; +} diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/MixinPlugin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/MixinPlugin.java index d2a436a14..269df15d6 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/MixinPlugin.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/MixinPlugin.java @@ -1,14 +1,24 @@ package com.copycatsplus.copycats.mixin; +import com.copycatsplus.copycats.compat.Mods; +import com.copycatsplus.copycats.foundation.annotation.ModMixin; import com.llamalad7.mixinextras.MixinExtrasBootstrap; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.AnnotationNode; import org.objectweb.asm.tree.ClassNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; +import org.spongepowered.asm.service.MixinService; +import org.spongepowered.asm.util.Annotations; +import java.io.IOException; import java.util.List; import java.util.Set; public class MixinPlugin implements IMixinConfigPlugin { + public static final Logger LOGGER = LoggerFactory.getLogger("Copycats+ | MixinPlugin"); private boolean isFrameworkInstalled; @Override @@ -29,9 +39,34 @@ public String getRefMapperConfig() { @Override public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { + try { + List annotationNodes = MixinService.getService().getBytecodeProvider().getClassNode(mixinClassName).visibleAnnotations; + if (annotationNodes == null) return true; + + boolean shouldApply = true; + for (AnnotationNode node : annotationNodes) { + if (node.desc.equals(Type.getDescriptor(ModMixin.class))) { + List mods = Annotations.getValue(node, "requiredMods", true, Mods.class); + boolean applyIfPresent = Annotations.getValue(node, "applyIfPresent", Boolean.TRUE); + boolean anyModsLoaded = anyModsLoaded(mods); + shouldApply = anyModsLoaded == applyIfPresent; + LOGGER.debug("{} is {} being applied because the mod(s) {} are {} loaded", mixinClassName, shouldApply ? " " : " not ", mods, anyModsLoaded ? " " : " not "); + } + } + return shouldApply; + } catch (ClassNotFoundException | IOException e) { + LOGGER.error("An error occurred when checking if {} has the ModMixin annotation", mixinClassName, e); + } return isFrameworkInstalled; // this makes sure that forge's helpful mods not found screen shows up } + private static boolean anyModsLoaded(List mods) { + for (Mods mod : mods) { + if (mod.isLoaded) return true; + } + return false; + } + @Override public void acceptTargets(Set myTargets, Set otherTargets) { diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/additionalplacements/ConfigCommonMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/additionalplacements/ConfigCommonMixin.java index 7f70027da..34b49bace 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/additionalplacements/ConfigCommonMixin.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/additionalplacements/ConfigCommonMixin.java @@ -1,6 +1,8 @@ package com.copycatsplus.copycats.mixin.compat.additionalplacements; import com.copycatsplus.copycats.Copycats; +import com.copycatsplus.copycats.compat.Mods; +import com.copycatsplus.copycats.foundation.annotation.ModMixin; import com.firemerald.additionalplacements.common.ConfigCommon; import net.minecraft.resources.ResourceLocation; import org.spongepowered.asm.mixin.Mixin; @@ -14,6 +16,7 @@ *

* Will appear to error but works and builds fine. */ +@ModMixin(requiredMods = Mods.ADDITIONAL_PLACEMENTS) @Pseudo @Mixin(value = {ConfigCommon.class}) public class ConfigCommonMixin { diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/additionalplacements/PlacementBlockMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/additionalplacements/PlacementBlockMixin.java index 0201c5fe0..3af03660c 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/additionalplacements/PlacementBlockMixin.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/additionalplacements/PlacementBlockMixin.java @@ -1,5 +1,7 @@ package com.copycatsplus.copycats.mixin.compat.additionalplacements; +import com.copycatsplus.copycats.compat.Mods; +import com.copycatsplus.copycats.foundation.annotation.ModMixin; import com.copycatsplus.copycats.foundation.copycat.ICopycatBlock; import com.firemerald.additionalplacements.block.AdditionalPlacementBlock; import net.minecraft.world.level.block.*; @@ -11,6 +13,7 @@ /** * Always report that our blocks have no extra states added by AdditionalPlacements. */ +@ModMixin(requiredMods = Mods.ADDITIONAL_PLACEMENTS) @Mixin( value = { AdditionalPlacementBlock.class, diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/diagonalfences/FenceBlockMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/diagonalfences/FenceBlockMixin.java index 09024cdd2..98495e7a2 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/diagonalfences/FenceBlockMixin.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/diagonalfences/FenceBlockMixin.java @@ -1,5 +1,7 @@ package com.copycatsplus.copycats.mixin.compat.diagonalfences; +import com.copycatsplus.copycats.compat.Mods; +import com.copycatsplus.copycats.foundation.annotation.ModMixin; import com.copycatsplus.copycats.foundation.copycat.ICopycatBlock; import net.minecraft.world.level.block.CrossCollisionBlock; import net.minecraft.world.level.block.FenceBlock; @@ -13,6 +15,7 @@ *

* This patch has to be applied after Diagonal Fences modifies the FenceBlock class */ +@ModMixin(requiredMods = Mods.DIAGONAL_FENCES) @Mixin(value = FenceBlock.class, priority = 1100) public abstract class FenceBlockMixin extends CrossCollisionBlock { diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/radium/PathNodeDefaultsMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/radium/PathNodeDefaultsMixin.java index a93a06068..5b2c7c376 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/radium/PathNodeDefaultsMixin.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/radium/PathNodeDefaultsMixin.java @@ -1,6 +1,8 @@ package com.copycatsplus.copycats.mixin.compat.radium; +import com.copycatsplus.copycats.compat.Mods; import com.copycatsplus.copycats.content.copycat.slab.CopycatSlabBlock; +import com.copycatsplus.copycats.foundation.annotation.ModMixin; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.minecraft.world.level.block.Block; @@ -13,6 +15,7 @@ /** * Make sure Radium's pathfinding algorithm considers slabs properly, since they do not extend from {@link net.minecraft.world.level.block.SlabBlock}. */ +@ModMixin(requiredMods = Mods.INDIUM) @Mixin(targets = "me.jellysquid.mods.lithium.common.ai.pathing.PathNodeDefaults") @Pseudo public class PathNodeDefaultsMixin { diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockOcclusionCacheMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockOcclusionCacheMixin.java index deb3d83a7..b2d74029a 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockOcclusionCacheMixin.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockOcclusionCacheMixin.java @@ -1,5 +1,7 @@ package com.copycatsplus.copycats.mixin.compat.rubidium; +import com.copycatsplus.copycats.compat.Mods; +import com.copycatsplus.copycats.foundation.annotation.ModMixin; import com.copycatsplus.copycats.foundation.copycat.ICopycatBlock; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -14,6 +16,7 @@ /** * Makes sure that copycat blocks are not occluded by Rubidium */ +@ModMixin(requiredMods = Mods.SODIUM) @Mixin(targets = "me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.BlockOcclusionCache") @Pseudo public class BlockOcclusionCacheMixin { diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockRendererMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockRendererMixin.java index 856b096fd..7d5d57061 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockRendererMixin.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockRendererMixin.java @@ -1,5 +1,7 @@ package com.copycatsplus.copycats.mixin.compat.rubidium; +import com.copycatsplus.copycats.compat.Mods; +import com.copycatsplus.copycats.foundation.annotation.ModMixin; import com.copycatsplus.copycats.foundation.copycat.multistate.MultiStateRenderManager; import com.copycatsplus.copycats.foundation.copycat.multistate.MultiStateTextureAtlasSprite; import me.jellysquid.mods.sodium.client.model.color.ColorProvider; @@ -18,6 +20,7 @@ *

* Rubidium compatible version of {@link com.copycatsplus.copycats.mixin.foundation.copycat.multistate.ModelBlockRendererMixin}. */ +@ModMixin(requiredMods = Mods.SODIUM) @Mixin(BlockRenderer.class) @Pseudo public class BlockRendererMixin {