aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/mixin
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/mixin')
-rw-r--r--src/main/java/gregtech/mixin/LateMixinPlugin.java21
-rw-r--r--src/main/java/gregtech/mixin/Mixin.java236
-rw-r--r--src/main/java/gregtech/mixin/MixinsVariablesHelper.java6
-rw-r--r--src/main/java/gregtech/mixin/TargetedMod.java75
4 files changed, 338 insertions, 0 deletions
diff --git a/src/main/java/gregtech/mixin/LateMixinPlugin.java b/src/main/java/gregtech/mixin/LateMixinPlugin.java
new file mode 100644
index 0000000000..dab8cc5f03
--- /dev/null
+++ b/src/main/java/gregtech/mixin/LateMixinPlugin.java
@@ -0,0 +1,21 @@
+package gregtech.mixin;
+
+import java.util.List;
+import java.util.Set;
+
+import com.gtnewhorizon.gtnhmixins.ILateMixinLoader;
+import com.gtnewhorizon.gtnhmixins.LateMixin;
+
+@LateMixin
+public class LateMixinPlugin implements ILateMixinLoader {
+
+ @Override
+ public String getMixinConfig() {
+ return "mixins.gregtech.late.json";
+ }
+
+ @Override
+ public List<String> getMixins(Set<String> loadedMods) {
+ return Mixin.getLateMixins(loadedMods);
+ }
+}
diff --git a/src/main/java/gregtech/mixin/Mixin.java b/src/main/java/gregtech/mixin/Mixin.java
new file mode 100644
index 0000000000..3e0ad23f0a
--- /dev/null
+++ b/src/main/java/gregtech/mixin/Mixin.java
@@ -0,0 +1,236 @@
+package gregtech.mixin;
+
+import static gregtech.mixin.TargetedMod.VANILLA;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Supplier;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import com.github.bartimaeusnek.bartworks.common.configs.ConfigHandler;
+
+import cpw.mods.fml.relauncher.FMLLaunchHandler;
+
+public enum Mixin {
+
+ // Minecraft
+ SoundManagerMixin(new Builder("Seeking sound playback")
+ .addMixinClasses("minecraft.SoundManagerMixin", "minecraft.SoundManagerInnerMixin")
+ .addTargetedMod(VANILLA)
+ .setApplyIf(() -> true)
+ .setPhase(Phase.EARLY)
+ .setSide(Side.CLIENT)),
+ WorldMixin(new Builder("Block update detection").addMixinClasses("minecraft.WorldMixin")
+ .addTargetedMod(VANILLA)
+ .setApplyIf(() -> true)
+ .setPhase(Phase.EARLY)
+ .setSide(Side.BOTH)),
+ StringTranslateMixin(new Builder("Keep track of currently translating mods")
+ .addMixinClasses("minecraft.StringTranslateMixin", "minecraft.LanguageRegistryMixin")
+ .addTargetedMod(VANILLA)
+ .setApplyIf(() -> true)
+ .setPhase(Phase.EARLY)
+ .setSide(Side.BOTH)),
+ LocaleMixin(new Builder("Keep track of currently translating client mods").addMixinClasses("minecraft.LocaleMixin")
+ .addTargetedMod(VANILLA)
+ .setApplyIf(() -> true)
+ .setPhase(Phase.EARLY)
+ .setSide(Side.CLIENT)),
+ CacheCraftingManagerRecipes(
+ new Builder("Cache CraftingManager recipes").addMixinClasses("minecraft.CraftingManagerMixin")
+ .addTargetedMod(VANILLA)
+ .setApplyIf(() -> ConfigHandler.enabledPatches[3])
+ .setPhase(Phase.EARLY)
+ .setSide(Side.BOTH)),
+ CraftingRecipeAccessorMixin(new Builder("Add accessors to crafting recipe types")
+ .addMixinClasses(
+ "minecraft.VanillaShapedRecipeMixin",
+ "minecraft.VanillaShapelessRecipeMixin",
+ "minecraft.ForgeShapedRecipeMixin",
+ "minecraft.ForgeShapelessRecipeMixin")
+ .addTargetedMod(VANILLA)
+ .setApplyIf(() -> true)
+ .setPhase(Phase.EARLY)
+ .setSide(Side.BOTH)),
+ BlockStemMixin(new Builder("Stem Crop Block Accessor").addMixinClasses("minecraft.BlockStemMixin")
+ .addTargetedMod(VANILLA)
+ .setApplyIf(() -> true)
+ .setPhase(Phase.EARLY)
+ .setSide(Side.BOTH));
+
+ public static final Logger LOGGER = LogManager.getLogger("GregTech-Mixin");
+
+ private final List<String> mixinClasses;
+ private final List<TargetedMod> targetedMods;
+ private final List<TargetedMod> excludedMods;
+ private final Supplier<Boolean> applyIf;
+ private final Phase phase;
+ private final Side side;
+
+ Mixin(Builder builder) {
+ this.mixinClasses = builder.mixinClasses;
+ this.targetedMods = builder.targetedMods;
+ this.excludedMods = builder.excludedMods;
+ this.applyIf = builder.applyIf;
+ this.phase = builder.phase;
+ this.side = builder.side;
+ if (this.mixinClasses.isEmpty()) {
+ throw new RuntimeException("No mixin class specified for Mixin : " + this.name());
+ }
+ if (this.targetedMods.isEmpty()) {
+ throw new RuntimeException("No targeted mods specified for Mixin : " + this.name());
+ }
+ if (this.applyIf == null) {
+ throw new RuntimeException("No ApplyIf function specified for Mixin : " + this.name());
+ }
+ if (this.phase == null) {
+ throw new RuntimeException("No Phase specified for Mixin : " + this.name());
+ }
+ if (this.side == null) {
+ throw new RuntimeException("No Side function specified for Mixin : " + this.name());
+ }
+ }
+
+ public static List<String> getEarlyMixins(Set<String> loadedCoreMods) {
+ final List<String> mixins = new ArrayList<>();
+ final List<String> notLoading = new ArrayList<>();
+ for (Mixin mixin : Mixin.values()) {
+ if (mixin.phase == Phase.EARLY) {
+ if (mixin.shouldLoad(loadedCoreMods, Collections.emptySet())) {
+ mixins.addAll(mixin.mixinClasses);
+ } else {
+ notLoading.addAll(mixin.mixinClasses);
+ }
+ }
+ }
+ LOGGER.info("Not loading the following EARLY mixins: {}", notLoading.toString());
+ return mixins;
+ }
+
+ public static List<String> getLateMixins(Set<String> loadedMods) {
+ // NOTE: Any targetmod here needs a modid, not a coremod id
+ final List<String> mixins = new ArrayList<>();
+ final List<String> notLoading = new ArrayList<>();
+ for (Mixin mixin : Mixin.values()) {
+ if (mixin.phase == Phase.LATE) {
+ if (mixin.shouldLoad(Collections.emptySet(), loadedMods)) {
+ mixins.addAll(mixin.mixinClasses);
+ } else {
+ notLoading.addAll(mixin.mixinClasses);
+ }
+ }
+ }
+ LOGGER.info("Not loading the following LATE mixins: {}", notLoading.toString());
+ return mixins;
+ }
+
+ private boolean shouldLoadSide() {
+ return side == Side.BOTH || (side == Side.SERVER && FMLLaunchHandler.side()
+ .isServer())
+ || (side == Side.CLIENT && FMLLaunchHandler.side()
+ .isClient());
+ }
+
+ private boolean allModsLoaded(List<TargetedMod> targetedMods, Set<String> loadedCoreMods, Set<String> loadedMods) {
+ if (targetedMods.isEmpty()) return false;
+
+ for (TargetedMod target : targetedMods) {
+ if (target == TargetedMod.VANILLA) continue;
+
+ // Check coremod first
+ if (!loadedCoreMods.isEmpty() && target.coreModClass != null
+ && !loadedCoreMods.contains(target.coreModClass)) return false;
+ else if (!loadedMods.isEmpty() && target.modId != null && !loadedMods.contains(target.modId)) return false;
+ }
+
+ return true;
+ }
+
+ private boolean noModsLoaded(List<TargetedMod> targetedMods, Set<String> loadedCoreMods, Set<String> loadedMods) {
+ if (targetedMods.isEmpty()) return true;
+
+ for (TargetedMod target : targetedMods) {
+ if (target == TargetedMod.VANILLA) continue;
+
+ // Check coremod first
+ if (!loadedCoreMods.isEmpty() && target.coreModClass != null
+ && loadedCoreMods.contains(target.coreModClass)) return false;
+ else if (!loadedMods.isEmpty() && target.modId != null && loadedMods.contains(target.modId)) return false;
+ }
+
+ return true;
+ }
+
+ private boolean shouldLoad(Set<String> loadedCoreMods, Set<String> loadedMods) {
+ return (shouldLoadSide() && applyIf.get()
+ && allModsLoaded(targetedMods, loadedCoreMods, loadedMods)
+ && noModsLoaded(excludedMods, loadedCoreMods, loadedMods));
+ }
+
+ private static class Builder {
+
+ private final String name;
+ private final List<String> mixinClasses = new ArrayList<>();
+ private final List<TargetedMod> targetedMods = new ArrayList<>();
+ private final List<TargetedMod> excludedMods = new ArrayList<>();
+ private Supplier<Boolean> applyIf = null;
+ private Phase phase = null;
+ private Side side = null;
+
+ public Builder(String name) {
+ this.name = name;
+ }
+
+ public Builder addMixinClasses(String... mixinClasses) {
+ this.mixinClasses.addAll(Arrays.asList(mixinClasses));
+ return this;
+ }
+
+ public Builder setPhase(Phase phase) {
+ if (this.phase != null) {
+ throw new RuntimeException("Trying to define Phase twice for " + this.name);
+ }
+ this.phase = phase;
+ return this;
+ }
+
+ public Builder setSide(Side side) {
+ if (this.side != null) {
+ throw new RuntimeException("Trying to define Side twice for " + this.name);
+ }
+ this.side = side;
+ return this;
+ }
+
+ public Builder setApplyIf(Supplier<Boolean> applyIf) {
+ this.applyIf = applyIf;
+ return this;
+ }
+
+ public Builder addTargetedMod(TargetedMod mod) {
+ this.targetedMods.add(mod);
+ return this;
+ }
+
+ public Builder addExcludedMod(TargetedMod mod) {
+ this.excludedMods.add(mod);
+ return this;
+ }
+ }
+
+ private enum Side {
+ BOTH,
+ CLIENT,
+ SERVER
+ }
+
+ private enum Phase {
+ EARLY,
+ LATE,
+ }
+}
diff --git a/src/main/java/gregtech/mixin/MixinsVariablesHelper.java b/src/main/java/gregtech/mixin/MixinsVariablesHelper.java
new file mode 100644
index 0000000000..96cc2ee115
--- /dev/null
+++ b/src/main/java/gregtech/mixin/MixinsVariablesHelper.java
@@ -0,0 +1,6 @@
+package gregtech.mixin;
+
+public class MixinsVariablesHelper {
+
+ public static String currentlyTranslating = null;
+}
diff --git a/src/main/java/gregtech/mixin/TargetedMod.java b/src/main/java/gregtech/mixin/TargetedMod.java
new file mode 100644
index 0000000000..d8e1018f17
--- /dev/null
+++ b/src/main/java/gregtech/mixin/TargetedMod.java
@@ -0,0 +1,75 @@
+package gregtech.mixin;
+
+import cpw.mods.fml.common.Mod;
+
+public enum TargetedMod {
+
+ // NOTE: This doesn't work - late mods need a modid, not a coremod class
+ ADVANCED_SOLAR_PANELS("Advanced Solar Panels", null, "AdvancedSolarPanel"),
+ ANGELICA("Angelica", "com.gtnewhorizons.angelica.loading.AngelicaTweaker", "angelica"),
+ ARCHAICFIX("ArchaicFix", "org.embeddedt.archaicfix.ArchaicCore", "archaicfix"),
+ AUTOMAGY("Automagy", null, "Automagy"),
+ BAUBLES("Baubles", null, "Baubles"),
+ BETTERHUD("Better HUD", null, "hud"),
+ BIBLIOCRAFT("Bibliocraft", null, "BiblioCraft"),
+ BOP("BiomesOPlenty", null, "BiomesOPlenty"),
+ BUGTORCH("BugTorch", "jss.bugtorch.mixinplugin.BugTorchEarlyMixins", "bugtorch"),
+ BUKKIT("Bukkit/Thermos", "Bukkit", null),
+ COFH_CORE("CoFHCore", "cofh.asm.LoadingPlugin", "CoFHCore"),
+ DAMAGE_INDICATORS("Damage Indicators", null, "DamageIndicatorsMod"),
+ EXTRATIC("ExtraTiC", null, "ExtraTiC"),
+ EXTRA_UTILITIES("ExtraUtilities", null, "ExtraUtilities"),
+ FASTCRAFT("FastCraft", "fastcraft.Tweaker"),
+ GALACTICRAFT_CORE("GalacticraftCore", "micdoodle8.mods.galacticraft.core.asm.GCLoadingPlugin", "GalacticraftCore"),
+ GT5U("GregTech5u", null, "gregtech"), // Also matches GT6.
+ GT6("GregTech6", "gregtech.asm.GT_ASM", "gregapi"), // Can be used to exclude GT6 from the GT5U target.
+ GTNHLIB("GTNHLib", "com.gtnewhorizon.gtnhlib.core.GTNHLibCore", "gtnhlib"),
+ HARVESTCRAFT("harvestcraft", null, "harvestcraft"),
+ HARVESTTHENETHER("harvestthenether", null, "harvestthenether"),
+ HUNGER_OVERHAUL("HungerOverhaul", null, "HungerOverhaul"),
+ IC2("IC2", "ic2.core.coremod.IC2core", "IC2"),
+ IMMERSIVE_ENGINENEERING("Immersive Engineering", null, "ImmersiveEngineering"),
+ JOURNEYMAP("JourneyMap", null, "journeymap"),
+ LOTR("The Lord of the rings mod", "lotr.common.coremod.LOTRLoadingPlugin", "lotr"),
+ LWJGL3IFY("lwjgl3ify", "me.eigenraven.lwjgl3ify.core.Lwjgl3ifyCoremod", "lwjgl3ify"),
+ MINECHEM("Minechem", null, "minechem"),
+ MINEFACTORY_RELOADED("MineFactory Reloaded", null, "MineFactoryReloaded"),
+ MRTJPCORE("MrTJPCore", null, "MrTJPCoreMod"),
+ NOTENOUGHITEMS("NotEnoughItems", "codechicken.nei.asm.NEICorePlugin", "NotEnoughItems"),
+ OPTIFINE("Optifine", "optifine.OptiFineForgeTweaker", "Optifine"),
+ PORTAL_GUN("PortalGun", null, "PortalGun"),
+ PROJECTE("ProjectE", null, "ProjectE"),
+ RAILCRAFT("Railcraft", null, "Railcraft"),
+ THAUMCRAFT("Thaumcraft", null, "Thaumcraft"), // "thaumcraft.codechicken.core.launch.DepLoader"
+ THERMALDYNAMICS("Thermal Dynamics", null, "ThermalDynamics"),
+ THERMALEXPANSION("Thermal Expansion", null, "ThermalExpansion"),
+ TINKERSCONSTRUCT("TConstruct", null, "TConstruct"),
+ TRAVELLERSGEAR("TravellersGear", null, "TravellersGear"),
+ VANILLA("Minecraft", null),
+ VOXELMAP("VoxelMap", "com.thevoxelbox.voxelmap.litemod.VoxelMapTransformer", "voxelmap"),
+ WITCHERY("Witchery", null, "witchery"),
+ XAEROWORLDMAP("Xaero's World Map", null, "XaeroWorldMap"),
+ ZTONES("ZTones", null, "Ztones");
+
+ /** The "name" in the {@link Mod @Mod} annotation */
+ public final String modName;
+ /** Class that implements the IFMLLoadingPlugin interface */
+ public final String coreModClass;
+ /** The "modid" in the {@link Mod @Mod} annotation */
+ public final String modId;
+
+ TargetedMod(String modName, String coreModClass) {
+ this(modName, coreModClass, null);
+ }
+
+ TargetedMod(String modName, String coreModClass, String modId) {
+ this.modName = modName;
+ this.coreModClass = coreModClass;
+ this.modId = modId;
+ }
+
+ @Override
+ public String toString() {
+ return "TargetedMod{modName='" + modName + "', coreModClass='" + coreModClass + "', modId='" + modId + "'}";
+ }
+}