From 56ff2d4e8d0b6bbecac8594e76bb67acb578acae Mon Sep 17 00:00:00 2001 From: Su5eD Date: Mon, 5 Feb 2024 18:30:58 +0100 Subject: [PATCH 1/7] Use latest LVT compat if no loader dependency is declared Fixes #803 --- gradle.properties | 2 +- .../sinytra/connector/service/FabricMixinBootstrap.java | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 679d0e07..2193cf71 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=true # Versions -versionConnector=1.0.0-beta.36 +versionConnector=1.0.0-beta.37 versionAdapter=1.11.19-1.20.1-20240126.215012 versionAdapterDefinition=1.11.24 diff --git a/src/main/java/dev/su5ed/sinytra/connector/service/FabricMixinBootstrap.java b/src/main/java/dev/su5ed/sinytra/connector/service/FabricMixinBootstrap.java index d5598e21..ff76bfb0 100644 --- a/src/main/java/dev/su5ed/sinytra/connector/service/FabricMixinBootstrap.java +++ b/src/main/java/dev/su5ed/sinytra/connector/service/FabricMixinBootstrap.java @@ -99,19 +99,26 @@ public static int getMixinCompat(ModMetadata metadata) { // infer from loader dependency by determining the least relevant loader version the mod accepts // AND any loader deps + boolean found = false; List reqIntervals = List.of(VersionInterval.INFINITE); for (ModDependency dep : metadata.getDependencies()) { if (dep.getModId().equals("fabricloader") || dep.getModId().equals("fabric-loader")) { if (dep.getKind() == ModDependency.Kind.DEPENDS) { + found = true; reqIntervals = VersionInterval.and(reqIntervals, dep.getVersionIntervals()); } else if (dep.getKind() == ModDependency.Kind.BREAKS) { + found = true; reqIntervals = VersionInterval.and(reqIntervals, VersionInterval.not(dep.getVersionIntervals())); } } } + if (!found) { + return FabricUtil.COMPATIBILITY_0_10_0; + } + if (reqIntervals.isEmpty()) throw new IllegalStateException("mod " + metadata.getId() + " is incompatible with every loader version?"); // shouldn't get there Version minLoaderVersion = reqIntervals.get(0).getMin(); // it is sorted, to 0 has the absolute lower bound From 63cb91d3eb8532a6a6066e27c5429ac64b3f36f6 Mon Sep 17 00:00:00 2001 From: Su5eD Date: Wed, 21 Feb 2024 22:06:38 +0100 Subject: [PATCH 2/7] Add direct dev build download link to README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4689966e..89234b46 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ +

