Skip to content

Commit

Permalink
Make MinecraftProvider a little more modular
Browse files Browse the repository at this point in the history
This is useful for NeoForge, where we need to extract the original jars,
not the split ones.
  • Loading branch information
SquidDev committed Jun 11, 2024
1 parent dbf66b2 commit eec0a8b
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,36 +35,36 @@ public MinecraftProvider(FileDownloader downloader) {
* A single Minecraft jar, and information required to consume that jar.
*
* @param jar The path to the jar file.
* @param mappings The mappings for this jar.
* @param dependencies A list of dependencies for this artifact.
*/
public record MinecraftJar(FileFingerprint jar, List<String> dependencies) {
public record MinecraftJar(FileFingerprint jar, FileFingerprint mappings, List<String> dependencies) {
}

/**
* All Minecraft artifacts.
* The raw artifacts.
*
* @param common The common/server jar.
* @param client The client-only jar.
* @param mappings The list of mappings used to deobfuscate the jars.
* @param server The server jar.
* @param client The client jar.
*/
public record Artifacts(
MinecraftJar common,
MinecraftJar client,
List<FileFingerprint> mappings
) {
public record RawArtifacts(MinecraftJar server, MinecraftJar client) {
}

/**
* Download the vanilla Minecraft jars and extract their dependencies.
* All Minecraft artifacts.
*
* @param target The directory to download and unpack the jars into.
* @param versionInfo All information about the version.
* @param refresh Re-process
* @return The resulting {@linkplain Artifacts minecraft artifacts}.
* @throws IOException If the jars could not be downloaded.
* @param common The common/server jar.
* @param client The client-only jar.
*/
public Artifacts provide(Path target, MinecraftVersion versionInfo, boolean refresh) throws IOException {
return provide(target, versionInfo.downloads(), versionInfo.libraries(), refresh);
public record SplitArtifacts(MinecraftJar common, MinecraftJar client) {
/**
* Get the list of mappings used to deobfuscate the jars.
*
* @return The list of mappings.
*/
public List<FileFingerprint> mappings() {
return List.of(common().mappings(), client().mappings());
}
}

/**
Expand All @@ -73,15 +73,13 @@ public Artifacts provide(Path target, MinecraftVersion versionInfo, boolean refr
* @param target The directory to download and unpack the jars into.
* @param downloads The downloads for this version.
* @param clientLibraries The client libraries for this version.
* @param refresh Re-process
* @return The resulting {@linkplain Artifacts minecraft artifacts}.
* @return The resulting {@linkplain SplitArtifacts minecraft artifacts}.
* @throws IOException If the jars could not be downloaded.
*/
public Artifacts provide(
public RawArtifacts provideRaw(
Path target,
MinecraftVersion.Downloads downloads,
List<MinecraftVersion.Library> clientLibraries,
boolean refresh
List<MinecraftVersion.Library> clientLibraries
) throws IOException {
var clientJar = target.resolve("client.jar");
var clientMappings = target.resolve("client.txt");
Expand Down Expand Up @@ -117,24 +115,44 @@ public Artifacts provide(
.filter(x -> x.rules() == null || x.rules().isEmpty())
.map(MinecraftVersion.Library::name).toList();

var clientLibrarySet = new HashSet<>(serverLibraries);
var commonLibraries = serverLibraries.stream().filter(clientLibrarySet::contains).toList();
return new RawArtifacts(
new MinecraftJar(
new FileFingerprint(extractedServerJar, downloads.server().sha1()),
new FileFingerprint(serverMappings, downloads.server_mappings().sha1()),
serverLibraries
),
new MinecraftJar(
new FileFingerprint(clientJar, downloads.client().sha1()),
new FileFingerprint(clientMappings, downloads.client_mappings().sha1()),
clientLibraryNames
)
);
}

/**
* Split the vanilla Minecraft jars into separate common and client jars.
*
* @param target The directory to download and unpack the jars into.
* @param rawArtifacts The raw Minecraft artifacts, as returned by {@link #provideRaw(Path, MinecraftVersion.Downloads, List)}.
* @param refresh Re-process the split files.
* @return The resulting {@linkplain SplitArtifacts minecraft artifacts}.
* @throws IOException If the jars could not be downloaded.
*/
public SplitArtifacts provideSplit(Path target, RawArtifacts rawArtifacts, boolean refresh) throws IOException {
// Split the client and server jars.
var clientOnlyJar = target.resolve("client-only.jar");
var commonJar = target.resolve("common.jar");
// FIXME: This doesn't correctly handle the jars changing. I don't think that'll ever happen, but worth checking!
if (refresh || !MoreFiles.exists(commonJar) || !MoreFiles.exists(clientOnlyJar)) {
JarContentsFilter.split(extractedServerJar, clientJar, commonJar, clientOnlyJar);
JarContentsFilter.split(rawArtifacts.server().jar().path(), rawArtifacts.client().jar().path(), commonJar, clientOnlyJar);
}

return new Artifacts(
new MinecraftJar(FileFingerprint.createImmutable(commonJar), commonLibraries),
new MinecraftJar(FileFingerprint.createImmutable(clientOnlyJar), clientLibraryNames),
List.of(
new FileFingerprint(clientMappings, downloads.client_mappings().sha1()),
new FileFingerprint(serverMappings, downloads.server_mappings().sha1())
)
var clientLibrarySet = new HashSet<>(rawArtifacts.client().dependencies());
var commonDependencies = rawArtifacts.server().dependencies().stream().filter(clientLibrarySet::contains).toList();

return new SplitArtifacts(
new MinecraftJar(FileFingerprint.createImmutable(commonJar), rawArtifacts.server().mappings(), commonDependencies),
new MinecraftJar(FileFingerprint.createImmutable(clientOnlyJar), rawArtifacts.client().mappings(), rawArtifacts.client().dependencies())
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public record TransformedJars(TransformedJar common, TransformedJar clientOnly)

public TransformedJars provide(
String version,
MinecraftProvider.Artifacts artifacts,
MinecraftProvider.SplitArtifacts artifacts,
FileFingerprint mappings,
List<FileFingerprint> accessWideners,
boolean refresh
Expand Down Expand Up @@ -215,7 +215,7 @@ private static byte[] transformClass(AccessWidener accessWidener, byte[] bytes)
}

private static void writeMinecraftPoms(
String version, MinecraftProvider.Artifacts artifacts, Path mavenPath, MavenRelease common, MavenRelease clientOnly
String version, MinecraftProvider.SplitArtifacts artifacts, Path mavenPath, MavenRelease common, MavenRelease clientOnly
) throws IOException {
writeMinecraftPom(
mavenPath, common, "Minecraft " + version + " (common)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class MinecraftProviderTest {
@TempDir
private Path dir;

public static MinecraftProvider.Artifacts setupMinecraft(Path dir, FileDownloader downloader) throws IOException {
public static MinecraftProvider.SplitArtifacts setupMinecraft(Path dir, FileDownloader downloader) throws IOException {
var downloads = new MinecraftVersion.Downloads(
new MinecraftVersion.Download("fd19469fed4a4b4c15b2d5133985f0e3e7816a8a", 0, "https://piston-data.mojang.com/v1/objects/fd19469fed4a4b4c15b2d5133985f0e3e7816a8a/client.jar"),
new MinecraftVersion.Download("be76ecc174ea25580bdc9bf335481a5192d9f3b7", 0, "https://piston-data.mojang.com/v1/objects/be76ecc174ea25580bdc9bf335481a5192d9f3b7/client.txt"),
Expand All @@ -29,7 +29,9 @@ public static MinecraftProvider.Artifacts setupMinecraft(Path dir, FileDownloade
new MinecraftVersion.Library(null, "org.slf4j:slf4j-api:2.0.7", null)
);

return new MinecraftProvider(downloader).provide(dir, downloads, libraries, false);
var provider = new MinecraftProvider(downloader);
var rawArtifacts = provider.provideRaw(dir, downloads, libraries);
return new MinecraftProvider(downloader).provideSplit(dir, rawArtifacts, false);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public interface Parameters extends BuildServiceParameters {
private final Path localMavenPath;
private final boolean refresh;

private final @GuardedBy("minecraftVersions") Map<String, cc.tweaked.vanillaextract.core.minecraft.manifest.MinecraftVersion> minecraftVersions = new HashMap<>();
private final @GuardedBy("minecraftVersions") Map<String, MinecraftVersion> minecraftVersions = new HashMap<>();
private final @GuardedBy("minecraftVersions") MinecraftVersionProvider minecraftVersionProvider;

private final MinecraftProvider minecraftProvider;
Expand Down Expand Up @@ -85,10 +85,6 @@ public MinecraftVersion getVersion(String version) throws IOException {
}
}

private synchronized MinecraftProvider.Artifacts getMinecraft(String version) throws IOException {
return minecraftProvider.provide(globalPluginCache.resolve(version), getVersion(version), refresh);
}

public Everything provide(String version, MappingProvider mappings, List<Path> accessWideners, boolean refresh) throws IOException {
long start = System.nanoTime();
Everything result = provideVanilla(version, mappings, accessWideners, refresh);
Expand All @@ -97,7 +93,14 @@ public Everything provide(String version, MappingProvider mappings, List<Path> a
}

private Everything provideVanilla(String version, MappingProvider mappings, List<Path> accessWideners, boolean refresh) throws IOException {
var minecraft = getMinecraft(version);
MinecraftProvider.SplitArtifacts minecraft;
synchronized (minecraftProvider) {
var folder = globalPluginCache.resolve(version);
var versionInfo = getVersion(version);
var raw = minecraftProvider.provideRaw(folder, versionInfo.downloads(), versionInfo.libraries());
minecraft = minecraftProvider.provideSplit(folder, raw, refresh);
}

var resolvedMappings = mappings.resolve(new MappingProvider.Context(minecraft.mappings(), this::fingerprint));
var mappingPath = mappingsFileProvider.saveMappings(version, resolvedMappings);

Expand Down

0 comments on commit eec0a8b

Please sign in to comment.