Skip to content

Commit 49748c5

Browse files
committed
conditional mixins via annotations
1 parent 35f0f42 commit 49748c5

File tree

18 files changed

+195
-43
lines changed

18 files changed

+195
-43
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,6 @@ Certain sections of the code are from the Create mod, which is licensed under th
3838

3939
Some datafixer code is from the Quilt Standard Libraries, which is licensed under the Apache-2.0 license. See [QSL's license](https://github.com/QuiltMC/quilt-standard-libraries/blob/1.19.4/LICENSE) for more information.
4040

41-
Most of the code for spy conductors is from Security Craft, which is licensed under the MIT license. See [Security Craft's license](https://github.com/Geforce132/SecurityCraft/blob/1.18.2/LICENSE) for more information.
41+
Most of the code for spy conductors is from Security Craft, which is licensed under the MIT license. See [Security Craft's license](https://github.com/Geforce132/SecurityCraft/blob/1.18.2/LICENSE) for more information.
42+
43+
Most of the code for annotation based conditional mixins is from Neruina, which is licensed under the MIT license. See [Neruina's license](https://github.com/Bawnorton/Neruina/blob/multi-version/LICENSE.txt) for more information.

common/src/main/java/com/railwayteam/railways/Railways.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
import net.minecraft.commands.CommandSourceStack;
2626
import net.minecraft.data.DataGenerator;
2727
import net.minecraft.resources.ResourceLocation;
28-
import org.apache.logging.log4j.LogManager;
29-
import org.apache.logging.log4j.Logger;
3028
import org.jetbrains.annotations.ApiStatus;
29+
import org.slf4j.Logger;
30+
import org.slf4j.LoggerFactory;
3131
import org.spongepowered.asm.mixin.MixinEnvironment;
3232

3333
import java.io.FileWriter;
@@ -39,7 +39,7 @@
3939

4040
public class Railways {
4141
public static final String MODID = "railways";
42-
public static final Logger LOGGER = LogManager.getLogger(MODID);
42+
public static final Logger LOGGER = LoggerFactory.getLogger("Railways");
4343
public static final String VERSION = findVersion();
4444
public static final int DATA_FIXER_VERSION = 1; // Only used for datafixers, bump whenever a block changes id etc (should not be bumped multiple times within a release)
4545

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2023-Present Bawnorton
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package com.railwayteam.railways.annotation;
26+
27+
import com.railwayteam.railways.compat.Mods;
28+
29+
import java.lang.annotation.ElementType;
30+
import java.lang.annotation.Retention;
31+
import java.lang.annotation.RetentionPolicy;
32+
import java.lang.annotation.Target;
33+
34+
@Target(ElementType.TYPE)
35+
@Retention(RetentionPolicy.RUNTIME)
36+
public @interface ConditionalMixin {
37+
Mods[] mods();
38+
39+
boolean applyIfPresent() default true;
40+
}

common/src/main/java/com/railwayteam/railways/base/datafixerapi/DataFixesInternals.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public static int getModDataVersion(@NotNull CompoundTag compound) {
6161

6262
if (latestVanillaSchema == null) {
6363
Railways.LOGGER.warn("[Railways DFU] Failed to initialize! Either someone stopped DFU from initializing,");
64-
Railways.LOGGER.warn("[Railways DFU] or this Minecraft build is hosed.");
64+
Railways.LOGGER.warn("[Railways DFU] or this Minecraft build is hosed.");
6565
Railways.LOGGER.warn("[Railways DFU] Using no-op implementation.");
6666
instance = new NoOpDataFixesInternals();
6767
} else {

common/src/main/java/com/railwayteam/railways/compat/incompatible_mods/IncompatibleModsCheck.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ public static void run() {
2020
public static void warnings(Minecraft mc) {
2121
if (IncompatibleModsCheck.optifinePresent) {
2222
if (!CRConfigs.client().disableOptifineWarning.get()) {
23-
Railways.LOGGER.fatal("Optifine Has been detected, Disabled Warning Status: false");
23+
Railways.LOGGER.error("Optifine Has been detected, Disabled Warning Status: false");
2424
mc.setScreen(new OptifineWarningScreen());
2525
} else {
26-
Railways.LOGGER.fatal("Optifine Has been detected, Disabled Warning Status: true");
26+
Railways.LOGGER.error("Optifine Has been detected, Disabled Warning Status: true");
2727
}
2828
}
2929
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.railwayteam.railways.mixin;
2+
3+
import com.railwayteam.railways.util.ConditionalMixinManager;
4+
import org.objectweb.asm.tree.ClassNode;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
8+
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
9+
10+
import java.util.List;
11+
import java.util.Set;
12+
13+
public class CRMixinPlugin implements IMixinConfigPlugin {
14+
public static final Logger LOGGER = LoggerFactory.getLogger("Railways/MixinPlugin");
15+
16+
@Override
17+
public void onLoad(String mixinPackage) { } // NO-OP
18+
19+
@Override
20+
public String getRefMapperConfig() { return null; } // DEFAULT
21+
22+
@Override
23+
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
24+
return ConditionalMixinManager.shouldApply(mixinClassName);
25+
}
26+
27+
@Override
28+
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) { } // NO-OP
29+
30+
@Override
31+
public List<String> getMixins() { return null; } // DEFAULT
32+
33+
@Override
34+
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { } // NO-OP
35+
36+
@Override
37+
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { } // NO-OP
38+
}

common/src/main/java/com/railwayteam/railways/mixin/compat/malilib/MixinGuiTextFieldGeneric.java

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.railwayteam.railways.mixin.compat.malilib;
22

3+
import com.railwayteam.railways.annotation.ConditionalMixin;
4+
import com.railwayteam.railways.compat.Mods;
35
import fi.dy.masa.malilib.gui.GuiTextFieldGeneric;
46
import net.minecraft.client.gui.Font;
57
import net.minecraft.client.gui.components.EditBox;
@@ -9,6 +11,7 @@
911
import org.spongepowered.asm.mixin.injection.Inject;
1012
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
1113

14+
@ConditionalMixin(mods = Mods.MALILIB)
1215
@Mixin(GuiTextFieldGeneric.class)
1316
public abstract class MixinGuiTextFieldGeneric extends EditBox {
1417
private MixinGuiTextFieldGeneric(Font font, int x, int y, int width, int height, Component message) {

common/src/main/java/com/railwayteam/railways/mixin/compat/sodium/MixinBlockOcclusionCache.java

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.railwayteam.railways.mixin.compat.sodium;
22

33
import com.llamalad7.mixinextras.sugar.Local;
4+
import com.railwayteam.railways.annotation.ConditionalMixin;
5+
import com.railwayteam.railways.compat.Mods;
46
import com.railwayteam.railways.mixin_interfaces.IForceRenderingSodium;
57
import me.jellysquid.mods.sodium.client.render.occlusion.BlockOcclusionCache;
68
import net.minecraft.core.BlockPos;
@@ -12,6 +14,7 @@
1214
import org.spongepowered.asm.mixin.injection.Inject;
1315
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
1416

17+
@ConditionalMixin(mods = Mods.SODIUM)
1518
@Mixin(BlockOcclusionCache.class)
1619
public class MixinBlockOcclusionCache {
1720
@Inject(method = "shouldDrawSide", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;skipRendering(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;)Z"), cancellable = true)

common/src/main/java/com/railwayteam/railways/mixin/compat/voicechat/EntityAudioChannelImplMixin.java

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
44
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
5+
import com.railwayteam.railways.annotation.ConditionalMixin;
6+
import com.railwayteam.railways.compat.Mods;
57
import com.railwayteam.railways.content.conductor.ConductorPossessionController;
68
import de.maxhenkel.voicechat.plugins.impl.audiochannel.EntityAudioChannelImpl;
79
import net.minecraft.server.level.ServerPlayer;
@@ -12,6 +14,7 @@
1214

1315
import java.util.UUID;
1416

17+
@ConditionalMixin(mods = Mods.VOICECHAT)
1518
@Mixin(EntityAudioChannelImpl.class)
1619
public class EntityAudioChannelImplMixin {
1720
@SuppressWarnings("unused")

common/src/main/java/com/railwayteam/railways/mixin/compat/voicechat/FreecamUtilMixin.java

+3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package com.railwayteam.railways.mixin.compat.voicechat;
22

3+
import com.railwayteam.railways.annotation.ConditionalMixin;
4+
import com.railwayteam.railways.compat.Mods;
35
import com.railwayteam.railways.content.conductor.ClientHandler;
46
import de.maxhenkel.voicechat.integration.freecam.FreecamUtil;
57
import org.spongepowered.asm.mixin.Mixin;
68
import org.spongepowered.asm.mixin.injection.At;
79
import org.spongepowered.asm.mixin.injection.Inject;
810
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
911

12+
@ConditionalMixin(mods = Mods.VOICECHAT)
1013
@Mixin(FreecamUtil.class)
1114
public class FreecamUtilMixin {
1215
@Inject(method = "isFreecamEnabled", at = @At("HEAD"), cancellable = true, remap = false)

common/src/main/java/com/railwayteam/railways/mixin/compat/voicechat/ServerMixin.java

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
44
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
5+
import com.railwayteam.railways.annotation.ConditionalMixin;
6+
import com.railwayteam.railways.compat.Mods;
57
import com.railwayteam.railways.content.conductor.ConductorPossessionController;
68
import de.maxhenkel.voicechat.voice.server.Server;
79
import net.minecraft.server.level.ServerPlayer;
@@ -12,6 +14,7 @@
1214

1315
import java.util.UUID;
1416

17+
@ConditionalMixin(mods = Mods.VOICECHAT)
1518
@Mixin(Server.class)
1619
public class ServerMixin {
1720
@SuppressWarnings("unused")

common/src/main/java/com/railwayteam/railways/mixin/compat/voicechat/ServerWorldUtilsMixin.java

+3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22

33
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
44
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
5+
import com.railwayteam.railways.annotation.ConditionalMixin;
6+
import com.railwayteam.railways.compat.Mods;
57
import com.railwayteam.railways.content.conductor.ConductorPossessionController;
68
import de.maxhenkel.voicechat.voice.server.ServerWorldUtils;
79
import net.minecraft.server.level.ServerPlayer;
810
import net.minecraft.world.phys.Vec3;
911
import org.spongepowered.asm.mixin.Mixin;
1012
import org.spongepowered.asm.mixin.injection.At;
1113

14+
@ConditionalMixin(mods = Mods.VOICECHAT)
1215
@Mixin(ServerWorldUtils.class)
1316
public class ServerWorldUtilsMixin {
1417
@SuppressWarnings("unused")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2023-Present Bawnorton
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package com.railwayteam.railways.util;
26+
27+
import com.railwayteam.railways.annotation.ConditionalMixin;
28+
import com.railwayteam.railways.compat.Mods;
29+
import com.railwayteam.railways.mixin.CRMixinPlugin;
30+
import org.objectweb.asm.Type;
31+
import org.objectweb.asm.tree.AnnotationNode;
32+
import org.spongepowered.asm.service.MixinService;
33+
import org.spongepowered.asm.util.Annotations;
34+
35+
import java.io.IOException;
36+
import java.util.List;
37+
38+
public class ConditionalMixinManager {
39+
public static boolean shouldApply(String className) {
40+
try {
41+
List<AnnotationNode> annotationNodes = MixinService.getService().getBytecodeProvider().getClassNode(className).visibleAnnotations;
42+
if (annotationNodes == null) return true;
43+
44+
boolean shouldApply = true;
45+
for (AnnotationNode node : annotationNodes) {
46+
if (node.desc.equals(Type.getDescriptor(ConditionalMixin.class))) {
47+
List<Mods> mods = Annotations.getValue(node, "mods", true, Mods.class);
48+
boolean applyIfPresent = Annotations.getValue(node, "applyIfPresent", Boolean.TRUE);
49+
boolean anyModsLoaded = anyModsLoaded(mods);
50+
shouldApply = anyModsLoaded == applyIfPresent;
51+
CRMixinPlugin.LOGGER.info("{} is{}being applied because the mod(s) {} are{}loaded", className, shouldApply ? " " : " not ", mods, anyModsLoaded ? " " : " not ");
52+
}
53+
}
54+
return shouldApply;
55+
} catch (ClassNotFoundException | IOException e) {
56+
throw new RuntimeException(e);
57+
}
58+
}
59+
60+
private static boolean anyModsLoaded(List<Mods> mods) {
61+
for (Mods mod : mods) {
62+
if (mod.isLoaded) return true;
63+
}
64+
return false;
65+
}
66+
}

common/src/main/resources/railways-common.mixins.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"required": true,
33
"minVersion": "0.8",
44
"package": "com.railwayteam.railways.mixin",
5+
"plugin": "com.railwayteam.railways.mixin.CRMixinPlugin",
56
"compatibilityLevel": "JAVA_17",
67
"mixins": [
78
"AccessorAbstractContraptionEntity",
@@ -153,6 +154,7 @@
153154
"conductor_possession.MixinMouseHandler"
154155
],
155156
"injectors": {
156-
"defaultRequire": 1
157+
"defaultRequire": 1,
158+
"maxShiftBy": 5
157159
}
158160
}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.railwayteam.railways.fabric.mixin;
22

3-
import com.railwayteam.railways.compat.Mods;
3+
import com.railwayteam.railways.util.ConditionalMixinManager;
44
import org.objectweb.asm.tree.ClassNode;
55
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
66
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
@@ -10,33 +10,25 @@
1010

1111
public class CRMixinPlugin implements IMixinConfigPlugin {
1212
@Override
13-
public void onLoad(String s) {}
13+
public void onLoad(String mixinPackage) { } // NO-OP
1414

1515
@Override
16-
public String getRefMapperConfig() {
17-
return null;
18-
} // null is default
16+
public String getRefMapperConfig() { return null; } // DEFAULT
1917

2018
@Override
21-
public boolean shouldApplyMixin(String targetName, String mixinName) {
22-
if (mixinName.contains("compat.voicechat"))
23-
return Mods.VOICECHAT.isLoaded;
24-
if (mixinName.contains("compat.malilib"))
25-
return Mods.MALILIB.isLoaded;
26-
return true;
19+
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
20+
return ConditionalMixinManager.shouldApply(mixinClassName);
2721
}
2822

2923
@Override
30-
public void acceptTargets(Set<String> set, Set<String> set1) {} // hook to remove targets
24+
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) { } // NO-OP
3125

3226
@Override
33-
public List<String> getMixins() {
34-
return null;
35-
} // null to not append extra mixins to the mixin config
27+
public List<String> getMixins() { return null; } // DEFAULT
3628

3729
@Override
38-
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {}
30+
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { } // NO-OP
3931

4032
@Override
41-
public void postApply(String s, ClassNode classNode, String s1, IMixinInfo iMixinInfo) {}
33+
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { } // NO-OP
4234
}

fabric/src/main/resources/railways.mixins.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
"EnderManMixin"
1616
],
1717
"injectors": {
18-
"defaultRequire": 1
18+
"defaultRequire": 1,
19+
"maxShiftBy": 5
1920
},
2021
"plugin": "com.railwayteam.railways.fabric.mixin.CRMixinPlugin"
2122
}

0 commit comments

Comments
 (0)