> [!WARNING] From deba3523eb764c20fee22c064912e64ebef3182d Mon Sep 17 00:00:00 2001 From: Su5eD Date: Thu, 22 Feb 2024 00:12:58 +0100 Subject: [PATCH 3/7] Add Cardinal Components API to test mods --- gradle.properties | 2 +- testmods.yaml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 2193cf71..2773467d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ versionForge=47.1.3 versionForgeAutoRenamingTool=1.0.9 versionFabricLoader=2.7.1+0.15.3+1.20.1 versionAccessWidener=2.1.0 -versionFabricApi=0.91.0+1.10.8+1.20.1 +versionFabricApi=0.92.0+1.11.2+1.20.1 versionMixin=0.12.5+mixin.0.8.5 versionMixinTransmog=0.4.3+1.20.1 diff --git a/testmods.yaml b/testmods.yaml index 97a0fed5..3c86f788 100644 --- a/testmods.yaml +++ b/testmods.yaml @@ -1,6 +1,9 @@ - id: fastback homepage: https://modrinth.com/mod/fastback maven: maven.modrinth:fastback:0.15.6+1.20.1-fabric +- id: cardinal-components + homepage: https://modrinth.com/mod/cardinal-components-api + maven: maven.modrinth:cardinal-components-api:5.2.2 # Requiring connector extras: - id: beaconoverhaul From 91fd982158ec29a35ed806db5432f2349e181aeb Mon Sep 17 00:00:00 2001 From: Su5eD Date: Fri, 23 Feb 2024 21:53:31 +0100 Subject: [PATCH 4/7] Improve mutable item attribute injector Fixes #845 --- .../connector/mod/ConnectorBootstrap.java | 23 ++++++++++++++++++- .../mod/mixin/item/ItemStackMixin.java | 10 -------- .../mod/mixin/item/LateItemStackMixin.java | 9 ++++++++ src/mod/resources/connectormod.mixins.json | 1 + 4 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/item/LateItemStackMixin.java diff --git a/src/mod/java/dev/su5ed/sinytra/connector/mod/ConnectorBootstrap.java b/src/mod/java/dev/su5ed/sinytra/connector/mod/ConnectorBootstrap.java index 842baf29..a91c3e72 100644 --- a/src/mod/java/dev/su5ed/sinytra/connector/mod/ConnectorBootstrap.java +++ b/src/mod/java/dev/su5ed/sinytra/connector/mod/ConnectorBootstrap.java @@ -2,10 +2,14 @@ import dev.su5ed.sinytra.connector.ConnectorUtil; import dev.su5ed.sinytra.connector.loader.ConnectorEarlyLoader; +import net.minecraftforge.coremod.api.ASMAPI; import net.minecraftforge.fml.CrashReportCallables; import net.minecraftforge.forgespi.language.IModInfo; import org.apache.commons.lang3.StringUtils; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.MethodInsnNode; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; @@ -57,6 +61,24 @@ public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { return !ConnectorEarlyLoader.hasEncounteredException(); } + @Override + public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { + if (mixinClassName.equals("dev.su5ed.sinytra.connector.mod.mixin.item.LateItemStackMixin")) { + String methodName = ASMAPI.mapMethod("m_41638_"); + targetClass.methods.stream() + .filter(m -> m.name.equals(methodName) && m.desc.equals("(Lnet/minecraft/world/entity/EquipmentSlot;)Lcom/google/common/collect/Multimap;")) + .findFirst() + .ifPresent(method -> { + for (AbstractInsnNode insn : method.instructions) { + if (insn.getOpcode() == Opcodes.ARETURN) { + method.instructions.insertBefore(insn, new MethodInsnNode(Opcodes.INVOKESTATIC, "com/google/common/collect/HashMultimap", "create", "(Lcom/google/common/collect/Multimap;)Lcom/google/common/collect/HashMultimap;", false)); + } + } + }); + + } + } + // We don't need any of the mixin stuff //@formatter:off @Override public void onLoad(String mixinPackage) {} @@ -64,6 +86,5 @@ public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { @Override public void acceptTargets(Set myTargets, Set otherTargets) {} @Override public List getMixins() {return null;} @Override public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} - @Override public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} //@formatter:on } diff --git a/src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/item/ItemStackMixin.java b/src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/item/ItemStackMixin.java index 8635b9da..bad46b61 100644 --- a/src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/item/ItemStackMixin.java +++ b/src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/item/ItemStackMixin.java @@ -1,13 +1,8 @@ package dev.su5ed.sinytra.connector.mod.mixin.item; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; import dev.su5ed.sinytra.connector.mod.compat.ItemStackExtensions; import net.minecraft.core.BlockPos; import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.ai.attributes.Attribute; -import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -38,9 +33,4 @@ public InteractionResult connector_useOn(UseOnContext context) { Item item = ((ItemStack) (Object) this).getItem(); return null; } - - @Inject(method = "getAttributeModifiers", at = @At("RETURN"), cancellable = true) - private void ensureMutableAttributeModifiers(EquipmentSlot slot, CallbackInfoReturnable> cir) { - cir.setReturnValue(HashMultimap.create(cir.getReturnValue())); - } } diff --git a/src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/item/LateItemStackMixin.java b/src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/item/LateItemStackMixin.java new file mode 100644 index 00000000..e5f9023d --- /dev/null +++ b/src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/item/LateItemStackMixin.java @@ -0,0 +1,9 @@ +package dev.su5ed.sinytra.connector.mod.mixin.item; + +import net.minecraft.world.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(value = ItemStack.class, priority = 9999) +public class LateItemStackMixin { + // Dummy class to serve as an entrypoint for our mixin plugin ASM hook +} diff --git a/src/mod/resources/connectormod.mixins.json b/src/mod/resources/connectormod.mixins.json index ae14c1f4..5d4dc834 100644 --- a/src/mod/resources/connectormod.mixins.json +++ b/src/mod/resources/connectormod.mixins.json @@ -12,6 +12,7 @@ "PoiTypesMixin", "TagLoaderMixin", "item.ItemStackMixin", + "item.LateItemStackMixin", "item.ForgeHooksMixin", "lang.PathPackResourcesAnonMixin", "lang.PathPackResourcesMixin", From 3508e0f58236e1c38269bec7af107103b4e30d09 Mon Sep 17 00:00:00 2001 From: Su5eD Date: Sat, 24 Feb 2024 14:10:31 +0100 Subject: [PATCH 5/7] Fix nightly download link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 89234b46..7b08bbe4 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ - +

