diff --git a/src/main/java/com/falsepattern/endlessids/IEPlugin.java b/src/main/java/com/falsepattern/endlessids/IEPlugin.java index 06c2768..564c635 100644 --- a/src/main/java/com/falsepattern/endlessids/IEPlugin.java +++ b/src/main/java/com/falsepattern/endlessids/IEPlugin.java @@ -3,10 +3,14 @@ package com.falsepattern.endlessids; import com.falsepattern.endlessids.asm.IETransformer; import com.falsepattern.lib.config.ConfigException; import com.falsepattern.lib.config.ConfigurationManager; +import lombok.SneakyThrows; +import lombok.val; +import net.minecraft.launchwrapper.LaunchClassLoader; import cpw.mods.fml.relauncher.IFMLLoadingPlugin; import java.util.Map; +import java.util.Set; import static cpw.mods.fml.relauncher.IFMLLoadingPlugin.DependsOn; import static cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion; @@ -30,7 +34,19 @@ public class IEPlugin implements IFMLLoadingPlugin { super(); } + @SneakyThrows public String[] getASMTransformerClass() { + val cl = ((LaunchClassLoader)this.getClass().getClassLoader()); + val field = cl.getClass().getDeclaredField("transformerExceptions"); + field.setAccessible(true); + val exceptions = (Set) field.get(cl); + if (exceptions.contains("code.elix_x.coremods")) { + System.out.println("AntiIDConflict detected!"); + System.out.println("Removing ASM protections so that we can fix its code."); + exceptions.remove("code.elix_x.coremods"); + exceptions.add("code.elix_x.coremods.antiidconflict.core"); + exceptions.add("code.elix_x.coremods.antiidconflict.ByteCodeTester"); + } return new String[]{IETransformer.class.getName()}; } diff --git a/src/main/java/com/falsepattern/endlessids/mixin/helpers/AIDCStringFixer.java b/src/main/java/com/falsepattern/endlessids/mixin/helpers/AIDCStringFixer.java new file mode 100644 index 0000000..917349c --- /dev/null +++ b/src/main/java/com/falsepattern/endlessids/mixin/helpers/AIDCStringFixer.java @@ -0,0 +1,13 @@ +package com.falsepattern.endlessids.mixin.helpers; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class AIDCStringFixer { + public static String fixString(String str) { + str = str.replace("\\", ""); + str = str.replace("vaible", "vailable"); + return str; + } +} diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/AntiIdConflictBaseMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/AntiIdConflictBaseMixin.java new file mode 100644 index 0000000..a9a26e6 --- /dev/null +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/AntiIdConflictBaseMixin.java @@ -0,0 +1,35 @@ +package com.falsepattern.endlessids.mixin.mixins.common.antiidconflict; + +import code.elix_x.coremods.antiidconflict.AntiIdConflictBase; +import org.spongepowered.asm.lib.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import cpw.mods.fml.common.event.FMLPreInitializationEvent; + +import java.io.File; + +@Mixin(value = AntiIdConflictBase.class, + remap = false) +public abstract class AntiIdConflictBaseMixin { + @Shadow public static File mainFolder; + + @Inject(method = "preinit", + at = @At("HEAD"), + require = 1) + private static void fixPath(FMLPreInitializationEvent event, CallbackInfo ci) { + mainFolder = new File(event.getModConfigurationDirectory().getPath(), "AntiIDConflict"); + } + + @Redirect(method = "preinit", + at = @At(value = "FIELD", + target = "Lcode/elix_x/coremods/antiidconflict/AntiIdConflictBase;mainFolder:Ljava/io/File;", + opcode = Opcodes.PUTSTATIC), + require = 1) + private static void removeOldPut(File value) { + } +} diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/BiomesManagerMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/BiomesManagerMixin.java new file mode 100644 index 0000000..7f2d244 --- /dev/null +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/BiomesManagerMixin.java @@ -0,0 +1,213 @@ +package com.falsepattern.endlessids.mixin.mixins.common.antiidconflict; + +import code.elix_x.coremods.antiidconflict.AntiIdConflictBase; +import code.elix_x.coremods.antiidconflict.managers.BiomesManager; +import com.falsepattern.endlessids.constants.ExtendedConstants; +import com.falsepattern.endlessids.constants.VanillaConstants; +import com.falsepattern.endlessids.mixin.helpers.AIDCStringFixer; +import lombok.val; +import org.apache.commons.lang3.ArrayUtils; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.ModifyConstant; + +import net.minecraft.world.biome.BiomeGenBase; + +import java.io.File; +import java.io.PrintWriter; + +import static code.elix_x.coremods.antiidconflict.managers.BiomesManager.conflicts; + +@Mixin(value = BiomesManager.class, + remap = false) +public abstract class BiomesManagerMixin { + @Shadow public static String freeBiomeIDs; + + @Shadow public static String occupiedBiomeIDs; + + @Shadow public static boolean debug; + + @Shadow public static int IconflictedIds; + + @Shadow public static String conflictedIds; + + private static String[] getIntervalNaming(int first, int last) { + if (first == last) { + return new String[]{Integer.toString(first)}; + } else if (first + 1 == last) { + return new String[]{Integer.toString(first), Integer.toString(last)}; + } else { + return new String[]{first + "-" + last}; + } + } + @ModifyConstant(method = "", + constant = @Constant(intValue = VanillaConstants.biomeIDCount), + require = 1) + private static int extendIDs(int constant) { + return ExtendedConstants.biomeIDCount; + } + + @ModifyConstant(method = "preinit", + constant = @Constant(stringValue = "\\biomes")) + private static String fixPaths(String original) { + return AIDCStringFixer.fixString(original); + } + + /** + * @author FalsePattern + * @reason Better code, and detecting empty areas. + */ + @Overwrite + public static void updateBiomesFolder() throws Exception { + val biomes = BiomeGenBase.getBiomeGenArray(); + val builder = new StringBuilder(); + boolean hasEmpty = false; + int emptyRegionStart = 0; + for (int i = 0; i < biomes.length; ++i) { + if (biomes[i] == null) { + if (!hasEmpty) { + emptyRegionStart = i; + hasEmpty = true; + } + ++BiomesManager.freeIds; + } else if (hasEmpty) { + hasEmpty = false; + for (val part: getIntervalNaming(emptyRegionStart, i - 1)) { + builder.append(part).append('\n'); + } + } + } + if (hasEmpty) { + for (val part: getIntervalNaming(emptyRegionStart, ExtendedConstants.biomeIDCount - 1)) { + builder.append(part).append('\n'); + } + } + freeBiomeIDs = builder.toString(); + builder.setLength(0); + + System.out.println("Found " + BiomesManager.freeIds + " free biome ids in total."); + + for (val biome : biomes) { + if (biome != null) { + builder.append(biome.biomeID) + .append(" : ") + .append(biome.biomeName) + .append(" (") + .append(biome.getBiomeClass()) + .append(")\n"); + ++BiomesManager.occupiedIds; + } + } + occupiedBiomeIDs = builder.toString(); + builder.setLength(0); + + System.out.println("Found " + BiomesManager.occupiedIds + " occupied biome ids in total."); + + for (val conflict : conflicts) { + if (conflict != null) { + if (debug) { + System.out.println( + "Found biomes id conflict for " + conflict.ID + " : " + conflict.getCrashMessage()); + } + builder.append(conflict.getCrashMessage()).append('\n'); + ++IconflictedIds; + } + } + conflictedIds = builder.toString(); + builder.setLength(0); + + System.out.println("Found " + IconflictedIds + " conflicted biome ids in total."); + File available = new File(AntiIdConflictBase.biomesFolder, "availableIDs.txt"); + if (available.exists()) { + available.delete(); + } + + available.createNewFile(); + PrintWriter writer = new PrintWriter(available); + writer.println("Total amount of free biome ids: " + available); + writer.println("List of free biome ids:"); + val freeIDs = freeBiomeIDs.split("\n"); + + for (val freeID : freeIDs) { + writer.println(freeID); + } + + writer.close(); + val occupied = new File(AntiIdConflictBase.biomesFolder, "occupiedIDs.txt"); + if (occupied.exists()) { + occupied.delete(); + } + + occupied.createNewFile(); + writer = new PrintWriter(occupied); + writer.println("Total amount of occupied biome ids: " + BiomesManager.occupiedIds); + writer.println("Table of occupied biome ids and their owners"); + writer.println("id:name(class)"); + val occupiedIDs = occupiedBiomeIDs.split("\n"); + + for (String occupiedID : occupiedIDs) { + writer.println(occupiedID); + } + + writer.close(); + val conflicted = new File(AntiIdConflictBase.biomesFolder, "conflictedIDs.txt"); + if (conflicted.exists()) { + conflicted.delete(); + } + + conflicted.createNewFile(); + writer = new PrintWriter(conflicted); + writer.println("Total amount of conflicted biome ids: " + IconflictedIds); + writer.println("IDs in conflict:\n"); + val conflictedIDs = conflictedIds.split("\n"); + for (val conflictedID : conflictedIDs) { + writer.println(conflictedID); + } + + writer.close(); + val all = new File(AntiIdConflictBase.biomesFolder, "AllIDs.txt"); + writer = new PrintWriter(all); + writer.println("Total amount of free biome ids: " + BiomesManager.freeIds); + writer.println("Total amount of occupied biome ids: " + BiomesManager.occupiedIds); + writer.println("Total amount of conflicted biome ids: " + IconflictedIds); + writer.println("All ids and their position:"); + + hasEmpty = false; + emptyRegionStart = 0; + + for(int i = 0; i < biomes.length; ++i) { + if (!ArrayUtils.isEmpty(conflicts) && conflicts[i] != null) { + writer.println(conflicts[i].getCrashMessage()); + } else if (biomes[i] != null) { + if (hasEmpty) { + hasEmpty = false; + for (val part: getIntervalNaming(emptyRegionStart, i - 1)) { + writer.print(part); + writer.println(" is Available"); + } + } + writer.print(i); + writer.print(" is Occupied by "); + writer.print(biomes[i].biomeName); + writer.print(" ("); + writer.print(biomes[i].getBiomeClass().getName()); + writer.println(")"); + } else if (!hasEmpty) { + hasEmpty = true; + emptyRegionStart = i; + } + } + if (hasEmpty) { + for (val part: getIntervalNaming(emptyRegionStart, ExtendedConstants.biomeIDCount - 1)) { + writer.print(part); + writer.println(" is Available"); + } + } + + writer.close(); + } +} diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/DimensionsManagerMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/DimensionsManagerMixin.java new file mode 100644 index 0000000..4eda302 --- /dev/null +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/DimensionsManagerMixin.java @@ -0,0 +1,22 @@ +package com.falsepattern.endlessids.mixin.mixins.common.antiidconflict; + +import code.elix_x.coremods.antiidconflict.managers.DimensionsManager; +import com.falsepattern.endlessids.mixin.helpers.AIDCStringFixer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; + +@Mixin(value = DimensionsManager.class, + remap = false) +public abstract class DimensionsManagerMixin { + + @ModifyConstant(method = "*", + constant = {@Constant(stringValue = "\\dimensions"), + @Constant(stringValue = "\\main.cfg"), + @Constant(stringValue = "\\avaibleIDs.txt"), + @Constant(stringValue = "\\occupiedIDs.txt"), + @Constant(stringValue = "\\AllIDs.txt")}) + private static String fixPaths(String original) { + return AIDCStringFixer.fixString(original); + } +} diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/EnchantementsManagerMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/EnchantementsManagerMixin.java new file mode 100644 index 0000000..ec3dc28 --- /dev/null +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/EnchantementsManagerMixin.java @@ -0,0 +1,22 @@ +package com.falsepattern.endlessids.mixin.mixins.common.antiidconflict; + +import code.elix_x.coremods.antiidconflict.managers.EnchantementsManager; +import com.falsepattern.endlessids.mixin.helpers.AIDCStringFixer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; + +@Mixin(value = EnchantementsManager.class, + remap = false) +public abstract class EnchantementsManagerMixin { + + @ModifyConstant(method = "*", + constant = {@Constant(stringValue = "\\enchantements"), + @Constant(stringValue = "\\main.cfg"), + @Constant(stringValue = "\\avaibleIDs.txt"), + @Constant(stringValue = "\\occupiedIDs.txt"), + @Constant(stringValue = "\\AllIDs.txt")}) + private static String fixPaths(String original) { + return AIDCStringFixer.fixString(original); + } +} diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/EntitiesManagerMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/EntitiesManagerMixin.java new file mode 100644 index 0000000..003cfc2 --- /dev/null +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/EntitiesManagerMixin.java @@ -0,0 +1,22 @@ +package com.falsepattern.endlessids.mixin.mixins.common.antiidconflict; + +import code.elix_x.coremods.antiidconflict.managers.EntitiesManager; +import com.falsepattern.endlessids.mixin.helpers.AIDCStringFixer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; + +@Mixin(value = EntitiesManager.class, + remap = false) +public abstract class EntitiesManagerMixin { + + @ModifyConstant(method = "*", + constant = {@Constant(stringValue = "\\entities"), + @Constant(stringValue = "\\main.cfg"), + @Constant(stringValue = "\\avaibleIDs.txt"), + @Constant(stringValue = "\\occupiedIDs.txt"), + @Constant(stringValue = "\\AllIDs.txt")}) + private static String fixPaths(String original) { + return AIDCStringFixer.fixString(original); + } +} diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/PotionsManagerMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/PotionsManagerMixin.java new file mode 100644 index 0000000..9dee48f --- /dev/null +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/antiidconflict/PotionsManagerMixin.java @@ -0,0 +1,23 @@ +package com.falsepattern.endlessids.mixin.mixins.common.antiidconflict; + +import code.elix_x.coremods.antiidconflict.managers.PotionsManager; +import com.falsepattern.endlessids.mixin.helpers.AIDCStringFixer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; + +@Mixin(value = PotionsManager.class, + remap = false) +public abstract class PotionsManagerMixin { + + @ModifyConstant(method = "*", + constant = {@Constant(stringValue = "\\potions"), + @Constant(stringValue = "\\main.cfg"), + @Constant(stringValue = "\\avaibleIDs.txt"), + @Constant(stringValue = "\\occupiedIDs.txt"), + @Constant(stringValue = "\\conflictedIDs.txt"), + @Constant(stringValue = "\\AllIDs.txt")}) + private static String fixPaths(String original) { + return AIDCStringFixer.fixString(original); + } +} diff --git a/src/main/java/com/falsepattern/endlessids/mixin/plugin/Mixin.java b/src/main/java/com/falsepattern/endlessids/mixin/plugin/Mixin.java index 371de05..6604e06 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/plugin/Mixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/plugin/Mixin.java @@ -59,8 +59,20 @@ public enum Mixin implements IMixin { //endregion Minecraft->client //endregion Minecraft //region AntiIDConflict->common + AIDCAntiIdConflictBaseMixin(Side.COMMON, require(TargetedMod.ANTIIDCONFLICT), + "antiidconflict.AntiIdConflictBaseMixin"), AIDCBiomesGenBasePlaceholderMixin(Side.COMMON, require(TargetedMod.ANTIIDCONFLICT), "antiidconflict.BiomeGenBasePlaceholderMixin"), + AIDCBiomesManagerMixin(Side.COMMON, require(TargetedMod.ANTIIDCONFLICT), + "antiidconflict.BiomesManagerMixin"), + AIDCDimensionsManagerMixin(Side.COMMON, require(TargetedMod.ANTIIDCONFLICT), + "antiidconflict.DimensionsManagerMixin"), + AIDCEnchantementsManagerMixin(Side.COMMON, require(TargetedMod.ANTIIDCONFLICT), + "antiidconflict.EnchantementsManagerMixin"), + AIDCEntitiesManagerMixin(Side.COMMON, require(TargetedMod.ANTIIDCONFLICT), + "antiidconflict.EntitiesManagerMixin"), + AIDCPotionsManagerMixin(Side.COMMON, require(TargetedMod.ANTIIDCONFLICT), + "antiidconflict.PotionsManagerMixin"), //endregion AntiIDConflict->common //region ATG->common ATGBiomeConfigMixin(Side.COMMON, require(TargetedMod.ATG), "atg.ATGBiomeConfigMixin"),