Skip to content

Commit 49ef4fc

Browse files
Jab125shedanielJuuxel
committed
Fix Forge 50 (1.20.6) (#219)
Co-authored-by: shedaniel <[email protected]> Co-authored-by: Juuz <[email protected]>
1 parent 69d9ec0 commit 49ef4fc

File tree

25 files changed

+719
-27
lines changed

25 files changed

+719
-27
lines changed

.github/workflows/test-push.yml

+50
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,53 @@ jobs:
148148
with:
149149
name: Reproducible Build ${{ matrix.os }} (${{ matrix.java }}) Results
150150
path: build/reports/
151+
152+
# Special case this test to run on Java 21
153+
neoForge1206Test:
154+
needs: build
155+
156+
strategy:
157+
fail-fast: false
158+
matrix:
159+
java: [ 21 ]
160+
os: [ ubuntu-22.04 ]
161+
162+
runs-on: ${{ matrix.os }}
163+
steps:
164+
- uses: actions/checkout@v4
165+
- uses: actions/setup-java@v4
166+
with:
167+
java-version: ${{ matrix.java }}
168+
distribution: 'temurin'
169+
170+
- run: ./gradlew test --tests *NeoForge1206Test --stacktrace --warning-mode fail
171+
172+
- uses: actions/upload-artifact@v4
173+
if: ${{ failure() }}
174+
with:
175+
name: NeoForge 1.20.6 Build Results
176+
# Special case this test to run on Java 21
177+
forge1206Test:
178+
needs: build
179+
180+
strategy:
181+
fail-fast: false
182+
matrix:
183+
java: [ 21 ]
184+
os: [ ubuntu-22.04 ]
185+
186+
runs-on: ${{ matrix.os }}
187+
steps:
188+
- uses: actions/checkout@v4
189+
- uses: actions/setup-java@v4
190+
with:
191+
java-version: ${{ matrix.java }}
192+
distribution: 'temurin'
193+
194+
- run: ./gradlew test --tests *Forge1206Test --stacktrace --warning-mode fail
195+
196+
- uses: actions/upload-artifact@v4
197+
if: ${{ failure() }}
198+
with:
199+
name: Forge 1.20.6 Build Results
200+
path: build/reports/

build.gradle

+5
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,11 @@ task writeActionsTestMatrix() {
423423
return
424424
}
425425

426+
if (it.name.endsWith("NeoForge1206Test.groovy") || it.name.endsWith("Forge1206Test.groovy")) {
427+
// Arch: The 1.20.6 tests require Java 21
428+
return
429+
}
430+
426431
def className = it.path.toString().replace(".groovy", "")
427432
className = className.substring(className.lastIndexOf("integration/") + "integration/".length()).replace('/', '.')
428433

gradle/runtime.libs.versions.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ access-transformers-new = "8.0.5"
1919
access-transformers-neo = "10.0.2"
2020
unprotect = "1.2.0"
2121
asm = "9.7"
22-
union-relauncher = "1.0.0"
22+
union-relauncher = "1.1.0"
2323
access-transformers-log4j = "2.17.1"
2424

2525
[libraries]

src/main/java/net/fabricmc/loom/build/IntermediaryNamespaces.java

+18-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ public static String intermediary(Project project) {
3737
return intermediaryNamespace(project).toString();
3838
}
3939

40+
/**
41+
* Returns the runtime intermediary namespace of the project.
42+
* This is the namespace used in the compiled jar.
43+
*/
44+
public static String runtimeIntermediary(Project project) {
45+
return runtimeIntermediaryNamespace(project).toString();
46+
}
47+
4048
/**
4149
* Returns the intermediary namespace of the project.
4250
*/
@@ -49,6 +57,15 @@ public static MappingsNamespace intermediaryNamespace(Project project) {
4957
};
5058
}
5159

60+
/**
61+
* Returns the intermediary namespace of the project.
62+
*/
63+
public static MappingsNamespace runtimeIntermediaryNamespace(Project project) {
64+
LoomGradleExtension extension = LoomGradleExtension.get(project);
65+
if (extension.isForge() && extension.getForgeProvider().usesMojangAtRuntime()) return MappingsNamespace.MOJANG;
66+
return intermediaryNamespace(project);
67+
}
68+
5269
/**
5370
* Potentially replaces the remapping target namespace for mixin refmaps.
5471
*
@@ -62,6 +79,6 @@ public static MappingsNamespace intermediaryNamespace(Project project) {
6279
* @return the correct namespace to use
6380
*/
6481
public static String replaceMixinIntermediaryNamespace(Project project, String namespace) {
65-
return namespace.equals(intermediary(project)) ? MappingsNamespace.INTERMEDIARY.toString() : namespace;
82+
return namespace.equals(runtimeIntermediary(project)) ? MappingsNamespace.INTERMEDIARY.toString() : namespace;
6683
}
6784
}

