Skip to content

Commit 3912bf6

Browse files
authored
Merge pull request #1 from MCDxAI/meteor-26
Add Meteor 26.x parser profile support
2 parents 4142aaa + fb38eb0 commit 3912bf6

204 files changed

Lines changed: 4697 additions & 86 deletions

File tree

Some content is hidden

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

.github/workflows/ci.yml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,16 @@ jobs:
4141
- name: Check out repository
4242
uses: actions/checkout@v4
4343

44-
- name: Set up Java 21
44+
- name: Set up Java 25
4545
uses: actions/setup-java@v4
4646
with:
4747
distribution: temurin
48-
java-version: "21"
48+
java-version: "25"
4949

5050
- name: Set up Gradle
5151
uses: gradle/actions/setup-gradle@v4
5252
with:
53-
gradle-version: "8.12.1"
53+
gradle-version: "9.4.1"
5454

5555
- name: Set up Python
5656
uses: actions/setup-python@v5
@@ -63,8 +63,13 @@ jobs:
6363
- name: Download latest release fixture jars
6464
run: gradle downloadLatestReleaseJars --no-daemon
6565

66-
- name: Run test suite
67-
run: gradle test --no-daemon -PautoGenerateStubs
66+
- name: Run 26x test suite
67+
run: gradle test --no-daemon -PautoGenerateStubs -PparserProfile=26x
68+
69+
- name: Generate 26x JSON output
70+
run: >
71+
gradle run --no-daemon -PparserProfile=26x
72+
--args="--input fixtures/addons/jars --output output/poc-scan --summary output/poc-scan/summary.json --profile 26x"
6873
6974
- name: Upload release summaries
7075
if: always()

build.gradle

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,18 @@ version = '0.1.0'
99

1010
java {
1111
toolchain {
12-
languageVersion = JavaLanguageVersion.of(21)
12+
languageVersion = JavaLanguageVersion.of(25)
1313
}
1414
}
1515