> [!WARNING] From bdfa15f5edf274aca3970ac57f06806f6db0e4d4 Mon Sep 17 00:00:00 2001 From: Su5eD Date: Sun, 25 Feb 2024 00:21:31 +0100 Subject: [PATCH 6/7] Unify connector_global_mod_aliases into ConnectorConfig --- .../sinytra/connector/ConnectorUtil.java | 9 +- .../loader/ConnectorEarlyLoader.java | 3 + .../connector/locator/ConnectorConfig.java | 47 +++++- .../connector/locator/DependencyResolver.java | 7 +- .../connector/locator/GlobalModAliases.java | 137 ------------------ .../sinytra/connector/mod/ConnectorMod.java | 13 ++ 6 files changed, 66 insertions(+), 150 deletions(-) delete mode 100644 src/main/java/dev/su5ed/sinytra/connector/locator/GlobalModAliases.java diff --git a/src/main/java/dev/su5ed/sinytra/connector/ConnectorUtil.java b/src/main/java/dev/su5ed/sinytra/connector/ConnectorUtil.java index 974f3fd1..a8f9dae3 100644 --- a/src/main/java/dev/su5ed/sinytra/connector/ConnectorUtil.java +++ b/src/main/java/dev/su5ed/sinytra/connector/ConnectorUtil.java @@ -1,7 +1,5 @@ package dev.su5ed.sinytra.connector; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.Multimap; import com.google.common.hash.Hashing; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -20,6 +18,7 @@ import java.nio.file.Path; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.regex.Pattern; @@ -114,9 +113,9 @@ public final class ConnectorUtil { ); // Common aliased mod dependencies that don't work with forge ports, which use a different modid. // They're too annoying to override individually in each mod, so we provide this small QoL feature for the user's comfort - public static final Multimap DEFAULT_GLOBAL_MOD_ALIASES = ImmutableMultimap.of( - "cloth_config", "cloth-config2", - "playeranimator", "player-animator" + public static final Map> DEFAULT_GLOBAL_MOD_ALIASES = Map.of( + "cloth_config", List.of("cloth-config2"), + "playeranimator", List.of("player-animator") ); private static final boolean CACHE_ENABLED; diff --git a/src/main/java/dev/su5ed/sinytra/connector/loader/ConnectorEarlyLoader.java b/src/main/java/dev/su5ed/sinytra/connector/loader/ConnectorEarlyLoader.java index 07e76623..89be228e 100644 --- a/src/main/java/dev/su5ed/sinytra/connector/loader/ConnectorEarlyLoader.java +++ b/src/main/java/dev/su5ed/sinytra/connector/loader/ConnectorEarlyLoader.java @@ -96,6 +96,9 @@ public static void init() { LOGGER.debug("Starting early connector loader setup"); ProgressMeter progress = StartupNotificationManager.addProgressBar("[Connector] Early Setup", 0); try { + if (ConnectorConfig.usesUnsupportedConfiguration()) { + LOGGER.warn("Outdated connector_global_mod_aliases.json configuration file detected. Please migrate to the new connector.json configuration."); + } List hiddenMods = ConnectorConfig.INSTANCE.get().hiddenMods(); // Find all connector loader mods List mods = LoadingModList.get().getMods().stream() diff --git a/src/main/java/dev/su5ed/sinytra/connector/locator/ConnectorConfig.java b/src/main/java/dev/su5ed/sinytra/connector/locator/ConnectorConfig.java index 0bb8d74f..ee6106c0 100644 --- a/src/main/java/dev/su5ed/sinytra/connector/locator/ConnectorConfig.java +++ b/src/main/java/dev/su5ed/sinytra/connector/locator/ConnectorConfig.java @@ -3,7 +3,15 @@ import com.google.common.base.Suppliers; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.mojang.datafixers.util.Either; import com.mojang.logging.LogUtils; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.JsonOps; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import dev.su5ed.sinytra.connector.ConnectorUtil; import net.minecraftforge.fml.loading.FMLPaths; import org.slf4j.Logger; @@ -11,27 +19,56 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; import java.util.function.Supplier; -public record ConnectorConfig(List hiddenMods) { - private static final ConnectorConfig DEFAULT = new ConnectorConfig(List.of()); +public record ConnectorConfig(int version, List hiddenMods, Map> globalModAliases) { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.INT + .comapFlatMap(i -> i == 1 ? DataResult.success(i) : DataResult.error(() -> "Unsupported \"version\", must be 1"), Function.identity()) + .optionalFieldOf("version") + .forGetter(c -> Optional.of(c.version())), + Codec.STRING + .listOf() + .optionalFieldOf("hiddenMods") + .forGetter(c -> Optional.of(c.hiddenMods())), + Codec.unboundedMap( + Codec.STRING, + Codec.either(Codec.STRING.listOf(), Codec.STRING).xmap(either -> either.map(list -> list, List::of), list -> list.size() == 1 ? Either.right(list.get(0)) : Either.left(list)) + ) + .optionalFieldOf("globalModAliases", Map.of()) + .forGetter(ConnectorConfig::globalModAliases) + ).apply(instance, ConnectorConfig::new)); + + ConnectorConfig(Optional version, Optional> hiddenMods, Map> globalModAliases) { + this(version.orElse(1), hiddenMods.orElseGet(List::of), globalModAliases); + } + + private static final ConnectorConfig DEFAULT = new ConnectorConfig(1, List.of(), ConnectorUtil.DEFAULT_GLOBAL_MOD_ALIASES); private static final Logger LOGGER = LogUtils.getLogger(); public static final Supplier INSTANCE = Suppliers.memoize(() -> { Path path = FMLPaths.CONFIGDIR.get().resolve("connector.json"); try { if (Files.exists(path)) { - Gson gson = new Gson(); try (Reader reader = Files.newBufferedReader(path)) { - return gson.fromJson(reader, ConnectorConfig.class); + JsonElement element = JsonParser.parseReader(reader); + return CODEC.decode(JsonOps.INSTANCE, element).getOrThrow(false, s -> {}).getFirst(); } } else { + JsonElement element = CODEC.encodeStart(JsonOps.INSTANCE, DEFAULT).getOrThrow(false, s -> {}); Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); - Files.writeString(path, gson.toJson(DEFAULT)); + Files.writeString(path, gson.toJson(element)); } } catch (Throwable t) { LOGGER.error("Error loading Connector configuration", t); } return DEFAULT; }); + + public static boolean usesUnsupportedConfiguration() { + return Files.exists(FMLPaths.CONFIGDIR.get().resolve("connector_global_mod_aliases.json")); + } } diff --git a/src/main/java/dev/su5ed/sinytra/connector/locator/DependencyResolver.java b/src/main/java/dev/su5ed/sinytra/connector/locator/DependencyResolver.java index 115ec8da..a189a7db 100644 --- a/src/main/java/dev/su5ed/sinytra/connector/locator/DependencyResolver.java +++ b/src/main/java/dev/su5ed/sinytra/connector/locator/DependencyResolver.java @@ -3,9 +3,9 @@ import com.google.common.base.Suppliers; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; +import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.mojang.logging.LogUtils; -import dev.su5ed.sinytra.connector.ConnectorUtil; import dev.su5ed.sinytra.connector.loader.ConnectorEarlyLoader; import dev.su5ed.sinytra.connector.transformer.jar.JarTransformer; import net.fabricmc.api.EnvType; @@ -46,11 +46,12 @@ public final class DependencyResolver { private static final Logger LOGGER = LogUtils.getLogger(); public static final VersionOverrides VERSION_OVERRIDES = new VersionOverrides(); public static final Supplier DEPENDENCY_OVERRIDES = Suppliers.memoize(() -> loadConfigFile("fabric_loader_dependencies.json", () -> new DependencyOverrides(FMLPaths.CONFIGDIR.get()))); - private static final Supplier GLOBAL_MOD_ALIASES = Suppliers.memoize(() -> loadConfigFile("connector_global_mod_aliases.json", () -> new GlobalModAliases(FMLPaths.CONFIGDIR.get(), ConnectorUtil.DEFAULT_GLOBAL_MOD_ALIASES))); public static List resolveDependencies(Collection keys, Multimap jars, Iterable loadedMods) { // Add global mod aliases - FabricLoaderImpl.INSTANCE.aliasMods(GLOBAL_MOD_ALIASES.get().getAliases()); + Multimap aliases = HashMultimap.create(); + ConnectorConfig.INSTANCE.get().globalModAliases().forEach(aliases::putAll); + FabricLoaderImpl.INSTANCE.aliasMods(aliases); BiMap jarToCandidate = HashBiMap.create(); // Fabric candidates List candidates = createCandidatesRecursive(keys, keys, jars, jarToCandidate); diff --git a/src/main/java/dev/su5ed/sinytra/connector/locator/GlobalModAliases.java b/src/main/java/dev/su5ed/sinytra/connector/locator/GlobalModAliases.java deleted file mode 100644 index 5d6b73ea..00000000 --- a/src/main/java/dev/su5ed/sinytra/connector/locator/GlobalModAliases.java +++ /dev/null @@ -1,137 +0,0 @@ -package dev.su5ed.sinytra.connector.locator; - -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.Multimap; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.stream.JsonWriter; -import com.mojang.logging.LogUtils; -import net.fabricmc.loader.impl.FormattedException; -import net.fabricmc.loader.impl.lib.gson.JsonReader; -import net.fabricmc.loader.impl.lib.gson.JsonToken; -import net.fabricmc.loader.impl.metadata.ParseMetadataException; -import net.fabricmc.loader.impl.util.LoaderUtil; -import org.slf4j.Logger; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collection; -import java.util.Map; - -public class GlobalModAliases { - private static final Logger LOGGER = LogUtils.getLogger(); - - private final Multimap aliases; - - public GlobalModAliases(Path configDir, Multimap defaultValues) { - Path path = configDir.resolve("connector_global_mod_aliases.json"); - - if (!Files.exists(path)) { - this.aliases = ImmutableMultimap.copyOf(defaultValues); - write(path); - return; - } - - try (JsonReader reader = new JsonReader(new InputStreamReader(Files.newInputStream(path), StandardCharsets.UTF_8))) { - this.aliases = parse(reader); - } catch (IOException | ParseMetadataException e) { - throw FormattedException.ofLocalized("exception.parsingOverride", "Failed to parse " + LoaderUtil.normalizePath(path), e); - } - } - - public Multimap getAliases() { - return this.aliases; - } - - private Multimap parse(JsonReader reader) throws IOException, ParseMetadataException { - if (reader.peek() != JsonToken.BEGIN_OBJECT) { - throw new ParseMetadataException("Root must be an object", reader); - } - - reader.beginObject(); - - if (!reader.nextName().equals("version")) { - throw new ParseMetadataException("First key must be \"version\"", reader); - } - - if (reader.peek() != JsonToken.NUMBER || reader.nextInt() != 1) { - throw new ParseMetadataException("Unsupported \"version\", must be 1", reader); - } - - ImmutableMultimap.Builder aliases = ImmutableMultimap.builder(); - - while (reader.hasNext()) { - String key = reader.nextName(); - - if ("aliases".equals(key)) { - reader.beginObject(); - - while (reader.hasNext()) { - String modid = reader.nextName(); - - switch (reader.peek()) { - case STRING -> { - String alias = reader.nextString(); - aliases.put(modid, alias); - } - case BEGIN_ARRAY -> { - reader.beginArray(); - while (reader.hasNext()) { - String alias = reader.nextString(); - aliases.put(modid, alias); - } - reader.endArray(); - } - default -> throw new ParseMetadataException("Mod aliases must be a string or string array!", reader); - } - } - - reader.endObject(); - } - else { - throw new ParseMetadataException("Unsupported root key: " + key, reader); - } - } - - reader.endObject(); - - return aliases.build(); - } - - private void write(Path path) { - Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); - try { - Files.createDirectories(path.getParent()); - - try (JsonWriter writer = gson.newJsonWriter(Files.newBufferedWriter(path))) { - writer.beginObject(); - - writer.name("version").value(1); - - writer.name("aliases").beginObject(); - for (Map.Entry> entry : this.aliases.asMap().entrySet()) { - Collection values = entry.getValue(); - writer.name(entry.getKey()); - if (values.size() == 1) { - writer.value(values.iterator().next()); - } - else { - writer.beginArray(); - for (String value : values) { - writer.value(value); - } - writer.endArray(); - } - } - writer.endObject(); - - writer.endObject(); - } - } catch (IOException e) { - LOGGER.error("Error writing default global mod aliases", e); - } - } -} diff --git a/src/mod/java/dev/su5ed/sinytra/connector/mod/ConnectorMod.java b/src/mod/java/dev/su5ed/sinytra/connector/mod/ConnectorMod.java index 7f8f7f20..83f63298 100644 --- a/src/mod/java/dev/su5ed/sinytra/connector/mod/ConnectorMod.java +++ b/src/mod/java/dev/su5ed/sinytra/connector/mod/ConnectorMod.java @@ -1,6 +1,7 @@ package dev.su5ed.sinytra.connector.mod; import dev.su5ed.sinytra.connector.ConnectorUtil; +import dev.su5ed.sinytra.connector.locator.ConnectorConfig; import dev.su5ed.sinytra.connector.mod.compat.FluidHandlerCompat; import dev.su5ed.sinytra.connector.mod.compat.LateRenderTypesInit; import dev.su5ed.sinytra.connector.mod.compat.LateSheetsInit; @@ -8,6 +9,10 @@ import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.ModList; +import net.minecraftforge.fml.ModLoader; +import net.minecraftforge.fml.ModLoadingContext; +import net.minecraftforge.fml.ModLoadingStage; +import net.minecraftforge.fml.ModLoadingWarning; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent; @@ -36,6 +41,14 @@ public ConnectorMod() { if (modList.isLoaded("fabric_object_builder_api_v1")) { bus.addListener(EventPriority.HIGHEST, LazyEntityAttributes::initializeLazyAttributes); } + + if (ConnectorConfig.usesUnsupportedConfiguration()) { + ModLoader.get().addWarning(new ModLoadingWarning( + ModLoadingContext.get().getActiveContainer().getModInfo(), + ModLoadingStage.CONSTRUCT, + "Outdated connector_global_mod_aliases.json configuration file detected. Please migrate to the new connector.json configuration." + )); + } } private static void onClientSetup(FMLClientSetupEvent event) { From 6914b3e18325f1d4019772989b95ff1c8709bc04 Mon Sep 17 00:00:00 2001 From: Su5eD Date: Sun, 25 Feb 2024 13:36:31 +0100 Subject: [PATCH 7/7] Update README to include docs website link --- README.md | 54 +++--------------------------------------------------- 1 file changed, 3 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 7b08bbe4..2e2359e0 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ on [MinecraftForge](https://minecraftforge.net). Its goal is to bring the two pl developers time and effort maintaining their mods for multiple platforms at once, as well as allowing players to play all their favourite mods in one modpack. +**📘 The official documentation is available at [sinytra.org](https://sinytra.org/docs).** + ### 🔗 Related Projects - Visit the [Mod Compatibility Thread](https://github.com/Sinytra/Connector/discussions/12) to can find information about known working / incompatible mods @@ -132,54 +134,4 @@ afterEvaluate { ## ⚙️ Configuration -### Global Mod Aliases - -To improve mod compatibility, Connector provides a Global Mod Alias feature that can be used to provide alternative IDs -for mods in the fabric loader. Similar to fabric's [Dependency Overrides](https://fabricmc.net/wiki/tutorial:dependency_overrides), -it uses a json config file to define aliases. - -Global Mod Aliases are defined in a file named `connector_global_mod_aliases.json`, located inside your config folder. -If it doesn't exist yet, Connector will create a new one with its default mod aliases. - -Here's a minimal configuration example: -```json -{ - "version": 1, - "aliases": { - "cloth_config": "cloth-config2", - "embeddium": [ - "sodium", - "magnesium" - ] - } -} -``` - -Let's go over it line-by-line. -- First, we have `version`, which specifies the config file spec version we would like to use. - At the time of writing, the latest version is version 1. -- Secondly, we have `aliases`. This JSON object contains all of our alises for various mods. - Keys inside the object represent mod IDs to be aliased. The value can be either a single **string**, or an **array** in case - we want to provide multiple aliases for one mod. - -### Hiding Forge mods' presence - -Fabric mods tend to integrate with others based on their modid. If you happen to install a Forge version of a mod that -a Fabric mod wants to integrate with, it might result in a crash, as the two versions' code is different. -Most of the time, mods provide toggles for integrations in their config. If that's not the case, your other option is -hiding the Forge mod's presence from Fabric mods entirely, which might help in disabling the problematic integration. - -This can be configured in the `connector.json` file, located in your config folder. -If it doesn't exist yet, Connector will create a new one with empty values. - -Inside, the `hiddenMods` field is defined as a list of mod IDs (strings). Forge mod IDs found in this list will be -excluded from being added to `FabricLoader`, hiding their presence from Fabric mods. - -Here's a minimal configuration example: -```json -{ - "hiddenMods": [ - "examplemod" - ] -} -``` +All information regarding Connector's configuration options can be found [here](https://sinytra.org/docs). \ No newline at end of file