Skip to content

Commit d036cf9

Browse files
committed
Add mcp-data task
1 parent b572f74 commit d036cf9

File tree

6 files changed

+246
-30
lines changed

6 files changed

+246
-30
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717
/.idea/
1818
/output.jar
1919
/output.jar.cache
20+
/parchment.tsrg
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/*
2+
* Copyright (c) Forge Development LLC and contributors
3+
* SPDX-License-Identifier: LGPL-2.1-only
4+
*/
5+
package net.minecraftforge.mcmaven.cli;
6+
7+
import java.io.File;
8+
import java.nio.file.Files;
9+
import java.util.zip.ZipFile;
10+
11+
import joptsimple.OptionParser;
12+
import net.minecraftforge.mcmaven.impl.MinecraftMaven;
13+
import net.minecraftforge.mcmaven.impl.cache.Cache;
14+
import net.minecraftforge.mcmaven.impl.mappings.Mappings;
15+
import net.minecraftforge.mcmaven.impl.mappings.ParchmentMappings;
16+
import net.minecraftforge.mcmaven.impl.repo.mcpconfig.MCPConfigRepo;
17+
import net.minecraftforge.mcmaven.impl.util.Artifact;
18+
import net.minecraftforge.srgutils.IMappingFile;
19+
import net.minecraftforge.srgutils.IRenamer;
20+
import net.minecraftforge.srgutils.IMappingFile.IField;
21+
import net.minecraftforge.srgutils.IMappingFile.IMethod;
22+
import net.minecraftforge.srgutils.IMappingFile.IParameter;
23+
import net.minecraftforge.util.logging.Log;
24+
25+
// TODO [Mavenizer][MCPDataTask] This is a copy of FG6's ExtractMCPData task.
26+
// its not the best, but I dont want to re-wrok INSTALLER_TOOLS to put the tsrg in the mappings zip
27+
public class MCPDataTask {
28+
public static void run(String[] args) throws Exception {
29+
int ret = runI(args);
30+
if (ret != 0) {
31+
Log.release();
32+
//System.exit(ret);
33+
}
34+
}
35+
36+
private static int runI(String[] args) throws Exception {
37+
// TODO [MCMavenizer] Make this into a --log [level] option
38+
Log.enabled = Log.Level.INFO;
39+
40+
var parser = new OptionParser();
41+
parser.allowsUnrecognizedOptions();
42+
43+
//@formatter:off
44+
// help message
45+
var helpO = parser.accepts("help",
46+
"Displays this help message and exits")
47+
.forHelp();
48+
49+
// root cache directory
50+
var cacheO = parser.accepts("cache",
51+
"Directory to store data needed for this program")
52+
.withRequiredArg().ofType(File.class).defaultsTo(new File("cache"));
53+
54+
// jdk cache directory
55+
var jdkCacheO = parser.accepts("jdk-cache",
56+
"Directory to store jdks downloaded from the disoco api")
57+
.withRequiredArg().ofType(File.class).defaultsTo(new File("cache/jdks"));
58+
59+
var outputO = parser.accepts("output",
60+
"File to place output data into")
61+
.withRequiredArg().ofType(File.class);
62+
63+
var artifactO = parser.accepts("artifact",
64+
"MCPConfig artifact coordinates")
65+
.withRequiredArg();
66+
67+
var versionO = parser.accepts("version",
68+
"MCPConfig artifact version")
69+
.availableUnless(artifactO)
70+
.withRequiredArg();
71+
72+
var officialO = parser.accepts("mappings",
73+
"Use to enable using official mappings");
74+
75+
var parchmentO = parser.accepts("parchment",
76+
"Version of parchment mappings to use, snapshots are not supported")
77+
.availableUnless(officialO)
78+
.withRequiredArg();
79+
80+
officialO
81+
.availableUnless(parchmentO);
82+
83+
var keyO = parser.accepts("key",
84+
"The key for which data file to extract")
85+
.withRequiredArg();
86+
//@formatter:on
87+
88+
var options = parser.parse(args);
89+
if (options.has(helpO)) {
90+
parser.printHelpOn(Log.INFO);
91+
return -1;
92+
}
93+
94+
var output = options.valueOf(outputO);
95+
var cacheRoot = options.valueOf(cacheO);
96+
var jdkCacheRoot = !options.has(cacheO) || options.has(jdkCacheO)
97+
? options.valueOf(jdkCacheO)
98+
: new File(cacheRoot, "jdks");
99+
100+
var artifact =
101+
options.has(artifactO) ? Artifact.from(options.valueOf(artifactO)) :
102+
options.has(versionO) ? Artifact.from("de.oceanlabs.mcp", "mcp_config", options.valueOf(versionO), null, "zip") :
103+
null;
104+
105+
if (artifact == null) {
106+
Log.error("Missing mcp --version or --artifact");
107+
return -2;
108+
}
109+
110+
var mcVersion = MinecraftMaven.mcpToMcVersion(artifact.getVersion());
111+
Mappings mappings = null;
112+
if (options.has(officialO))
113+
mappings = new Mappings("official", null).withMCVersion(mcVersion);
114+
else if (options.has(parchmentO))
115+
mappings = new ParchmentMappings(options.valueOf(parchmentO)).withMCVersion(mcVersion);
116+
else
117+
mappings = null;
118+
119+
var key = options.valueOf(keyO);
120+
if (key == null) {
121+
Log.error("Missing --key option");
122+
return -3;
123+
}
124+
125+
var repo = new MCPConfigRepo(new Cache(cacheRoot, jdkCacheRoot));
126+
Log.info(" Output: " + output.getAbsolutePath());
127+
Log.info(" Cache: " + cacheRoot.getAbsolutePath());
128+
Log.info(" JDK Cache: " + jdkCacheRoot.getAbsolutePath());
129+
Log.info(" Artifact: " + artifact);
130+
Log.info(" Key: " + key);
131+
if (mappings != null)
132+
Log.info(" Mappings: " + mappings);
133+
Log.info();
134+
135+
var mcp = repo.get(artifact);
136+
var side = mcp.getSide("joined");
137+
138+
var cfg = mcp.getConfig().getData("joined");
139+
var path = cfg.get(key);
140+
if (path == null && "statics".equals(key))
141+
path = "config/static_methods.txt";
142+
143+
if (path == null) {
144+
Log.error("Could not find data entry for '%s'".formatted(key));
145+
return -4;
146+
}
147+
148+
try (ZipFile zip = new ZipFile(mcp.getData())) {
149+
var entry = zip.getEntry(path);
150+
if (entry == null) {
151+
Log.error("Invalid config zip, missing file: " + path);
152+
return -5;
153+
}
154+
155+
if ("mappings".equals(key)) {
156+
var ret = IMappingFile.load(zip.getInputStream(entry));
157+
158+
if (mcp.getConfig().official) {
159+
var mc = mcp.getMinecraftTasks();
160+
var client = mc.versionFile("client_mappings", "txt");
161+
var server = mc.versionFile("server_mappings", "txt");
162+
163+
var obf2OffClient = IMappingFile.load(client.execute());
164+
var obf2OffServer = IMappingFile.load(server.execute());
165+
var obf2Off = obf2OffClient.merge(obf2OffServer);
166+
167+
ret = ret.rename(new IRenamer() {
168+
@Override
169+
public String rename(IMappingFile.IClass value) {
170+
return obf2Off.remapClass(value.getOriginal());
171+
}
172+
});
173+
}
174+
175+
if (mappings != null) {
176+
var csv = mappings.getCsvZip(side).execute();
177+
var names = Mappings.load(csv).names();
178+
ret = ret.rename(new IRenamer() {
179+
@Override
180+
public String rename(IField value) {
181+
return names.getOrDefault(value.getMapped(), value.getMapped());
182+
}
183+
184+
@Override
185+
public String rename(IMethod value) {
186+
return names.getOrDefault(value.getMapped(), value.getMapped());
187+
}
188+
189+
@Override
190+
public String rename(IParameter value) {
191+
return names.getOrDefault(value.getMapped(), value.getMapped());
192+
}
193+
});
194+
}
195+
196+
197+
ret.write(output.getAbsoluteFile().toPath(), IMappingFile.Format.TSRG2, false);
198+
} else {
199+
Files.copy(zip.getInputStream(entry), output.toPath());
200+
}
201+
}
202+
203+
return 0;
204+
}
205+
}