16+
// Mapping profile: selects which shim source dir is included in the main sourceSet.
17+
// Run gradle with -PparserProfile=legacy to build the 1.21.x flavor; default is 26x.
18+
ext.parserProfile = (project.findProperty('parserProfile') ?: '26x').toString().toLowerCase()
19+
if (parserProfile != 'legacy' && parserProfile != '26x') {
20+
throw new GradleException("Unknown parserProfile: ${parserProfile} (expected 'legacy' or '26x')")
21+
}
22+
def profileSourceDir = parserProfile == 'legacy' ? 'src/profile-legacy/java' : 'src/profile-26x/java'
23+
1624
repositories {
1725
mavenCentral()
1826
maven { url = uri('https://libraries.minecraft.net') }
@@ -21,8 +29,8 @@ repositories {
2129

2230
dependencies {
2331
implementation 'com.fasterxml.jackson.core:jackson-databind:2.18.3'
24-
implementation 'org.ow2.asm:asm:9.7.1'
25-
implementation 'org.ow2.asm:asm-commons:9.7.1'
32+
implementation 'org.ow2.asm:asm:9.9'
33+
implementation 'org.ow2.asm:asm-commons:9.9'
2634
implementation 'org.slf4j:slf4j-api:2.0.16'
2735
runtimeOnly 'org.slf4j:slf4j-simple:2.0.16'
2836
implementation 'org.apache.logging.log4j:log4j-api:2.24.3'
@@ -31,20 +39,23 @@ dependencies {
3139
implementation 'com.mojang:brigadier:1.0.18'
3240
implementation 'org.spongepowered:mixin:0.8.5'
3341
testImplementation 'org.junit.jupiter:junit-jupiter:5.11.4'
42+
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
3443
}
3544

3645
tasks.withType(Test).configureEach {
3746
useJUnitPlatform()
3847
jvmArgs '-noverify'
48+
systemProperty 'addonparser.profile', parserProfile
3949
}
4050

4151
application {
4252
mainClass = 'com.cope.addonparser.cli.Main'
43-
applicationDefaultJvmArgs = ['-noverify']
53+
applicationDefaultJvmArgs = ['-noverify', "-Daddonparser.profile=${project.parserProfile}"]
4454
}
4555

4656
tasks.named('run') {
4757
jvmArgs '-noverify'
58+
systemProperty 'addonparser.profile', parserProfile
4859
}
4960

5061
sourceSets {
@@ -56,13 +67,13 @@ sourceSets {
5667

5768
main {
5869
java {
59-
srcDirs += ['src/generated/java']
70+
srcDirs += ['src/generated/java', profileSourceDir]
6071
}
6172
}
6273
}
6374

6475
dependencies {
65-
stubgenImplementation 'org.ow2.asm:asm:9.7.1'
76+
stubgenImplementation 'org.ow2.asm:asm:9.9'
6677
stubgenImplementation 'com.google.code.gson:gson:2.11.0'
6778
}
6879

@@ -71,11 +82,15 @@ tasks.register('generateStubs', JavaExec) {
7182
mainClass = 'com.cope.addonparser.tools.StubGenerator'
7283
args '--input-dir', 'fixtures/addons/jars',
7384
'--output-dir', 'src/generated/java',
74-
'--manual-class-list', 'tools/manual_classes.txt'
85+
'--manual-class-list', 'tools/manual_classes.txt',
86+
'--manual-source-dirs', files('src/main/java', profileSourceDir).asPath,
87+
'--profile', parserProfile
7588

7689
// Incremental support: declare inputs and outputs
7790
inputs.dir('fixtures/addons/jars')
7891
inputs.file('tools/manual_classes.txt')
92+
inputs.dir('src/main/java')
93+
inputs.dir(profileSourceDir)
7994
inputs.files(sourceSets.stubgen.output)
8095
outputs.dir('src/generated/java')
8196
}
@@ -139,7 +154,8 @@ tasks.named('clean') {
139154
// AP-009: Spotless configuration for Google Java Style on manual sources
140155
spotless {
141156
java {
142-
target 'src/main/java/**/*.java', 'src/test/java/**/*.java', 'src/stubgen/java/**/*.java'
157+
target 'src/main/java/**/*.java', 'src/test/java/**/*.java', 'src/stubgen/java/**/*.java',
158+
'src/profile-legacy/java/**/*.java', 'src/profile-26x/java/**/*.java'
143159
targetExclude 'src/generated/java/**'
144160
googleJavaFormat()
145161
removeUnusedImports()

src/main/java/com/cope/addonparser/cli/Main.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.cope.addonparser.model.JarScanResult;
44
import com.cope.addonparser.model.ScanSummary;
5+
import com.cope.addonparser.profile.MappingProfile;
56
import com.cope.addonparser.scanner.AddonScanner;
67
import com.cope.addonparser.scanner.IsolatedScanner;
78
import com.cope.addonparser.scanner.RuntimeMode;
@@ -25,6 +26,10 @@ public static void main(String[] args) throws Exception {
2526
return;
2627
}
2728

29+
// Make profile visible to in-process consumers (e.g. ValueNormalizer) and forwarded
30+
// subprocesses.
31+
System.setProperty(MappingProfile.SYSTEM_PROPERTY, parsed.profile.cliValue());
32+
2833
List<Path> jars = collectJars(parsed.input);
2934
if (jars.isEmpty()) {
3035
System.err.println("No jar files found in: " + parsed.input);
@@ -40,9 +45,12 @@ public static void main(String[] args) throws Exception {
4045
summary.jarCount = jars.size();
4146

4247
System.out.println("Runtime mode: " + parsed.mode);
48+
System.out.println("Mapping profile: " + parsed.profile.cliValue());
4349

4450
try (AutoCloseable scanner =
45-
parsed.mode == RuntimeMode.ISOLATED ? new IsolatedScanner() : new AddonScanner()) {
51+
parsed.mode == RuntimeMode.ISOLATED
52+
? new IsolatedScanner(parsed.profile)
53+
: new AddonScanner(parsed.profile)) {
4654
for (Path jar : jars) {
4755
JarScanResult result =
4856
parsed.mode == RuntimeMode.ISOLATED
@@ -115,15 +123,17 @@ private static List<Path> collectJars(Path input) throws Exception {
115123

116124
private static void printUsage() {
117125
System.out.println(
118-
"Usage: java -jar addon-parser.jar --input <jar-or-dir> [--output <dir>] [--summary <file>] [--mode isolated|legacy]");
126+
"Usage: java -jar addon-parser.jar --input <jar-or-dir> [--output <dir>] [--summary <file>] [--mode isolated|legacy] [--profile legacy|26x]");
119127
}
120128

121-
private record Args(Path input, Path outputDir, Path summaryFile, RuntimeMode mode) {
129+
private record Args(
130+
Path input, Path outputDir, Path summaryFile, RuntimeMode mode, MappingProfile profile) {
122131
static Args parse(String[] args) {
123132
Path input = null;
124133
Path output = Paths.get("output");
125134
Path summary = null;
126135
RuntimeMode mode = RuntimeMode.LEGACY;
136+
MappingProfile profile = MappingProfile.fromSystemProperty();
127137

128138
for (int i = 0; i < args.length; i++) {
129139
String arg = args[i];
@@ -135,13 +145,15 @@ static Args parse(String[] args) {
135145
summary = Paths.get(args[++i]);
136146
} else if ("--mode".equals(arg) && i + 1 < args.length) {
137147
mode = RuntimeMode.fromString(args[++i]);
148+
} else if ("--profile".equals(arg) && i + 1 < args.length) {
149+
profile = MappingProfile.fromString(args[++i]);
138150
} else {
139151
return null;
140152
}
141153
}
142154

143155
if (input == null) return null;
144-
return new Args(input, output, summary, mode);
156+
return new Args(input, output, summary, mode, profile);
145157
}
146158
}
147159
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.cope.addonparser.profile;
2+
3+
import java.util.Locale;
4+
5+
public enum MappingProfile {
6+
LEGACY,
7+
MOJMAP_26X;
8+
9+
public static final String SYSTEM_PROPERTY = "addonparser.profile";
10+
11+
public static MappingProfile fromString(String value) {
12+
if (value == null || value.isBlank()) return MOJMAP_26X;
13+
return switch (value.trim().toLowerCase(Locale.ROOT)) {
14+
case "legacy", "1.21", "1.21.x", "yarn" -> LEGACY;
15+
case "26x", "26", "26.1", "mojmap", "mojmap_26x" -> MOJMAP_26X;
16+
default -> throw new IllegalArgumentException(
17+
"Unknown mapping profile: " + value + " (expected 'legacy' or '26x')");
18+
};
19+
}
20+
21+
public static MappingProfile fromSystemProperty() {
22+
return fromString(System.getProperty(SYSTEM_PROPERTY));
23+
}
24+
25+
public String cliValue() {
26+
return this == LEGACY ? "legacy" : "26x";
27+
}
28+
}

src/main/java/com/cope/addonparser/scanner/AddonScanner.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.cope.addonparser.model.ModuleDump;
77
import com.cope.addonparser.model.SettingDump;
88
import com.cope.addonparser.model.SettingGroupDump;
9+
import com.cope.addonparser.profile.MappingProfile;
910
import com.cope.addonparser.util.ChildFirstClassLoader;
1011
import com.cope.addonparser.util.FabricModParser;
1112
import com.cope.addonparser.util.ValueNormalizer;
@@ -40,7 +41,20 @@ public class AddonScanner implements AutoCloseable {
4041
private static final String KEEP_TMP_PROPERTY = "addonparser.keepTmp";
4142
private static final Path DEFAULT_TMP_ROOT = Paths.get("tmp", "addon-parser-runtime");
4243

43-
public AddonScanner() {}
44+
private final MappingProfile profile;
45+
46+
public AddonScanner() {
47+
this(MappingProfile.fromSystemProperty());
48+
}
49+
50+
public AddonScanner(MappingProfile profile) {
51+
this.profile = profile;
52+
System.setProperty(MappingProfile.SYSTEM_PROPERTY, profile.cliValue());
53+
}
54+
55+
public MappingProfile profile() {
56+
return profile;
57+
}
4458

4559
public JarScanResult scan(Path jarPath) {
4660
Path absoluteJar = jarPath.toAbsolutePath().normalize();

src/main/java/com/cope/addonparser/scanner/IsolatedScanner.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.cope.addonparser.scanner;
22

33
import com.cope.addonparser.model.JarScanResult;
4+
import com.cope.addonparser.profile.MappingProfile;
45
import com.fasterxml.jackson.databind.DeserializationFeature;
56
import com.fasterxml.jackson.databind.ObjectMapper;
67
import java.io.BufferedReader;
@@ -22,13 +23,23 @@ public class IsolatedScanner implements AutoCloseable {
2223
private static final String WORKER_MAIN = ScanWorker.class.getName();
2324

2425
private final long timeoutSeconds;
26+
private final MappingProfile profile;
2527

2628
public IsolatedScanner() {
27-
this(DEFAULT_TIMEOUT_SECONDS);
29+
this(DEFAULT_TIMEOUT_SECONDS, MappingProfile.fromSystemProperty());
30+
}
31+
32+
public IsolatedScanner(MappingProfile profile) {
33+
this(DEFAULT_TIMEOUT_SECONDS, profile);
2834
}
2935

3036
public IsolatedScanner(long timeoutSeconds) {
37+
this(timeoutSeconds, MappingProfile.fromSystemProperty());
38+
}
39+
40+
public IsolatedScanner(long timeoutSeconds, MappingProfile profile) {
3141
this.timeoutSeconds = timeoutSeconds;
42+
this.profile = profile;
3243
}
3344

3445
public JarScanResult scan(Path jarPath) {
@@ -39,7 +50,7 @@ public JarScanResult scan(Path jarPath) {
3950
result.jarPath = absoluteJar.toString();
4051

4152
try {
42-
List<String> command = buildWorkerCommand(absoluteJar);
53+
List<String> command = buildWorkerCommand(absoluteJar, profile);
4354
ProcessBuilder pb = new ProcessBuilder(command);
4455
pb.redirectErrorStream(false);
4556

@@ -118,7 +129,7 @@ public JarScanResult scan(Path jarPath) {
118129
}
119130
}
120131

121-
private static List<String> buildWorkerCommand(Path jarPath) {
132+
private static List<String> buildWorkerCommand(Path jarPath, MappingProfile profile) {
122133
List<String> cmd = new ArrayList<>();
123134
String javaHome = System.getProperty("java.home");
124135
String javaBin = Path.of(javaHome, "bin", "java").toString();
@@ -145,8 +156,12 @@ private static List<String> buildWorkerCommand(Path jarPath) {
145156
}
146157
}
147158

159+
cmd.add("-D" + MappingProfile.SYSTEM_PROPERTY + "=" + profile.cliValue());
160+
148161
cmd.add(WORKER_MAIN);
149162
cmd.add(jarPath.toString());
163+
cmd.add("--profile");
164+
cmd.add(profile.cliValue());
150165

151166
return cmd;
152167
}

src/main/java/com/cope/addonparser/scanner/ScanWorker.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.cope.addonparser.scanner;
22

33
import com.cope.addonparser.model.JarScanResult;
4+
import com.cope.addonparser.profile.MappingProfile;
45
import com.fasterxml.jackson.databind.ObjectMapper;
56
import java.io.PrintStream;
67
import java.nio.file.Path;
@@ -9,26 +10,45 @@
910
* Entry point for the isolated worker JVM process. Scans a single jar using {@link AddonScanner}
1011
* and writes the result as JSON to stdout.
1112
*
12-
* <p>Usage: {@code java ... com.cope.addonparser.scanner.ScanWorker <jar-path>}
13+
* <p>Usage: {@code java ... com.cope.addonparser.scanner.ScanWorker <jar-path> [--profile
14+
* legacy|26x]}
1315
*/
1416
public final class ScanWorker {
1517
private ScanWorker() {}
1618

1719
public static void main(String[] args) {
1820
if (args.length < 1) {
19-
System.err.println("Usage: ScanWorker <jar-path>");
21+
System.err.println("Usage: ScanWorker <jar-path> [--profile legacy|26x]");
2022
System.exit(2);
2123
return;
2224
}
2325

26+
Path jarPath = null;
27+
MappingProfile profile = MappingProfile.fromSystemProperty();
28+
for (int i = 0; i < args.length; i++) {
29+
String arg = args[i];
30+
if ("--profile".equals(arg) && i + 1 < args.length) {
31+
profile = MappingProfile.fromString(args[++i]);
32+
} else if (jarPath == null) {
33+
jarPath = Path.of(arg);
34+
}
35+
}
36+
37+
if (jarPath == null) {
38+
System.err.println("Usage: ScanWorker <jar-path> [--profile legacy|26x]");
39+
System.exit(2);
40+
return;
41+
}
42+
43+
System.setProperty(MappingProfile.SYSTEM_PROPERTY, profile.cliValue());
44+
2445
// Redirect stdout early so addon code can't pollute the JSON output
2546
PrintStream originalOut = System.out;
2647
System.setOut(System.err);
2748

28-
Path jarPath = Path.of(args[0]);
2949
JarScanResult result;
3050

31-
try (AddonScanner scanner = new AddonScanner()) {
51+
try (AddonScanner scanner = new AddonScanner(profile)) {
3252
result = scanner.scan(jarPath);
3353
} catch (Throwable t) {
3454
result = new JarScanResult();

src/main/java/com/cope/addonparser/util/ChildFirstClassLoader.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ private boolean isParentFirst(String name) {
368368
|| name.startsWith("sun.")
369369
|| name.startsWith("org.meteordev.starscript.")
370370
|| name.startsWith("meteordevelopment.starscript.")
371-
|| name.startsWith("com.cope.addonparser.");
371+
|| name.startsWith("com.cope.addonparser.")
372+
|| name.equals("dev.jfronny.meteoradditions.util.IModule");
372373
}
373374
}

0 commit comments

Comments
 (0)