diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/ServerPlayerGameModeMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/ServerPlayerGameModeMixin.java index e58e1e237..205a4f02e 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/ServerPlayerGameModeMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/ServerPlayerGameModeMixin.java @@ -30,6 +30,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.DoubleBlockHalf; import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.craftbukkit.v.block.CraftBlock; @@ -99,7 +100,8 @@ public void handleBlockBreakAction(BlockPos blockPos, ServerboundPlayerActionPac level.sendBlockUpdated(blockPos, level.getBlockState(blockPos), level.getBlockState(blockPos), 3); return; } - if (!((PlayerEntityBridge) this.player).bridge$platform$canReach(blockPos, 1.5)) { // Vanilla check is eye-to-center distance < 6, so padding is 6 - 4.5 = 1.5 + if (this.player.getEyePosition().distanceToSqr(Vec3.atCenterOf(blockPos)) != 0 // mixin compat with immptl: https://github.com/iPortalTeam/ImmersivePortalsMod/blob/f419883d285995f2269da11bc1c761e76dafd0e9/src/main/java/qouteall/imm_ptl/core/mixin/common/interaction/MixinServerPlayerGameMode.java + && !((PlayerEntityBridge) this.player).bridge$platform$canReach(blockPos, 1.5)) { // Vanilla check is eye-to-center distance < 6, so padding is 6 - 4.5 = 1.5 this.debugLogging(blockPos, false, j, "too far"); } else if (blockPos.getY() >= i) { this.player.connection.send(new ClientboundBlockUpdatePacket(blockPos, this.level.getBlockState(blockPos))); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/general/network/ChunkMapMixin_Optimize.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/general/network/ChunkMapMixin_Optimize.java index 9e6075da8..130eef0d0 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/general/network/ChunkMapMixin_Optimize.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/general/network/ChunkMapMixin_Optimize.java @@ -2,6 +2,8 @@ import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.bridge.core.world.server.ChunkMap_TrackedEntityBridge; +import io.izzel.arclight.common.mod.compat.ModIds; +import io.izzel.arclight.common.mod.mixins.annotation.LoadIfMod; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.objects.ObjectArraySet; import it.unimi.dsi.fastutil.objects.ObjectCollection; @@ -24,6 +26,7 @@ import java.util.Set; @Mixin(ChunkMap.class) +@LoadIfMod(modid = ModIds.IMMERSIVE_PORTALS, condition = LoadIfMod.ModCondition.ABSENT) public class ChunkMapMixin_Optimize { // @formatter:off diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightCommon.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightCommon.java index 2464f16a0..3d1b1b0e6 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightCommon.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightCommon.java @@ -5,6 +5,8 @@ public class ArclightCommon { public interface Api { byte[] platformRemapClass(byte[] cl); + + boolean isModLoaded(String modid); } private static Api instance; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightMixinPlugin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightMixinPlugin.java index 0476b1c0c..04724c6eb 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightMixinPlugin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightMixinPlugin.java @@ -4,8 +4,8 @@ import io.izzel.arclight.common.mod.mixins.InlineFieldProcessor; import io.izzel.arclight.common.mod.mixins.InlineMethodProcessor; import io.izzel.arclight.common.mod.mixins.MixinProcessor; -import io.izzel.arclight.common.mod.mixins.PlatformMixinProcessor; import io.izzel.arclight.common.mod.mixins.RenameIntoProcessor; +import io.izzel.arclight.common.mod.mixins.ShouldApplyProcessor; import io.izzel.arclight.common.mod.mixins.TransformAccessProcessor; import org.objectweb.asm.tree.ClassNode; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; @@ -38,7 +38,7 @@ public String getRefMapperConfig() { @Override public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - return PlatformMixinProcessor.shouldApply(mixinClassName); + return ShouldApplyProcessor.shouldApply(mixinClassName); } @Override diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/compat/ModIds.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/compat/ModIds.java new file mode 100644 index 000000000..3d9fa667a --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/compat/ModIds.java @@ -0,0 +1,6 @@ +package io.izzel.arclight.common.mod.compat; + +public class ModIds { + + public static final String IMMERSIVE_PORTALS = "immersive_portals"; +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/mixins/LoadIfModProcessor.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/mixins/LoadIfModProcessor.java new file mode 100644 index 000000000..93b87efbc --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/mixins/LoadIfModProcessor.java @@ -0,0 +1,48 @@ +package io.izzel.arclight.common.mod.mixins; + +import io.izzel.arclight.common.mod.ArclightCommon; +import io.izzel.arclight.common.mod.mixins.annotation.LoadIfMod; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.AnnotationNode; +import org.objectweb.asm.tree.ClassNode; + +import java.util.Objects; + +public class LoadIfModProcessor { + + private static final String TYPE = Type.getDescriptor(LoadIfMod.class); + + static boolean shouldApply(ClassNode node) { + for (var ann : node.invisibleAnnotations) { + if (ann.desc.equals(TYPE)) { + var loadIfModData = parse(ann); + return switch (loadIfModData.condition()) { + case ABSENT -> !ArclightCommon.api().isModLoaded(loadIfModData.modid()); + case PRESENT -> ArclightCommon.api().isModLoaded(loadIfModData.modid()); + }; + } + } + return true; + } + + private static LoadIfModData parse(AnnotationNode ann) { + LoadIfMod.ModCondition condition = null; + String modid = null; + for (int i = 0; i < ann.values.size(); i += 2) { + var name = ((String) ann.values.get(i)); + var value = ann.values.get(i + 1); + switch (name) { + case "condition" -> { + var condName = ((String[]) value)[1]; + condition = LoadIfMod.ModCondition.valueOf(condName); + } + case "modid" -> modid = ((String) value); + } + } + return new LoadIfModData(Objects.requireNonNull(condition, "condition"), + Objects.requireNonNull(modid, "modid")); + } + + private record LoadIfModData(LoadIfMod.ModCondition condition, String modid) { + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/mixins/PlatformMixinProcessor.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/mixins/PlatformMixinProcessor.java index 21d639336..7e130c2f5 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/mixins/PlatformMixinProcessor.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/mixins/PlatformMixinProcessor.java @@ -2,11 +2,9 @@ import io.izzel.arclight.api.ArclightPlatform; import io.izzel.arclight.common.mod.mixins.annotation.OnlyInPlatform; -import org.objectweb.asm.ClassReader; import org.objectweb.asm.Type; import org.objectweb.asm.tree.ClassNode; -import java.io.IOException; import java.util.List; public class PlatformMixinProcessor { @@ -14,31 +12,19 @@ public class PlatformMixinProcessor { private static final String TYPE = Type.getDescriptor(OnlyInPlatform.class); @SuppressWarnings("unchecked") - public static boolean shouldApply(String mixinClass) { + static boolean shouldApply(ClassNode node) { var current = ArclightPlatform.current(); - try (var stream = PlatformMixinProcessor.class.getClassLoader().getResourceAsStream(mixinClass.replace('.', '/') + ".class")) { - if (stream != null) { - var bytes = stream.readAllBytes(); - var cr = new ClassReader(bytes); - var node = new ClassNode(); - cr.accept(node, ClassReader.SKIP_CODE); - for (var ann : node.invisibleAnnotations) { - if (ann.desc.equals(TYPE)) { - var list = (List) ann.values.get(1); - for (String[] platform : list) { - if (platform[1].equals(current.name())) { - return true; - } - } - return false; + for (var ann : node.invisibleAnnotations) { + if (ann.desc.equals(TYPE)) { + var list = (List) ann.values.get(1); + for (String[] platform : list) { + if (platform[1].equals(current.name())) { + return true; } } - } else { - System.out.println(mixinClass); + return false; } - return true; - } catch (IOException e) { - return true; } + return true; } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/mixins/ShouldApplyProcessor.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/mixins/ShouldApplyProcessor.java new file mode 100644 index 000000000..01aa0390f --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/mixins/ShouldApplyProcessor.java @@ -0,0 +1,38 @@ +package io.izzel.arclight.common.mod.mixins; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.tree.ClassNode; + +import java.io.IOException; +import java.util.List; +import java.util.function.Predicate; + +public class ShouldApplyProcessor { + + private static final List> PREDICATES = List.of( + PlatformMixinProcessor::shouldApply, + LoadIfModProcessor::shouldApply + ); + + public static boolean shouldApply(String mixinClass) { + try (var stream = PlatformMixinProcessor.class.getClassLoader().getResourceAsStream(mixinClass.replace('.', '/') + ".class")) { + if (stream != null) { + var bytes = stream.readAllBytes(); + var cr = new ClassReader(bytes); + var node = new ClassNode(); + cr.accept(node, ClassReader.SKIP_CODE); + for (var predicate : PREDICATES) { + if (!predicate.test(node)) { + return false; + } + } + return true; + } else { + System.out.println(mixinClass); + } + return true; + } catch (IOException e) { + return true; + } + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/mixins/annotation/LoadIfMod.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/mixins/annotation/LoadIfMod.java new file mode 100644 index 000000000..d2372110a --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/mixins/annotation/LoadIfMod.java @@ -0,0 +1,20 @@ +package io.izzel.arclight.common.mod.mixins.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.CLASS) +public @interface LoadIfMod { + + String modid(); + + ModCondition condition(); + + enum ModCondition { + ABSENT, + PRESENT + } +} diff --git a/arclight-common/src/main/resources/mixins.arclight.impl.optimization.json b/arclight-common/src/main/resources/mixins.arclight.impl.optimization.json index 44ad2f798..e22060215 100644 --- a/arclight-common/src/main/resources/mixins.arclight.impl.optimization.json +++ b/arclight-common/src/main/resources/mixins.arclight.impl.optimization.json @@ -3,6 +3,7 @@ "minVersion": "0.8", "package": "io.izzel.arclight.common.mixin.optimization.general", "target": "@env(DEFAULT)", + "plugin": "io.izzel.arclight.common.mod.ArclightMixinPlugin", "compatibilityLevel": "JAVA_17", "mixins": [ "ClassInheritanceMultiMapMixin", diff --git a/arclight-fabric/src/main/java/io/izzel/arclight/fabric/ArclightModEntrypoint.java b/arclight-fabric/src/main/java/io/izzel/arclight/fabric/ArclightModEntrypoint.java index 742f3e182..fb474cacd 100644 --- a/arclight-fabric/src/main/java/io/izzel/arclight/fabric/ArclightModEntrypoint.java +++ b/arclight-fabric/src/main/java/io/izzel/arclight/fabric/ArclightModEntrypoint.java @@ -11,6 +11,5 @@ public class ArclightModEntrypoint implements ModInitializer { @Override public void onInitialize() { Arclight.setServer(new FabricArclightServer()); - ArclightCommon.setInstance(new FabricCommonImpl()); } } \ No newline at end of file diff --git a/arclight-fabric/src/main/java/io/izzel/arclight/fabric/mod/FabricArclightServer.java b/arclight-fabric/src/main/java/io/izzel/arclight/fabric/mod/FabricArclightServer.java index 307af53c9..b29b10705 100644 --- a/arclight-fabric/src/main/java/io/izzel/arclight/fabric/mod/FabricArclightServer.java +++ b/arclight-fabric/src/main/java/io/izzel/arclight/fabric/mod/FabricArclightServer.java @@ -1,6 +1,5 @@ package io.izzel.arclight.fabric.mod; -import io.izzel.arclight.api.ArclightPlatform; import io.izzel.arclight.api.ArclightServer; import io.izzel.arclight.api.TickingTracker; import io.izzel.arclight.common.mod.server.api.DefaultTickingTracker; diff --git a/arclight-fabric/src/main/java/io/izzel/arclight/fabric/mod/FabricCommonImpl.java b/arclight-fabric/src/main/java/io/izzel/arclight/fabric/mod/FabricCommonImpl.java index a048f8891..d5a8bc789 100644 --- a/arclight-fabric/src/main/java/io/izzel/arclight/fabric/mod/FabricCommonImpl.java +++ b/arclight-fabric/src/main/java/io/izzel/arclight/fabric/mod/FabricCommonImpl.java @@ -2,6 +2,7 @@ import io.izzel.arclight.common.mod.ArclightCommon; import net.fabricmc.api.EnvType; +import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.impl.transformer.FabricTransformer; import org.objectweb.asm.ClassReader; import org.spongepowered.asm.mixin.MixinEnvironment; @@ -16,4 +17,9 @@ public byte[] platformRemapClass(byte[] cl) { bytes = ((IMixinTransformer) MixinEnvironment.getCurrentEnvironment().getActiveTransformer()).transformClassBytes(name, name, bytes); return bytes; } + + @Override + public boolean isModLoaded(String modid) { + return FabricLoader.getInstance().isModLoaded(modid); + } } \ No newline at end of file diff --git a/arclight-fabric/src/main/java/io/izzel/arclight/fabric/mod/FabricMixinPlugin.java b/arclight-fabric/src/main/java/io/izzel/arclight/fabric/mod/FabricMixinPlugin.java index e0f24363e..3d1ead8c9 100644 --- a/arclight-fabric/src/main/java/io/izzel/arclight/fabric/mod/FabricMixinPlugin.java +++ b/arclight-fabric/src/main/java/io/izzel/arclight/fabric/mod/FabricMixinPlugin.java @@ -2,6 +2,7 @@ import io.izzel.arclight.api.ArclightPlatform; import io.izzel.arclight.boot.AbstractBootstrap; +import io.izzel.arclight.common.mod.ArclightCommon; import io.izzel.arclight.common.mod.ArclightMixinPlugin; import io.izzel.arclight.i18n.ArclightConfig; import io.izzel.arclight.i18n.ArclightLocale; @@ -12,6 +13,7 @@ public class FabricMixinPlugin extends ArclightMixinPlugin implements AbstractBo @Override public void onLoad(String mixinPackage) { + ArclightCommon.setInstance(new FabricCommonImpl()); super.onLoad(mixinPackage); MixinTools.setup(); LoggerFactory.getLogger("Arclight").info( diff --git a/arclight-forge/src/main/java/io/izzel/arclight/forge/ArclightMod.java b/arclight-forge/src/main/java/io/izzel/arclight/forge/ArclightMod.java index 35e3c028b..fcbb3befa 100644 --- a/arclight-forge/src/main/java/io/izzel/arclight/forge/ArclightMod.java +++ b/arclight-forge/src/main/java/io/izzel/arclight/forge/ArclightMod.java @@ -22,7 +22,6 @@ public class ArclightMod { public ArclightMod() { ArclightServer.LOGGER.info("mod-load"); Arclight.setServer(new ForgeArclightServer()); - ArclightCommon.setInstance(new ForgeCommonImpl()); System.setOut(new LoggingPrintStream("STDOUT", System.out, Level.INFO)); System.setErr(new LoggingPrintStream("STDERR", System.err, Level.ERROR)); ArclightEventDispatcherRegistry.registerAllEventDispatchers(); diff --git a/arclight-forge/src/main/java/io/izzel/arclight/forge/mod/ForgeCommonImpl.java b/arclight-forge/src/main/java/io/izzel/arclight/forge/mod/ForgeCommonImpl.java index adcfaacb6..03d4d23b2 100644 --- a/arclight-forge/src/main/java/io/izzel/arclight/forge/mod/ForgeCommonImpl.java +++ b/arclight-forge/src/main/java/io/izzel/arclight/forge/mod/ForgeCommonImpl.java @@ -4,6 +4,8 @@ import cpw.mods.modlauncher.TransformingClassLoader; import io.izzel.arclight.api.Unsafe; import io.izzel.arclight.common.mod.ArclightCommon; +import net.minecraftforge.fml.ModList; +import net.minecraftforge.fml.loading.FMLLoader; import org.objectweb.asm.ClassReader; import java.lang.invoke.MethodHandle; @@ -36,4 +38,9 @@ public byte[] platformRemapClass(byte[] cl) { throw new RuntimeException(e); } } + + @Override + public boolean isModLoaded(String modid) { + return ModList.get() != null ? ModList.get().isLoaded(modid) : FMLLoader.getLoadingModList().getModFileById(modid) != null; + } } diff --git a/arclight-forge/src/main/java/io/izzel/arclight/forge/mod/ForgeMixinPlugin.java b/arclight-forge/src/main/java/io/izzel/arclight/forge/mod/ForgeMixinPlugin.java new file mode 100644 index 000000000..814e13678 --- /dev/null +++ b/arclight-forge/src/main/java/io/izzel/arclight/forge/mod/ForgeMixinPlugin.java @@ -0,0 +1,12 @@ +package io.izzel.arclight.forge.mod; + +import io.izzel.arclight.common.mod.ArclightCommon; +import io.izzel.arclight.common.mod.ArclightMixinPlugin; + +public class ForgeMixinPlugin extends ArclightMixinPlugin { + + @Override + public void onLoad(String mixinPackage) { + ArclightCommon.setInstance(new ForgeCommonImpl()); + } +} diff --git a/arclight-forge/src/main/resources/mixins.arclight.forge.json b/arclight-forge/src/main/resources/mixins.arclight.forge.json index f043b7876..1a34bbd74 100644 --- a/arclight-forge/src/main/resources/mixins.arclight.forge.json +++ b/arclight-forge/src/main/resources/mixins.arclight.forge.json @@ -3,7 +3,7 @@ "minVersion": "0.8", "package": "io.izzel.arclight.forge.mixin", "target": "@env(DEFAULT)", - "plugin": "io.izzel.arclight.common.mod.ArclightMixinPlugin", + "plugin": "io.izzel.arclight.forge.mod.ForgeMixinPlugin", "setSourceFile": true, "injectors": { "defaultRequire": 1 diff --git a/arclight-neoforge/src/main/java/io/izzel/arclight/neoforge/ArclightMod.java b/arclight-neoforge/src/main/java/io/izzel/arclight/neoforge/ArclightMod.java index 0eaab4f36..f6f7a2782 100644 --- a/arclight-neoforge/src/main/java/io/izzel/arclight/neoforge/ArclightMod.java +++ b/arclight-neoforge/src/main/java/io/izzel/arclight/neoforge/ArclightMod.java @@ -22,7 +22,6 @@ public class ArclightMod { public ArclightMod() { ArclightServer.LOGGER.info("mod-load"); Arclight.setServer(new NeoForgeArclightServer()); - ArclightCommon.setInstance(new NeoForgeCommonImpl()); System.setOut(new LoggingPrintStream("STDOUT", System.out, Level.INFO)); System.setErr(new LoggingPrintStream("STDERR", System.err, Level.ERROR)); ArclightEventDispatcherRegistry.registerAllEventDispatchers(); diff --git a/arclight-neoforge/src/main/java/io/izzel/arclight/neoforge/mod/NeoForgeCommonImpl.java b/arclight-neoforge/src/main/java/io/izzel/arclight/neoforge/mod/NeoForgeCommonImpl.java index 87823511d..ec3cdfb09 100644 --- a/arclight-neoforge/src/main/java/io/izzel/arclight/neoforge/mod/NeoForgeCommonImpl.java +++ b/arclight-neoforge/src/main/java/io/izzel/arclight/neoforge/mod/NeoForgeCommonImpl.java @@ -4,6 +4,8 @@ import cpw.mods.modlauncher.TransformingClassLoader; import io.izzel.arclight.api.Unsafe; import io.izzel.arclight.common.mod.ArclightCommon; +import net.neoforged.fml.ModList; +import net.neoforged.fml.loading.FMLLoader; import org.objectweb.asm.ClassReader; import java.lang.invoke.MethodHandle; @@ -36,4 +38,9 @@ public byte[] platformRemapClass(byte[] cl) { throw new RuntimeException(e); } } + + @Override + public boolean isModLoaded(String modid) { + return ModList.get() != null ? ModList.get().isLoaded(modid) : FMLLoader.getLoadingModList().getModFileById(modid) != null; + } } diff --git a/arclight-neoforge/src/main/java/io/izzel/arclight/neoforge/mod/NeoForgeMixinPlugin.java b/arclight-neoforge/src/main/java/io/izzel/arclight/neoforge/mod/NeoForgeMixinPlugin.java new file mode 100644 index 000000000..cc28587df --- /dev/null +++ b/arclight-neoforge/src/main/java/io/izzel/arclight/neoforge/mod/NeoForgeMixinPlugin.java @@ -0,0 +1,12 @@ +package io.izzel.arclight.neoforge.mod; + +import io.izzel.arclight.common.mod.ArclightCommon; +import io.izzel.arclight.common.mod.ArclightMixinPlugin; + +public class NeoForgeMixinPlugin extends ArclightMixinPlugin { + + @Override + public void onLoad(String mixinPackage) { + ArclightCommon.setInstance(new NeoForgeCommonImpl()); + } +} diff --git a/arclight-neoforge/src/main/resources/mixins.arclight.neoforge.json b/arclight-neoforge/src/main/resources/mixins.arclight.neoforge.json index 37429f159..70daa6390 100644 --- a/arclight-neoforge/src/main/resources/mixins.arclight.neoforge.json +++ b/arclight-neoforge/src/main/resources/mixins.arclight.neoforge.json @@ -3,7 +3,7 @@ "minVersion": "0.8", "package": "io.izzel.arclight.neoforge.mixin", "target": "@env(DEFAULT)", - "plugin": "io.izzel.arclight.common.mod.ArclightMixinPlugin", + "plugin": "io.izzel.arclight.neoforge.mod.NeoForgeMixinPlugin", "setSourceFile": true, "injectors": { "defaultRequire": 1