Skip to content

Commit

Permalink
Develop beta 37 (#808)
Browse files Browse the repository at this point in the history
  • Loading branch information
Su5eD committed Feb 27, 2024
2 parents 0514fec + 6914b3e commit cf46217
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 214 deletions.
55 changes: 4 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<a href="https://modrinth.com/mod/connector"><img src="https://img.shields.io/modrinth/dt/u58R1TMW?color=00AF5C&label=modrinth&style=flat&logo=modrinth"></a>
<a href="https://github.com/Sinytra/ForgifiedFabricAPI"><img src="https://raw.githubusercontent.com/Sinytra/.github/main/badges/forgified-fabric-api/compacter.svg"></a>
<a href="https://discord.gg/mamk7z3TKZ"><img src="https://discordapp.com/api/guilds/1141048834177388746/widget.png?style=shield"></a>
<a href="https://nightly.link/Sinytra/Connector/workflows/build/dev/Maven%20Local.zip"><img src="https://img.shields.io/badge/Nightly-Download-9a32f0?logo=github"></a>
</p>

> [!WARNING]
Expand All @@ -24,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
Expand Down Expand Up @@ -131,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).
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down
9 changes: 4 additions & 5 deletions src/main/java/dev/su5ed/sinytra/connector/ConnectorUtil.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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<String, String> DEFAULT_GLOBAL_MOD_ALIASES = ImmutableMultimap.of(
"cloth_config", "cloth-config2",
"playeranimator", "player-animator"
public static final Map<String, List<String>> DEFAULT_GLOBAL_MOD_ALIASES = Map.of(
"cloth_config", List.of("cloth-config2"),
"playeranimator", List.of("player-animator")
);

private static final boolean CACHE_ENABLED;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> hiddenMods = ConnectorConfig.INSTANCE.get().hiddenMods();
// Find all connector loader mods
List<ModInfo> mods = LoadingModList.get().getMods().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,72 @@
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;

import java.io.Reader;
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<String> hiddenMods) {
private static final ConnectorConfig DEFAULT = new ConnectorConfig(List.of());
public record ConnectorConfig(int version, List<String> hiddenMods, Map<String, List<String>> globalModAliases) {
public static final Codec<ConnectorConfig> 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<Integer> version, Optional<List<String>> hiddenMods, Map<String, List<String>> 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<ConnectorConfig> 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"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<DependencyOverrides> DEPENDENCY_OVERRIDES = Suppliers.memoize(() -> loadConfigFile("fabric_loader_dependencies.json", () -> new DependencyOverrides(FMLPaths.CONFIGDIR.get())));
private static final Supplier<GlobalModAliases> GLOBAL_MOD_ALIASES = Suppliers.memoize(() -> loadConfigFile("connector_global_mod_aliases.json", () -> new GlobalModAliases(FMLPaths.CONFIGDIR.get(), ConnectorUtil.DEFAULT_GLOBAL_MOD_ALIASES)));

public static List<JarTransformer.TransformableJar> resolveDependencies(Collection<JarTransformer.TransformableJar> keys, Multimap<JarTransformer.TransformableJar, JarTransformer.TransformableJar> jars, Iterable<IModFile> loadedMods) {
// Add global mod aliases
FabricLoaderImpl.INSTANCE.aliasMods(GLOBAL_MOD_ALIASES.get().getAliases());
Multimap<String, String> aliases = HashMultimap.create();
ConnectorConfig.INSTANCE.get().globalModAliases().forEach(aliases::putAll);
FabricLoaderImpl.INSTANCE.aliasMods(aliases);
BiMap<JarTransformer.TransformableJar, ModCandidate> jarToCandidate = HashBiMap.create();
// Fabric candidates
List<ModCandidate> candidates = createCandidatesRecursive(keys, keys, jars, jarToCandidate);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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<VersionInterval> 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
Expand Down
Loading

0 comments on commit cf46217

Please sign in to comment.