src/main/java/net/minecraftforge/mcmaven/cli/Tasks.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
enum Tasks {
1010
MAVEN(MavenTask::run, "Generates a maven repository for Minecraft Artifacts"),
11-
MCP(MCPTask::run, "Generates a 'clean' sources jar from a MCPConfig pipeline")
11+
MCP(MCPTask::run, "Generates a 'clean' sources jar from a MCPConfig pipeline"),
12+
MCP_DATA(MCPDataTask::run, "Extracts a data file from a MCPConfig archive")
1213
;
1314

1415
interface Callback {
@@ -19,7 +20,7 @@ interface Callback {
1920
final String description;
2021

2122
private Tasks(Callback callback, String description) {
22-
this.key = name().toLowerCase(Locale.ENGLISH);
23+
this.key = name().toLowerCase(Locale.ENGLISH).replace('_', '-');
2324
this.callback = callback;
2425
this.description = description;
2526
}

src/main/java/net/minecraftforge/mcmaven/impl/MinecraftMaven.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@ public static String mcpToMcVersion(String version) {
105105
// MCP names can either be {MCVersion} or {MCVersion}-{Timestamp}, EXA: 1.21.1-20240808.132146
106106
// So lets see if the thing following the last - matches a timestamp
107107
int idx = version.lastIndexOf('-');
108-
if (idx < 0 || idx != version.length() - 15)
108+
if (idx < 0)
109109
return version;
110-
if (!version.substring(idx).matches("\\d{8}\\.\\d{6}"))
110+
if (!version.substring(idx + 1).matches("\\d{8}\\.\\d{6}"))
111111
return version;
112112
return version.substring(0, idx);
113113
}

src/main/java/net/minecraftforge/mcmaven/impl/mappings/Mappings.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
package net.minecraftforge.mcmaven.impl.mappings;
66

77
import java.io.File;
8+
import java.io.IOException;
9+
import java.io.InputStreamReader;
810
import java.util.Collections;
911
import java.util.HashMap;
1012
import java.util.List;
1113
import java.util.Map;
14+
import java.util.zip.ZipFile;
15+
1216
import net.minecraftforge.mcmaven.impl.GlobalOptions;
1317
import net.minecraftforge.mcmaven.impl.repo.mcpconfig.MCPSide;
1418
import net.minecraftforge.mcmaven.impl.util.Artifact;
@@ -18,6 +22,8 @@
1822
import net.minecraftforge.util.hash.HashStore;
1923
import org.jetbrains.annotations.Nullable;
2024

25+
import de.siegmar.fastcsv.reader.CsvReader;
26+
2127
public class Mappings {
2228
public static final String CHANNEL_ATTR = "net.minecraftforge.mappings.channel";
2329
public static final String VERSION_ATTR = "net.minecraftforge.mappings.version";
@@ -36,6 +42,32 @@ public static Mappings of(String mappingsNotation) {
3642
: new Mappings(channel, version);
3743
}
3844

45+
public record Data(Map<String, String> names, Map<String, String> docs) { }
46+
public static Data load(File data) throws IOException {
47+
var names = new HashMap<String, String>();
48+
var docs = new HashMap<String, String>();
49+
try (var zip = new ZipFile(data)) {
50+
var entries = zip.stream().filter(e -> e.getName().endsWith(".csv")).toList();
51+
for (var entry : entries) {
52+
try (var reader = CsvReader.builder().ofNamedCsvRecord(new InputStreamReader(zip.getInputStream(entry)))) {
53+
for (var row : reader) {
54+
var header = row.getHeader();
55+
var obf = header.contains("searge") ? "searge" : "param";
56+
var searge = row.getField(obf);
57+
names.put(searge, row.getField("name"));
58+
if (header.contains("desc")) {
59+
String desc = row.getField("desc");
60+
if (!desc.isBlank())
61+
docs.put(searge, desc);
62+
}
63+
}
64+
}
65+
}
66+
}
67+
68+
return new Data(names, docs);
69+
}
70+
3971
public Mappings(String channel, @Nullable String version) {
4072
this.channel = channel;
4173
this.version = version;

src/main/java/net/minecraftforge/mcmaven/impl/tasks/MCPNames.java

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55
package net.minecraftforge.mcmaven.impl.tasks;
66

7-
import de.siegmar.fastcsv.reader.CsvReader;
7+
import net.minecraftforge.mcmaven.impl.mappings.Mappings;
88
import net.minecraftforge.util.hash.HashFunction;
99
import net.minecraftforge.util.logging.Log;
1010
import org.apache.commons.io.IOUtils;
@@ -15,15 +15,13 @@
1515
import java.io.File;
1616
import java.io.IOException;
1717
import java.io.InputStream;
18-
import java.io.InputStreamReader;
1918
import java.io.StringReader;
2019
import java.nio.charset.Charset;
2120
import java.nio.charset.StandardCharsets;
2221
import java.util.ArrayList;
2322
import java.util.Arrays;
2423
import java.util.Collection;
2524
import java.util.Deque;
26-
import java.util.HashMap;
2725
import java.util.HashSet;
2826
import java.util.LinkedList;
2927
import java.util.List;
@@ -32,7 +30,6 @@
3230
import java.util.Set;
3331
import java.util.regex.Matcher;
3432
import java.util.regex.Pattern;
35-
import java.util.zip.ZipFile;
3633

3734
// TODO: [MCMavenizer][MCPName] GARBAGE GARBAGE GARBAGE, CLEAN UP OR RE-IMPLEMENT
3835
final class MCPNames {
@@ -49,28 +46,8 @@ final class MCPNames {
4946
//@formatter:on
5047

5148
static MCPNames load(File data) throws IOException {
52-
var names = new HashMap<String, String>();
53-
var docs = new HashMap<String, String>();
54-
try (var zip = new ZipFile(data)) {
55-
var entries = zip.stream().filter(e -> e.getName().endsWith(".csv")).toList();
56-
for (var entry : entries) {
57-
try (var reader = CsvReader.builder().ofNamedCsvRecord(new InputStreamReader(zip.getInputStream(entry)))) {
58-
for (var row : reader) {
59-
var header = row.getHeader();
60-
var obf = header.contains("searge") ? "searge" : "param";
61-
var searge = row.getField(obf);
62-
names.put(searge, row.getField("name"));
63-
if (header.contains("desc")) {
64-
String desc = row.getField("desc");
65-
if (!desc.isBlank())
66-
docs.put(searge, desc);
67-
}
68-
}
69-
}
70-
}
71-
}
72-
73-
return new MCPNames(HashFunction.SHA1.hash(data), names, docs);
49+
var loaded = Mappings.load(data);
50+
return new MCPNames(HashFunction.SHA1.hash(data), loaded.names(), loaded.docs());
7451
}
7552

7653
// NOTE: this is a micro-optimization to avoid creating a new pattern for every line

0 commit comments

Comments
 (0)