Skip to content

Commit a59dbd2

Browse files
authored
Develop beta 41 (#935)
2 parents e40dcef + 63bd0ff commit a59dbd2

17 files changed

+263
-83
lines changed

build.gradle.kts

+2-2
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,8 @@ dependencies {
320320
shade(group = "io.github.steelwoolmc", name = "mixin-transmogrifier", version = versionMixinTransmog)
321321
adapterData(group = "org.sinytra.adapter", name = "adapter", version = versionAdapter)
322322

323-
annotationProcessor(group = "net.fabricmc", name = "sponge-mixin", version = versionMixin)
324-
compileOnly(group = "net.fabricmc", name = "sponge-mixin", version = versionMixin)
323+
annotationProcessor(group = "org.sinytra", name = "sponge-mixin", version = versionMixin)
324+
compileOnly(group = "org.sinytra", name = "sponge-mixin", version = versionMixin)
325325
implementation(jarJar("io.github.llamalad7:mixinextras-forge:${mixinextrasVersion}")!!) {
326326
jarJar.ranged(this, "[${mixinextrasVersion},)")
327327
}

gradle.properties

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@ org.gradle.jvmargs=-Xmx3G
44
org.gradle.daemon=true
55

66
# Versions
7-
versionConnector=1.0.0-beta.40
8-
versionAdapter=1.11.32-1.20.1-20240314.234555
9-
versionAdapterDefinition=1.11.34
7+
versionConnector=1.0.0-beta.41
8+
versionAdapter=1.11.39-1.20.1-20240406.124555
9+
versionAdapterDefinition=1.11.39
1010

1111
versionMc=1.20.1
1212
versionForge=47.1.3
1313
versionForgeAutoRenamingTool=1.0.11
1414
versionFabricLoader=2.7.2+0.15.3+1.20.1
1515
versionAccessWidener=2.1.0
16-
versionFabricApi=0.92.0+1.11.2+1.20.1
17-
versionMixin=0.12.5+mixin.0.8.5
18-
versionMixinTransmog=0.4.3+1.20.1
16+
versionFabricApi=0.92.0+1.11.5+1.20.1
17+
versionMixin=0.12.10+mixin.0.8.5
18+
versionMixinTransmog=0.4.5+1.20.1
1919

2020
# Publishing
2121
curseForgeId=890127

src/main/java/dev/su5ed/sinytra/connector/locator/ConnectorLocator.java

+46-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.su5ed.sinytra.connector.locator;
22

3+
import com.electronwill.nightconfig.core.file.FileConfig;
34
import com.google.common.collect.HashMultimap;
45
import com.google.common.collect.Multimap;
56
import com.mojang.logging.LogUtils;
@@ -8,6 +9,7 @@
89
import dev.su5ed.sinytra.connector.loader.ConnectorEarlyLoader;
910
import dev.su5ed.sinytra.connector.loader.ConnectorLoaderModMetadata;
1011
import dev.su5ed.sinytra.connector.transformer.jar.JarTransformer;
12+
import net.fabricmc.loader.api.FabricLoader;
1113
import net.fabricmc.loader.impl.metadata.NestedJarEntry;
1214
import net.minecraftforge.fml.loading.ClasspathLocatorUtils;
1315
import net.minecraftforge.fml.loading.EarlyLoadingException;
@@ -19,6 +21,7 @@
1921
import net.minecraftforge.fml.loading.moddiscovery.AbstractJarFileModProvider;
2022
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
2123
import net.minecraftforge.fml.loading.moddiscovery.ModJarMetadata;
24+
import net.minecraftforge.fml.loading.moddiscovery.NightConfigWrapper;
2225
import net.minecraftforge.fml.loading.progress.StartupNotificationManager;
2326
import net.minecraftforge.forgespi.language.IModInfo;
2427
import net.minecraftforge.forgespi.locating.IDependencyLocator;
@@ -60,6 +63,7 @@
6063
public class ConnectorLocator extends AbstractJarFileModProvider implements IDependencyLocator {
6164
private static final String NAME = "connector_locator";
6265
private static final String SUFFIX = ".jar";
66+
private static final String PLACEHOLDER_PROPERTY = "connector:placeholder";
6367

6468
private static final Logger LOGGER = LogUtils.getLogger();
6569
private static final MethodHandle MJM_INIT = uncheck(() -> MethodHandles.privateLookupIn(ModJarMetadata.class, MethodHandles.lookup()).findConstructor(ModJarMetadata.class, MethodType.methodType(void.class)));
@@ -86,58 +90,65 @@ public List<IModFile> scanMods(Iterable<IModFile> loadedMods) {
8690
return List.of();
8791
}
8892

89-
private List<IModFile> locateFabricMods(Iterable<IModFile> loadedMods) {
93+
private List<IModFile> locateFabricMods(Iterable<IModFile> discoveredMods) {
9094
LOGGER.debug(SCAN, "Scanning mods dir {} for mods", FMLPaths.MODSDIR.get());
9195
Path tempDir = ConnectorUtil.CONNECTOR_FOLDER.resolve("temp");
9296
// Get all existing mod ids
93-
Collection<SimpleModInfo> loadedModInfos = StreamSupport.stream(loadedMods.spliterator(), false)
97+
Collection<SimpleModInfo> loadedModInfos = StreamSupport.stream(discoveredMods.spliterator(), false)
9498
.flatMap(modFile -> Optional.ofNullable(modFile.getModFileInfo()).stream())
9599
.flatMap(modFileInfo -> {
96100
IModFile modFile = modFileInfo.getFile();
97101
List<IModInfo> modInfos = modFileInfo.getMods();
102+
// Ignore placeholder mods
103+
if (modFileInfo.getFileProperties().containsKey(PLACEHOLDER_PROPERTY)) {
104+
// Set mod version to 0.0 to prioritize the Fabric mod when FML resolves duplicates
105+
modInfos.forEach(mod -> mod.getVersion().parseVersion("0.0"));
106+
return Stream.empty();
107+
}
98108
if (!modInfos.isEmpty()) {
99109
return modInfos.stream().map(modInfo -> new SimpleModInfo(modInfo.getModId(), modInfo.getVersion(), false, modFile));
100110
}
101111
String version = modFileInfo.getFile().getSecureJar().moduleDataProvider().descriptor().version().map(ModuleDescriptor.Version::toString).orElse("0.0");
102112
return Stream.of(new SimpleModInfo(modFileInfo.moduleName(), new DefaultArtifactVersion(version), true, modFile));
103113
})
104114
.toList();
115+
Collection<IModFile> loadedModFiles = loadedModInfos.stream().map(SimpleModInfo::origin).toList();
105116
Collection<String> loadedModIds = loadedModInfos.stream().filter(mod -> !mod.library()).map(SimpleModInfo::modid).collect(Collectors.toUnmodifiableSet());
106117
// Discover fabric mod jars
107118
List<Path> excluded = ModDirTransformerDiscoverer.allExcluded();
108119
List<JarTransformer.TransformableJar> discoveredJars = Stream.of(scanModsDir(excluded), scanClasspath(), scanFromArguments(excluded)).flatMap(s -> s)
109120
.map(rethrowFunction(p -> cacheTransformableJar(p.toFile())))
110121
.filter(jar -> {
111-
String modid = jar.modPath().metadata().modMetadata().getId();
112-
return !shouldIgnoreMod(modid, loadedModIds);
122+
ConnectorLoaderModMetadata metadata = jar.modPath().metadata().modMetadata();
123+
return !shouldIgnoreMod(metadata, loadedModIds);
113124
})
114125
.toList();
115126
Multimap<JarTransformer.TransformableJar, JarTransformer.TransformableJar> parentToChildren = HashMultimap.create();
116127
// Discover fabric nested mod jars
117128
List<JarTransformer.TransformableJar> discoveredNestedJars = discoveredJars.stream()
118129
.flatMap(jar -> {
119130
ConnectorLoaderModMetadata metadata = jar.modPath().metadata().modMetadata();
120-
return shouldIgnoreMod(metadata.getId(), loadedModIds) ? Stream.empty() : discoverNestedJarsRecursive(tempDir, jar, metadata.getJars(), parentToChildren, loadedModIds);
131+
return shouldIgnoreMod(metadata, loadedModIds) ? Stream.empty() : discoverNestedJarsRecursive(tempDir, jar, metadata.getJars(), parentToChildren, loadedModIds);
121132
})
122133
.toList();
123134
// Collect mods that are (likely) going to be excluded by FML's UniqueModListBuilder. Exclude them from global split package filtering
124135
Collection<? super IModFile> ignoredModFiles = new ArrayList<>();
125136
// Remove mods loaded by FML
126137
List<JarTransformer.TransformableJar> uniqueJars = handleDuplicateMods(discoveredJars, discoveredNestedJars, loadedModInfos, ignoredModFiles);
127138
// Ensure we have all required dependencies before transforming
128-
List<JarTransformer.TransformableJar> candidates = DependencyResolver.resolveDependencies(uniqueJars, parentToChildren, loadedMods);
139+
List<JarTransformer.TransformableJar> candidates = DependencyResolver.resolveDependencies(uniqueJars, parentToChildren, loadedModFiles);
129140
// Get renamer library classpath
130-
List<Path> renameLibs = StreamSupport.stream(loadedMods.spliterator(), false).map(modFile -> modFile.getSecureJar().getRootPath()).toList();
141+
List<Path> renameLibs = loadedModFiles.stream().map(modFile -> modFile.getSecureJar().getRootPath()).toList();
131142
// Run jar transformations (or get existing outputs from cache)
132-
List<JarTransformer.FabricModPath> transformed = JarTransformer.transform(candidates, renameLibs, loadedMods);
143+
List<JarTransformer.FabricModPath> transformed = JarTransformer.transform(candidates, renameLibs, loadedModFiles);
133144
// Skip last step to save time if an error occured during transformation
134145
if (ConnectorEarlyLoader.hasEncounteredException()) {
135146
StartupNotificationManager.addModMessage("JAR TRANSFORMATION ERROR");
136147
LOGGER.error("Cancelling jar discovery due to previous error");
137148
return List.of();
138149
}
139150
// Deal with split packages (thanks modules)
140-
List<SplitPackageMerger.FilteredModPath> moduleSafeJars = SplitPackageMerger.mergeSplitPackages(transformed, loadedMods, ignoredModFiles);
151+
List<SplitPackageMerger.FilteredModPath> moduleSafeJars = SplitPackageMerger.mergeSplitPackages(transformed, loadedModFiles, ignoredModFiles);
141152

142153
List<IModFile> modFiles = new ArrayList<>(moduleSafeJars.stream().map(this::createConnectorModFile).toList());
143154
// Create mod file for generated adapter mixins jar
@@ -154,9 +165,9 @@ private Stream<Path> scanModsDir(List<Path> excluded) {
154165

155166
private Stream<Path> filterPaths(Stream<Path> stream, List<Path> excluded) {
156167
return stream
157-
.filter(p -> !excluded.contains(p) && StringUtils.toLowerCase(p.getFileName().toString()).endsWith(SUFFIX))
158-
.sorted(Comparator.comparing(path -> StringUtils.toLowerCase(path.getFileName().toString())))
159-
.filter(ConnectorLocator::isFabricModJar);
168+
.filter(p -> !excluded.contains(p) && StringUtils.toLowerCase(p.getFileName().toString()).endsWith(SUFFIX))
169+
.sorted(Comparator.comparing(path -> StringUtils.toLowerCase(path.getFileName().toString())))
170+
.filter(ConnectorLocator::isFabricModJar);
160171
}
161172

162173
private Stream<Path> scanClasspath() {
@@ -190,7 +201,8 @@ private Stream<Path> scanFromArguments(List<Path> excluded) {
190201
Arrays.stream(paths).filter(s -> !s.isBlank()).map(Path::of).forEach(path -> {
191202
if (Files.isDirectory(path)) {
192203
uncheck(() -> Files.list(path)).forEach(files::add);
193-
} else {
204+
}
205+
else {
194206
files.add(path);
195207
}
196208
});
@@ -216,7 +228,8 @@ private IModFile createModOrThrow(Path... paths) {
216228
private static boolean isFabricModJar(Path path) {
217229
SecureJar secureJar = SecureJar.from(path);
218230
String name = secureJar.name();
219-
if (secureJar.moduleDataProvider().findFile(ConnectorUtil.MODS_TOML).isPresent()) {
231+
Path modsToml = secureJar.getPath(ConnectorUtil.MODS_TOML);
232+
if (Files.exists(modsToml) && !containsPlaceholder(modsToml)) {
220233
LOGGER.debug(SCAN, "Skipping jar {} as it contains a mods.toml file", path);
221234
return false;
222235
}
@@ -228,6 +241,21 @@ private static boolean isFabricModJar(Path path) {
228241
return false;
229242
}
230243

244+
private static boolean containsPlaceholder(Path modsTomlPath) {
245+
try {
246+
FileConfig fileConfig = FileConfig.of(modsTomlPath);
247+
fileConfig.load();
248+
fileConfig.close();
249+
NightConfigWrapper config = new NightConfigWrapper(fileConfig);
250+
return config.<Map<String, Object>>getConfigElement("properties")
251+
.map(map -> map.containsKey(PLACEHOLDER_PROPERTY))
252+
.orElse(false);
253+
} catch (Throwable t) {
254+
LOGGER.error("Error reading placeholder information from {}", modsTomlPath, t);
255+
return false;
256+
}
257+
}
258+
231259
private static Stream<JarTransformer.TransformableJar> discoverNestedJarsRecursive(Path tempDir, JarTransformer.TransformableJar parent, Collection<NestedJarEntry> jars, Multimap<JarTransformer.TransformableJar, JarTransformer.TransformableJar> parentToChildren, Collection<String> loadedModIds) {
232260
SecureJar secureJar = SecureJar.from(parent.input().toPath());
233261
return jars.stream()
@@ -236,7 +264,7 @@ private static Stream<JarTransformer.TransformableJar> discoverNestedJarsRecursi
236264
.flatMap(path -> {
237265
JarTransformer.TransformableJar jar = uncheck(() -> prepareNestedJar(tempDir, secureJar.getPrimaryPath().getFileName().toString(), path));
238266
ConnectorLoaderModMetadata metadata = jar.modPath().metadata().modMetadata();
239-
if (shouldIgnoreMod(metadata.getId(), loadedModIds)) {
267+
if (shouldIgnoreMod(metadata, loadedModIds)) {
240268
return Stream.empty();
241269
}
242270
parentToChildren.put(parent, jar);
@@ -289,7 +317,9 @@ private static List<JarTransformer.TransformableJar> handleDuplicateMods(List<Ja
289317
.toList();
290318
}
291319

292-
private static boolean shouldIgnoreMod(String id, Collection<String> loadedModIds) {
320+
private static boolean shouldIgnoreMod(ConnectorLoaderModMetadata metadata, Collection<String> loadedModIds) {
321+
if (!metadata.loadsInEnvironment(FabricLoader.getInstance().getEnvironmentType())) return true;
322+
String id = metadata.getId();
293323
return ConnectorUtil.DISABLED_MODS.contains(id) || loadedModIds.contains(id);
294324
}
295325

src/main/java/dev/su5ed/sinytra/connector/locator/ConnectorModMetadataParser.java

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
import java.util.regex.Pattern;
2424
import java.util.stream.Collectors;
2525

26+
/**
27+
* Parses Fabric mod JSON metadata into TOML format at runtime.
28+
*/
2629
public final class ConnectorModMetadataParser {
2730
private static final String DEFAULT_LICENSE = "All Rights Reserved";
2831
// From ModInfo

src/main/java/dev/su5ed/sinytra/connector/locator/EmbeddedDependencies.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.google.common.base.Suppliers;
44
import com.google.common.collect.ImmutableMap;
55
import com.mojang.logging.LogUtils;
6+
import net.minecraftforge.fml.loading.FMLEnvironment;
67
import org.apache.commons.lang3.RandomStringUtils;
78
import org.jetbrains.annotations.Nullable;
89
import org.slf4j.Logger;
@@ -55,7 +56,7 @@ public final class EmbeddedDependencies {
5556
// Return a random string to still write an input file, so that once we have a proper version available we refresh the cache
5657
return RandomStringUtils.randomAlphabetic(5);
5758
}
58-
return ver;
59+
return ver + "," + FMLEnvironment.dist.name().toLowerCase();
5960
});
6061

6162
/**

src/main/java/dev/su5ed/sinytra/connector/service/ConnectorLoaderService.java

+5
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ public class ConnectorLoaderService implements ITransformationService {
3939
private static final String AUTHLIB_MODULE = "authlib";
4040
private static final Logger LOGGER = LogUtils.getLogger();
4141

42+
static {
43+
// Enable frame expansion fixes on our mixin fork
44+
System.setProperty("mixin.env.fixFrameExpansion", "true");
45+
}
46+
4247
@Override
4348
public String name() {
4449
return NAME;

src/main/java/dev/su5ed/sinytra/connector/service/FabricMixinBootstrap.java

+9-4
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,15 @@ static void apply(Map<String, ModFileInfo> configToModMap) {
8686
config.decorate(FabricUtil.KEY_MOD_ID, mod.moduleName());
8787
if (!mod.getMods().isEmpty()) {
8888
String modid = mod.getMods().get(0).getModId();
89-
int compat = ConnectorEarlyLoader.isConnectorMod(modid) ? FabricLoaderImpl.INSTANCE.getModContainer(modid)
90-
.map(m -> getMixinCompat(m.getMetadata()))
91-
.orElse(FabricUtil.COMPATIBILITY_0_10_0)
92-
: FabricUtil.COMPATIBILITY_0_10_0;
89+
int compat;
90+
if (ConnectorEarlyLoader.isConnectorMod(modid)) {
91+
compat = FabricLoaderImpl.INSTANCE.getModContainer(modid)
92+
.map(m -> getMixinCompat(m.getMetadata()))
93+
.orElse(FabricUtil.COMPATIBILITY_0_10_0);
94+
config.decorate(FabricUtil.KEY_FIX_FRAME_EXPANSION, true);
95+
} else {
96+
compat = FabricUtil.COMPATIBILITY_0_10_0;
97+
}
9398
config.decorate(FabricUtil.KEY_COMPATIBILITY, compat);
9499
}
95100
}

0 commit comments

Comments
 (0)