src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ private void stripNestedJars(Path path) {
165165
private void remapJars(List<ModDependency> remapList) throws IOException {
166166
final LoomGradleExtension extension = LoomGradleExtension.get(project);
167167
final MappingConfiguration mappingConfiguration = extension.getMappingConfiguration();
168-
String fromM = IntermediaryNamespaces.intermediary(project);
168+
String fromM = IntermediaryNamespaces.runtimeIntermediary(project);
169169

170170
Stopwatch stopwatch = Stopwatch.createStarted();
171171

src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeProvider.java

+4
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ public ForgeVersion getVersion() {
6060
return version;
6161
}
6262

63+
public boolean usesMojangAtRuntime() {
64+
return platform == ModPlatform.NEOFORGE || version.getMajorVersion() >= Constants.Forge.MIN_USE_MOJANG_NS_VERSION;
65+
}
66+
6367
public File getGlobalCache() {
6468
if (globalCache == null) {
6569
globalCache = getMinecraftProvider().dir(platform.id() + "/" + version.getCombined());

src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java

+32-17
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,18 @@
3535
import java.nio.file.NoSuchFileException;
3636
import java.nio.file.Path;
3737
import java.nio.file.StandardCopyOption;
38+
import java.nio.file.StandardOpenOption;
3839
import java.util.ArrayList;
3940
import java.util.Arrays;
4041
import java.util.HashMap;
4142
import java.util.List;
4243
import java.util.Map;
4344
import java.util.Objects;
4445

46+
import org.apache.tools.ant.util.StringUtils;
4547
import com.google.common.base.Stopwatch;
4648
import com.google.gson.JsonObject;
4749
import dev.architectury.loom.util.MappingOption;
48-
import org.apache.tools.ant.util.StringUtils;
4950
import org.gradle.api.Project;
5051
import org.gradle.api.artifacts.Configuration;
5152
import org.jetbrains.annotations.Nullable;
@@ -211,28 +212,20 @@ public void setupPost(Project project) throws IOException {
211212
// Generate the Mojmap-merged mappings if needed.
212213
// Note that this needs to happen before manipulateMappings for FieldMigratedMappingConfiguration.
213214
if (Files.notExists(tinyMappingsWithMojang) || extension.refreshDeps()) {
214-
final Stopwatch stopwatch = Stopwatch.createStarted();
215-
final MappingContext context = new GradleMappingContext(project, "tmp-neoforge");
216-
217-
try (Tiny2FileWriter writer = new Tiny2FileWriter(Files.newBufferedWriter(tinyMappingsWithMojang), false)) {
218-
ForgeMappingsMerger.mergeMojang(context, tinyMappings, null, true).accept(writer);
219-
}
220-
221-
project.getLogger().info(":merged mojang mappings in {}", stopwatch.stop());
215+
mergeMojang(project, tinyMappings, tinyMappingsWithMojang);
222216
}
223217
}
224218

225219
if (extension.shouldGenerateSrgTiny()) {
226220
if (Files.notExists(tinyMappingsWithSrg) || extension.refreshDeps()) {
227-
// Merge tiny mappings with srg
228-
Stopwatch stopwatch = Stopwatch.createStarted();
229-
ForgeMappingsMerger.ExtraMappings extraMappings = ForgeMappingsMerger.ExtraMappings.ofMojmapTsrg(getMojmapSrgFileIfPossible(project));
230-
231-
try (Tiny2FileWriter writer = new Tiny2FileWriter(Files.newBufferedWriter(tinyMappingsWithSrg), false)) {
232-
ForgeMappingsMerger.mergeSrg(getRawSrgFile(project), tinyMappings, extraMappings, true).accept(writer);
221+
if (extension.isForge() && extension.getForgeProvider().usesMojangAtRuntime()) {
222+
Path tmp = Files.createTempFile("mappings", ".tiny");
223+
mergeMojang(project, tinyMappings, tmp);
224+
mergeSrg(project, tmp, tinyMappingsWithSrg);
225+
Files.deleteIfExists(tmp);
226+
} else {
227+
mergeSrg(project, tinyMappings, tinyMappingsWithSrg);
233228
}
234-
235-
project.getLogger().info(":merged srg mappings in " + stopwatch.stop());
236229
}
237230
}
238231

@@ -288,6 +281,28 @@ public static Path getMojmapSrgFileIfPossible(Project project) {
288281
}
289282
}
290283

284+
private static void mergeMojang(Project project, Path source, Path target) throws IOException {
285+
final Stopwatch stopwatch = Stopwatch.createStarted();
286+
final MappingContext context = new GradleMappingContext(project, "tmp-mojang");
287+
288+
try (Tiny2FileWriter writer = new Tiny2FileWriter(Files.newBufferedWriter(target, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING), false)) {
289+
ForgeMappingsMerger.mergeMojang(context, source, null, true).accept(writer);
290+
}
291+
292+
project.getLogger().info(":merged mojang mappings in {}", stopwatch.stop());
293+
}
294+
295+
private static void mergeSrg(Project project, Path source, Path target) throws IOException {
296+
Stopwatch stopwatch = Stopwatch.createStarted();
297+
ForgeMappingsMerger.ExtraMappings extraMappings = ForgeMappingsMerger.ExtraMappings.ofMojmapTsrg(getMojmapSrgFileIfPossible(project));
298+
299+
try (Tiny2FileWriter writer = new Tiny2FileWriter(Files.newBufferedWriter(target, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING), false)) {
300+
ForgeMappingsMerger.mergeSrg(getRawSrgFile(project), source, extraMappings, true).accept(writer);
301+
}
302+
303+
project.getLogger().info(":merged srg mappings in " + stopwatch.stop());
304+
}
305+
291306
protected void manipulateMappings(Project project, Path mappingsJar) throws IOException {
292307
}
293308

src/main/java/net/fabricmc/loom/extension/MixinExtensionApiImpl.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ public abstract class MixinExtensionApiImpl implements MixinExtensionAPI {
5050
public MixinExtensionApiImpl(Project project) {
5151
this.project = Objects.requireNonNull(project);
5252
this.useMixinAp = project.getObjects().property(Boolean.class)
53-
.convention(project.provider(() -> !LoomGradleExtension.get(project).isNeoForge()));
53+
.convention(project.provider(() -> !LoomGradleExtension.get(project).isNeoForge() && (!LoomGradleExtension.get(project).isForge() || !LoomGradleExtension.get(project).getForgeProvider().usesMojangAtRuntime())));
5454

5555
this.refmapTargetNamespace = project.getObjects().property(String.class)
56-
.convention(project.provider(() -> IntermediaryNamespaces.intermediary(project)));
56+
.convention(project.provider(() -> IntermediaryNamespaces.runtimeIntermediary(project)));
5757
this.refmapTargetNamespace.finalizeValueOnRead();
5858

5959
this.messages = project.getObjects().mapProperty(String.class, String.class);

src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public abstract class AbstractRemapJarTask extends Jar {
116116
@Inject
117117
public AbstractRemapJarTask() {
118118
getSourceNamespace().convention(MappingsNamespace.NAMED.toString()).finalizeValueOnRead();
119-
getTargetNamespace().convention(IntermediaryNamespaces.intermediary(getProject())).finalizeValueOnRead();
119+
getTargetNamespace().convention(getProject().provider(() -> IntermediaryNamespaces.runtimeIntermediary(getProject()))).finalizeValueOnRead();
120120
getRemapperIsolation().convention(true).finalizeValueOnRead();
121121
getIncludesClientOnlyClasses().convention(false).finalizeValueOnRead();
122122
getJarType().finalizeValueOnRead();

src/main/java/net/fabricmc/loom/util/Constants.java

+5
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,11 @@ public static final class Forge {
186186
public static final String UNION_RELAUNCHER_MAIN_CLASS = "juuxel.unionrelauncher.UnionRelauncher";
187187
public static final String UNION_RELAUNCHER_MAIN_CLASS_PROPERTY = "unionRelauncher.mainClass";
188188

189+
/**
190+
* The minimum version of Forge that uses "mojang" as the namespace in production.
191+
*/
192+
public static final int MIN_USE_MOJANG_NS_VERSION = 50;
193+
189194
private Forge() {
190195
}
191196
}

src/main/java/net/fabricmc/loom/util/SourceRemapper.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public class SourceRemapper {
6565
private Mercury mercury;
6666

6767
public SourceRemapper(Project project, SharedServiceManager serviceManager, boolean toNamed) {
68-
this(project, serviceManager, toNamed ? IntermediaryNamespaces.intermediary(project) : "named", !toNamed ? IntermediaryNamespaces.intermediary(project) : "named");
68+
this(project, serviceManager, toNamed ? IntermediaryNamespaces.runtimeIntermediary(project) : "named", !toNamed ? IntermediaryNamespaces.runtimeIntermediary(project) : "named");
6969
}
7070

7171
public SourceRemapper(Project project, SharedServiceManager serviceManager, String from, String to) {

src/main/java/net/fabricmc/loom/util/srg/CoreModClassRemapper.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public final class CoreModClassRemapper {
6161

6262
public static void remapJar(Project project, ModPlatform platform, Path jar, MappingTree mappings) throws IOException {
6363
final Logger logger = project.getLogger();
64-
final String sourceNamespace = IntermediaryNamespaces.intermediary(project);
64+
final String sourceNamespace = IntermediaryNamespaces.runtimeIntermediary(project);
6565

6666
try (FileSystemUtil.Delegate fs = FileSystemUtil.getJarFileSystem(jar, false)) {
6767
Path coremodsJsonPath = fs.getPath("META-INF", "coremods.json");

src/main/java/net/fabricmc/loom/util/srg/ForgeMappingsMerger.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
*/
6666
public final class ForgeMappingsMerger {
6767
private static final List<String> INPUT_NAMESPACES = List.of("official", "intermediary", "named");
68+
private static final List<String> INPUT_NAMESPACES_WITH_MOJANG = List.of("official", "mojang", "intermediary", "named");
6869
private final MemoryMappingTree newNs;
6970
private final MemoryMappingTree src;
7071
private final MemoryMappingTree output;
@@ -111,8 +112,8 @@ private static MemoryMappingTree readInput(Path tiny) throws IOException {
111112
List<String> inputNamespaces = new ArrayList<>(src.getDstNamespaces());
112113
inputNamespaces.add(0, src.getSrcNamespace());
113114

114-
if (!inputNamespaces.equals(INPUT_NAMESPACES)) {
115-
throw new MappingException("Mapping file " + tiny + " does not have 'official, intermediary, named' as its namespaces! Found: " + inputNamespaces);
115+
if (!inputNamespaces.equals(INPUT_NAMESPACES) && !inputNamespaces.equals(INPUT_NAMESPACES_WITH_MOJANG)) {
116+
throw new MappingException("Mapping file " + tiny + " does not have 'official(, mojang), intermediary, named' as its namespaces! Found: " + inputNamespaces);
116117
}
117118

118119
return src;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* This file is part of fabric-loom, licensed under the MIT License (MIT).
3+
*
4+
* Copyright (c) 2024 FabricMC
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package net.fabricmc.loom.test.integration.forge
26+
27+
import spock.lang.Specification
28+
import spock.lang.Unroll
29+
30+
import net.fabricmc.loom.test.util.GradleProjectTestTrait
31+
32+
import static net.fabricmc.loom.test.LoomTestConstants.DEFAULT_GRADLE
33+
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
34+
35+
class Forge1206Test extends Specification implements GradleProjectTestTrait {
36+
@Unroll
37+
def "build #mcVersion #neoforgeVersion #mappings #patches"() {
38+
if (Integer.valueOf(System.getProperty("java.version").split("\\.")[0]) < 21) {
39+
println("This test requires Java 21. Currently you have Java ${System.getProperty("java.version")}.")
40+
return
41+
}
42+
43+
setup:
44+
def gradle = gradleProject(project: "forge/1206", version: DEFAULT_GRADLE)
45+
gradle.buildGradle.text = gradle.buildGradle.text.replace('@MCVERSION@', mcVersion)
46+
.replace('@FORGEVERSION@', neoforgeVersion)
47+
.replace('MAPPINGS', mappings) // Spotless doesn't like the @'s
48+
.replace('PATCHES', patches)
49+
50+
when:
51+
def result = gradle.run(task: "build")
52+
53+
then:
54+
result.task(":build").outcome == SUCCESS
55+
56+
where:
57+
mcVersion | neoforgeVersion | mappings | patches
58+
'1.20.6' | '1.20.6-50.1.3' | 'loom.officialMojangMappings()' | ''
59+
}
60+
}

0 commit comments

Comments
 (0)