Skip to content

Commit 45a3722

Browse files
authored
Develop 1.21.1 beta 8 (#1720)
2 parents ff8de66 + c2a73e0 commit 45a3722

File tree

47 files changed

+1570
-368
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1570
-368
lines changed

.github/workflows/probe.yml

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
name: Compatibility tests
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
test_count:
7+
type: number
8+
default: 1000
9+
description: Number of mods to test
10+
required: true
11+
tag:
12+
type: string
13+
required: true
14+
description: Target release tag
15+
16+
env:
17+
TEST_COUNT: ${{ inputs.test_count }}
18+
GATHERER_IMG: ghcr.io/sinytra/probe/gatherer:latest
19+
20+
jobs:
21+
run_tests:
22+
name: Run tests
23+
runs-on: ubuntu-latest
24+
25+
services:
26+
redis:
27+
image: redis
28+
options: >-
29+
--health-cmd "redis-cli ping"
30+
--health-interval 10s
31+
--health-timeout 5s
32+
--health-retries 5
33+
--name probe_redis
34+
ports:
35+
- 6379:6379
36+
37+
permissions:
38+
contents: write
39+
packages: read
40+
41+
steps:
42+
- name: Setup env
43+
run: mkdir probe
44+
45+
- name: Cache test data
46+
uses: tespkg/actions-cache@v1
47+
with:
48+
accessKey: ${{ secrets.S3_ACCESS_KEY }}
49+
secretKey: ${{ secrets.S3_SECRET_KEY }}
50+
bucket: ${{ secrets.S3_BUCKET_NAME }}
51+
use-fallback: false
52+
53+
key: ${{ runner.os }}-cache-${{ env.TEST_COUNT }}
54+
path: |
55+
probe/.setup
56+
probe/mods
57+
probe/candidates.json
58+
probe/dump.rdb
59+
restore-keys: |
60+
${{ runner.os }}-cache-
61+
62+
- name: Restore redis data
63+
if: ${{ hashFiles('probe/dump.rdb') != '' }}
64+
run: |
65+
docker stop probe_redis
66+
docker cp probe/dump.rdb probe_redis:/data/dump.rdb
67+
docker start probe_redis
68+
69+
- name: Login to GitHub Container Registry
70+
uses: docker/login-action@v3
71+
with:
72+
registry: ghcr.io
73+
username: ${{ github.actor }}
74+
password: ${{ secrets.GITHUB_TOKEN }}
75+
76+
- name: Run tests in a container
77+
run: >
78+
docker run --rm
79+
--network host
80+
-v ./probe:/probe
81+
-e REDIS_URL=redis://localhost:6379/0
82+
-e TEST_COUNT=${{ env.TEST_COUNT }}
83+
-e FORCE_RETAKE_TESTS=true
84+
-e CLEANUP_OUTPUT=true
85+
${{ env.GATHERER_IMG }}
86+
87+
- name: Backup redis data
88+
run: |
89+
docker stop probe_redis
90+
docker cp probe_redis:/data/dump.rdb probe/dump.rdb
91+
92+
- name: Upload report
93+
if: ${{ hashFiles('probe/report.md') != '' }}
94+
run: cat probe/report.md >> $GITHUB_STEP_SUMMARY
95+
96+
- name: Upload test results
97+
uses: actions/upload-artifact@v4
98+
with:
99+
name: test-results
100+
path: probe/results.json
101+
102+
- name: Uploade release assets
103+
uses: softprops/action-gh-release@v2
104+
if: ${{ inputs.tag != '' || github.ref_type == 'tag' }}
105+
with:
106+
tag_name: ${{ inputs.tag || github.ref_name }}
107+
files: probe/results.json

build.gradle.kts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ plugins {
88
java
99
`maven-publish`
1010
id("net.neoforged.moddev") version "2.0.78"
11-
id("io.github.goooler.shadow") version "8.1.8" apply false
11+
id("com.gradleup.shadow") version "9.0.0-beta12" apply false
1212
id("me.modmuss50.mod-publish-plugin") version "0.5.+"
1313
id("net.neoforged.gradleutils") version "3.0.0"
1414
id("org.sinytra.adapter.userdev") version "1.2.1-SNAPSHOT"
@@ -34,7 +34,6 @@ val forgifiedFabricApiCurseForge: String by project
3434
val forgifiedFabricApiModrinth: String by project
3535
val connectorExtrasCurseForge: String by project
3636
val connectorExtrasModrinth: String by project
37-
val mixinextrasVersion: String by project
3837

3938
val PUBLISH_RELEASE_TYPE: Provider<String> = providers.environmentVariable("PUBLISH_RELEASE_TYPE")
4039

@@ -47,7 +46,6 @@ if (!PUBLISH_RELEASE_TYPE.isPresent) {
4746
logger.lifecycle("Project version: $version")
4847

4948
val mod: SourceSet by sourceSets.creating
50-
val test: SourceSet by sourceSets
5149

5250
val shade: Configuration by configurations.creating
5351
val adapterData: Configuration by configurations.creating
@@ -137,6 +135,7 @@ dependencies {
137135
shade(group = "org.sinytra", name = "ForgeAutoRenamingTool", version = versionForgeAutoRenamingTool) { isTransitive = false }
138136
shade(group = "org.sinytra.adapter", name = "definition", version = versionAdapterDefinition) { isTransitive = false }
139137
adapterData(group = "org.sinytra.adapter", name = "adapter", version = versionAdapter)
138+
shade(project(":transformer")) { isTransitive = false }
140139

141140
jarJar(implementation(group = "org.sinytra.adapter", name = "runtime", version = versionAdapterRuntime))
142141
"modImplementation"(implementation(group = "org.sinytra.forgified-fabric-api", name = "forgified-fabric-api", version = versionForgifiedFabricApi)) {
@@ -180,7 +179,9 @@ val depsJar: ShadowJar by tasks.creating(ShadowJar::class) {
180179
}
181180

182181
val fullJar by tasks.registering(ShadowJar::class) {
183-
from(tasks.jar, depsJar)
182+
from(
183+
depsJar.archiveFile.map(::zipTree),
184+
tasks.jar.flatMap { it.archiveFile.map(::zipTree) })
184185
mergeServiceFiles() // Relocate services
185186
relocate("net.minecraftforge.fart", "reloc.net.minecraftforge.fart")
186187
relocate("net.minecraftforge.srgutils", "reloc.net.minecraftforge.srgutils")
@@ -274,6 +275,9 @@ publishing {
274275
from(components["java"])
275276
}
276277
}
278+
}
279+
280+
allprojects {
277281
repositories {
278282
val env = System.getenv()
279283
if (env["MAVEN_URL"] != null) {

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ org.gradle.caching=true
77
#org.gradle.configuration-cache=true
88

99
# Versions
10-
versionConnector=2.0.0-beta.7
10+
versionConnector=2.0.0-beta.8
1111
versionAdapter=1.13.20+1.21.1-20240811.191740
12-
versionAdapterDefinition=1.13.25+1.21.1
12+
versionAdapterDefinition=1.13.26+1.21.1
1313
versionAdapterRuntime=1.0.0+1.21.1
1414

1515
versionMc=1.21.1

settings.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ pluginManagement {
1313
}
1414

1515
rootProject.name = "connector"
16+
17+
include("transformer")

src/main/java/org/sinytra/connector/ConnectorCoremods.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,13 @@ public Iterable<? extends ITransformer<?>> getTransformers() {
6767
method.visitVarInsn(Opcodes.ALOAD, 5);
6868
// displayItemsGenerator
6969
method.visitVarInsn(Opcodes.ALOAD, 6);
70-
// backgroundLocation
71-
method.visitTypeInsn(Opcodes.NEW, "net/minecraft/resources/ResourceLocation");
72-
method.visitInsn(Opcodes.DUP);
73-
method.visitLdcInsn("textures/gui/container/creative_inventory/tab_items.png");
74-
method.visitMethodInsn(Opcodes.INVOKESPECIAL, "net/minecraft/resources/ResourceLocation", "<init>", "(Ljava/lang/String;)V", false);
70+
// scrollerSpriteLocation
71+
method.visitInsn(Opcodes.ACONST_NULL);
7572
// hasSearchBar
7673
method.visitInsn(Opcodes.ICONST_0);
7774
// searchBarWidth
7875
method.visitLdcInsn(89);
76+
// tabsImage
7977
method.visitFieldInsn(Opcodes.GETSTATIC, "net/minecraft/world/item/CreativeModeTab$Builder", "CREATIVE_INVENTORY_TABS_IMAGE", "Lnet/minecraft/resources/ResourceLocation;"); // tabsImage
8078
// labelColor
8179
method.visitLdcInsn(4210752);

src/main/java/org/sinytra/connector/locator/ConnectorLocator.java

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import cpw.mods.jarhandling.JarContents;
77
import cpw.mods.jarhandling.JarContentsBuilder;
88
import cpw.mods.jarhandling.SecureJar;
9+
import cpw.mods.modlauncher.Launcher;
10+
import cpw.mods.modlauncher.api.IModuleLayerManager;
11+
import net.fabricmc.loader.impl.metadata.LoaderModMetadata;
912
import net.fabricmc.loader.impl.metadata.NestedJarEntry;
1013
import net.neoforged.fml.ModLoadingException;
1114
import net.neoforged.fml.loading.FMLPaths;
@@ -14,17 +17,15 @@
1417
import net.neoforged.fml.loading.moddiscovery.readers.JarModsDotTomlModFileReader;
1518
import net.neoforged.fml.loading.progress.StartupNotificationManager;
1619
import net.neoforged.neoforgespi.language.IModInfo;
17-
import net.neoforged.neoforgespi.locating.IDependencyLocator;
18-
import net.neoforged.neoforgespi.locating.IDiscoveryPipeline;
19-
import net.neoforged.neoforgespi.locating.IModFile;
20-
import net.neoforged.neoforgespi.locating.IncompatibleFileReporting;
21-
import net.neoforged.neoforgespi.locating.ModFileDiscoveryAttributes;
20+
import net.neoforged.neoforgespi.locating.*;
2221
import org.apache.maven.artifact.versioning.ArtifactVersion;
2322
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
2423
import org.jetbrains.annotations.Nullable;
2524
import org.sinytra.connector.ConnectorEarlyLoader;
2625
import org.sinytra.connector.locator.filter.ForgeModPackageFilter;
2726
import org.sinytra.connector.locator.filter.SplitPackageMerger;
27+
import org.sinytra.connector.locator.transform.ConnectorTransformerEnvironment;
28+
import org.sinytra.connector.transformer.TransformerEnvironment;
2829
import org.sinytra.connector.transformer.jar.JarTransformer;
2930
import org.sinytra.connector.util.ConnectorUtil;
3031
import org.sinytra.connector.util.PriorityModLoadingException;
@@ -34,19 +35,13 @@
3435
import java.lang.module.ModuleDescriptor;
3536
import java.nio.file.Files;
3637
import java.nio.file.Path;
37-
import java.util.ArrayList;
38-
import java.util.Collection;
39-
import java.util.Comparator;
40-
import java.util.List;
41-
import java.util.Objects;
42-
import java.util.Optional;
38+
import java.util.*;
4339
import java.util.stream.Collectors;
4440
import java.util.stream.Stream;
4541

4642
import static cpw.mods.modlauncher.api.LambdaExceptionUtils.rethrowFunction;
4743
import static cpw.mods.modlauncher.api.LambdaExceptionUtils.uncheck;
4844
import static net.neoforged.fml.loading.LogMarkers.SCAN;
49-
import static org.sinytra.connector.transformer.jar.JarTransformer.cacheTransformableJar;
5045

5146
public class ConnectorLocator implements IDependencyLocator {
5247
public static final String PLACEHOLDER_PROPERTY = "connector:placeholder";
@@ -63,13 +58,14 @@ public void scanMods(List<IModFile> loadedMods, IDiscoveryPipeline pipeline) {
6358
LOGGER.error("Skipping mod scan due to previously encountered error");
6459
return;
6560
}
61+
6662
try {
67-
List<IModFile> results = locateFabricMods(loadedMods);
63+
LocationResult results = locateFabricMods(loadedMods);
6864
if (results != null) {
69-
results.forEach(pipeline::addModFile);
65+
results.mods().forEach(pipeline::addModFile);
7066

7167
// Create mod file for generated adapter mixins jar
72-
Path generatedAdapterJar = JarTransformer.getGeneratedJarPath();
68+
Path generatedAdapterJar = results.generatedJarPath();
7369
if (Files.exists(generatedAdapterJar)) {
7470
pipeline.addPath(generatedAdapterJar, ModFileDiscoveryAttributes.DEFAULT, IncompatibleFileReporting.ERROR);
7571
}
@@ -93,28 +89,37 @@ public void scanMods(List<IModFile> loadedMods, IDiscoveryPipeline pipeline) {
9389
}
9490

9591
@Nullable
96-
private List<IModFile> locateFabricMods(List<IModFile> discoveredMods) {
92+
private LocationResult locateFabricMods(List<IModFile> discoveredMods) {
9793
LOGGER.debug(SCAN, "Scanning mods dir {} for mods", FMLPaths.MODSDIR.get());
9894
Path tempDir = ConnectorUtil.CONNECTOR_FOLDER.resolve("temp");
9995

10096
// Get all existing mods
10197
Collection<SimpleModInfo> loadedModInfos = getPreviouslyDiscoveredMods(discoveredMods);
10298
Collection<IModFile> loadedModFiles = loadedModInfos.stream().map(SimpleModInfo::origin).toList();
10399
Collection<String> loadedModIds = loadedModInfos.stream().filter(mod -> !mod.library()).map(SimpleModInfo::modid).collect(Collectors.toUnmodifiableSet());
104-
Collection<String> loadedModuleNames = loadedModInfos.stream().filter(SimpleModInfo::library).map(SimpleModInfo::moduleName).filter(Objects::nonNull).collect(Collectors.toUnmodifiableSet());
100+
Collection<String> loadedModuleNames = Stream.concat(
101+
Launcher.INSTANCE.findLayerManager().flatMap(m -> m.getLayer(IModuleLayerManager.Layer.BOOT))
102+
.stream()
103+
.flatMap(m -> m.modules().stream())
104+
.map(Module::getName),
105+
loadedModInfos.stream().filter(SimpleModInfo::library).map(SimpleModInfo::moduleName).filter(Objects::nonNull))
106+
.collect(Collectors.toUnmodifiableSet());
107+
108+
TransformerEnvironment environment = new ConnectorTransformerEnvironment(loadedModFiles);
109+
JarTransformer transformer = new JarTransformer(environment);
105110

106111
// Discover fabric mod jars
107112
List<JarTransformer.TransformableJar> discoveredJars = FabricModsDiscoverer.scanFabricMods()
108-
.map(rethrowFunction(p -> cacheTransformableJar(p.toFile())))
113+
.map(rethrowFunction(p -> transformer.cacheTransformableJar(p.toFile())))
109114
.filter(jar -> !shouldIgnoreMod(jar, loadedModIds, loadedModuleNames))
110115
.toList();
111116

112117
// Discover fabric nested mod jars
113118
Multimap<JarTransformer.TransformableJar, JarTransformer.TransformableJar> parentToChildren = HashMultimap.create();
114119
List<JarTransformer.TransformableJar> discoveredNestedJars = discoveredJars.stream()
115120
.flatMap(jar -> {
116-
ConnectorFabricModMetadata metadata = jar.modPath().metadata().modMetadata();
117-
return shouldIgnoreMod(jar, loadedModIds, loadedModuleNames) ? Stream.empty() : discoverNestedJarsRecursive(tempDir, jar, metadata.getJars(), parentToChildren, loadedModIds, loadedModuleNames);
121+
LoaderModMetadata metadata = jar.modPath().metadata().modMetadata();
122+
return shouldIgnoreMod(jar, loadedModIds, loadedModuleNames) ? Stream.empty() : discoverNestedJarsRecursive(transformer, tempDir, jar, metadata.getJars(), parentToChildren, loadedModIds, loadedModuleNames);
118123
})
119124
.toList();
120125

@@ -131,7 +136,7 @@ private List<IModFile> locateFabricMods(List<IModFile> discoveredMods) {
131136
List<Path> renameLibs = loadedModFiles.stream().map(modFile -> modFile.getSecureJar().getRootPath()).toList();
132137

133138
// Run jar transformations (or get existing outputs from cache)
134-
List<JarTransformer.TransformedFabricModPath> transformed = JarTransformer.transform(candidates, renameLibs, loadedModFiles);
139+
List<JarTransformer.TransformedFabricModPath> transformed = transformer.transform(candidates, renameLibs);
135140

136141
List<JarTransformer.TransformedFabricModPath> failing = transformed.stream().filter(j -> j.auditTrail() != null && j.auditTrail().hasFailingMixins()).toList();
137142
if (!failing.isEmpty()) {
@@ -148,7 +153,8 @@ private List<IModFile> locateFabricMods(List<IModFile> discoveredMods) {
148153
// Deal with split packages (thanks modules)
149154
List<SplitPackageMerger.FilteredModPath> moduleSafeJars = SplitPackageMerger.mergeSplitPackages(transformed.stream().map(JarTransformer.TransformedFabricModPath::output).toList(), loadedModFiles, ignoredModFiles);
150155

151-
return moduleSafeJars.stream().map(ConnectorLocator::createConnectorModFile).toList();
156+
List<IModFile> loadedMods = moduleSafeJars.stream().map(ConnectorLocator::createConnectorModFile).toList();
157+
return new LocationResult(loadedMods, environment.getGeneratedJarPath());
152158
}
153159

154160
private static IModFile createConnectorModFile(SplitPackageMerger.FilteredModPath modPath) {
@@ -158,36 +164,36 @@ private static IModFile createConnectorModFile(SplitPackageMerger.FilteredModPat
158164
}
159165
ModJarMetadata modJarMetadata = new ModJarMetadata(jarContents);
160166
SecureJar secureJar = SecureJar.from(jarContents, modJarMetadata);
161-
IModFile modFile = IModFile.create(secureJar, f -> FabricModMetadataParser.createForgeMetadata(f, modPath.metadata().modMetadata(), modPath.metadata().visibleMixinConfigs(), modPath.metadata().generated()));
167+
IModFile modFile = IModFile.create(secureJar, f -> FabricModMetadataParser.createForgeMetadata(f, (ConnectorFabricModMetadata) modPath.metadata().modMetadata(), modPath.metadata().visibleMixinConfigs(), modPath.metadata().generated()));
162168
modJarMetadata.setModFile(modFile);
163169
return modFile;
164170
}
165171

166-
private static Stream<JarTransformer.TransformableJar> discoverNestedJarsRecursive(Path tempDir, JarTransformer.TransformableJar parent, Collection<NestedJarEntry> jars, Multimap<JarTransformer.TransformableJar, JarTransformer.TransformableJar> parentToChildren, Collection<String> loadedModIds, Collection<String> loadedModuleNames) {
172+
private static Stream<JarTransformer.TransformableJar> discoverNestedJarsRecursive(JarTransformer transformer, Path tempDir, JarTransformer.TransformableJar parent, Collection<NestedJarEntry> jars, Multimap<JarTransformer.TransformableJar, JarTransformer.TransformableJar> parentToChildren, Collection<String> loadedModIds, Collection<String> loadedModuleNames) {
167173
SecureJar secureJar = SecureJar.from(parent.input().toPath());
168174
return jars.stream()
169175
.map(entry -> secureJar.getPath(entry.getFile()))
170176
.filter(Files::exists)
171177
.flatMap(path -> {
172-
JarTransformer.TransformableJar jar = uncheck(() -> prepareNestedJar(tempDir, secureJar.getPrimaryPath().getFileName().toString(), path));
178+
JarTransformer.TransformableJar jar = uncheck(() -> prepareNestedJar(transformer, tempDir, secureJar.getPrimaryPath().getFileName().toString(), path));
173179
if (shouldIgnoreMod(jar, loadedModIds, loadedModuleNames)) {
174180
return Stream.empty();
175181
}
176182
parentToChildren.put(parent, jar);
177-
ConnectorFabricModMetadata metadata = jar.modPath().metadata().modMetadata();
178-
return Stream.concat(Stream.of(jar), discoverNestedJarsRecursive(tempDir, jar, metadata.getJars(), parentToChildren, loadedModIds, loadedModuleNames));
183+
LoaderModMetadata metadata = jar.modPath().metadata().modMetadata();
184+
return Stream.concat(Stream.of(jar), discoverNestedJarsRecursive(transformer, tempDir, jar, metadata.getJars(), parentToChildren, loadedModIds, loadedModuleNames));
179185
});
180186
}
181187

182-
private static JarTransformer.TransformableJar prepareNestedJar(Path tempDir, String parentName, Path path) throws IOException {
188+
private static JarTransformer.TransformableJar prepareNestedJar(JarTransformer transformer, Path tempDir, String parentName, Path path) throws IOException {
183189
Files.createDirectories(tempDir);
184190

185191
String parentNameWithoutExt = parentName.split("\\.(?!.*\\.)")[0];
186192
// Extract JiJ
187193
Path extracted = tempDir.resolve(parentNameWithoutExt + "$" + path.getFileName().toString());
188194
ConnectorUtil.cache(path, extracted, () -> Files.copy(path, extracted));
189195

190-
return uncheck(() -> JarTransformer.cacheTransformableJar(extracted.toFile()));
196+
return uncheck(() -> transformer.cacheTransformableJar(extracted.toFile()));
191197
}
192198

193199
// Removes any duplicates from located connector mods, as well as mods that are already located by FML.
@@ -225,7 +231,7 @@ private static List<JarTransformer.TransformableJar> handleDuplicateMods(List<Ja
225231
}
226232

227233
private static boolean shouldIgnoreMod(JarTransformer.TransformableJar jar, Collection<String> loadedModIds, Collection<String> loadedModuleNames) {
228-
ConnectorFabricModMetadata metadata = jar.modPath().metadata().modMetadata();
234+
LoaderModMetadata metadata = jar.modPath().metadata().modMetadata();
229235
String id = metadata.getId();
230236
return ConnectorUtil.DISABLED_MODS.contains(id) || loadedModIds.contains(id)
231237
|| jar.modPath().metadata().generated() && loadedModuleNames.contains(jar.moduleName());
@@ -260,4 +266,6 @@ private static void loadEmbeddedJars(IDiscoveryPipeline pipeline) throws Excepti
260266

261267
private record SimpleModInfo(String modid, ArtifactVersion version, boolean library, @Nullable IModFile origin, @Nullable String moduleName) {
262268
}
269+
270+
private record LocationResult(List<IModFile> mods, Path generatedJarPath) {}
263271
}

0 commit comments

Comments
 (0)