Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 6 additions & 17 deletions src/main/java/org/quiltmc/installer/CliInstaller.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Set;

import org.jetbrains.annotations.Nullable;
import org.quiltmc.installer.action.Action;
Expand Down Expand Up @@ -147,11 +146,9 @@ private static Action<?> parse(String input) {
return Action.DISPLAY_HELP;
}

String intermediary = fetchIntermediary(GameSide.CLIENT, minecraftVersion);

// At this point all the require arguments have been parsed
if (split.size() == 0) {
return Action.installClient(minecraftVersion, launcherType, loaderType, null, intermediary, null, false, false);
return Action.installClient(minecraftVersion, launcherType, loaderType, null, null, null, false, false);
}

// Try to parse loader version first
Expand All @@ -166,7 +163,7 @@ private static Action<?> parse(String input) {

// No more arguments, just loader version
if (split.size() == 0) {
return Action.installClient(minecraftVersion, launcherType, loaderType, loaderVersion, intermediary, null, false, false);
return Action.installClient(minecraftVersion, launcherType, loaderType, loaderVersion, null, null, false, false);
}

// There are some additional options
Expand Down Expand Up @@ -224,7 +221,7 @@ private static Action<?> parse(String input) {
}
}

return Action.installClient(minecraftVersion, launcherType, loaderType, loaderVersion, intermediary, options.get("--install-dir"), !options.containsKey("--no-profile"), options.containsKey("--copy-profile-path"));
return Action.installClient(minecraftVersion, launcherType, loaderType, loaderVersion, null, options.get("--install-dir"), !options.containsKey("--no-profile"), options.containsKey("--copy-profile-path"));
}
case "server": {
if (split.size() < 1) {
Expand All @@ -247,7 +244,7 @@ private static Action<?> parse(String input) {

// At this point all the require arguments have been parsed
if (split.size() == 0) {
return Action.installServer(minecraftVersion, loaderType, null, null, false, false);
return Action.installServer(minecraftVersion, loaderType, null, null, null, false, false);
}

// Try to parse loader version first
Expand All @@ -262,7 +259,7 @@ private static Action<?> parse(String input) {

// No more arguments, just loader version
if (split.size() == 0) {
return Action.installServer(minecraftVersion, loaderType, loaderVersion, null, false, false);
return Action.installServer(minecraftVersion, loaderType, loaderVersion, null, null, false, false);
}

// There are some additional options
Expand Down Expand Up @@ -319,7 +316,7 @@ private static Action<?> parse(String input) {
}
}

return Action.installServer(minecraftVersion, loaderType, loaderVersion, options.get("--install-dir"), options.containsKey("--create-scripts"), options.containsKey("--download-server"));
return Action.installServer(minecraftVersion, loaderType, loaderVersion, null, options.get("--install-dir"), options.containsKey("--create-scripts"), options.containsKey("--download-server"));
}
default:
System.err.printf("Invalid side \"%s\", expected \"client\" or \"server\"%n", arg);
Expand All @@ -332,14 +329,6 @@ private static Action<?> parse(String input) {
}
}

private static String fetchIntermediary(GameSide side, String minecraftVersion) {
return OrnitheMeta.create(OrnitheMeta.ORNITHE_META_URL, Set.of(OrnitheMeta.INTERMEDIARY_VERSIONS_ENDPOINT)).thenApply(meta -> {
VersionManifest manifest = VersionManifest.create().join();
VersionManifest.Version version = manifest.getVersion(minecraftVersion);
return meta.getEndpoint(OrnitheMeta.INTERMEDIARY_VERSIONS_ENDPOINT).get(version.id(side));
}).join();
}

/**
* Takes a string and splits it at spaces while leaving quoted segements unsplit.
*
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/org/quiltmc/installer/GameSide.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,18 @@ public String id() {
public String launchJsonEndpoint() {
return this.launchJsonEndpoint;
}

public String stripFromVersion(String version) {
return version.endsWith(this.id) ? version.substring(0, version.length() - (this.id.length() + 1)) : version;
}

public boolean versionMatches(String version) {
for (GameSide side : GameSide.values()) {
if (version.endsWith(side.id)) {
return side == this;
}
}

return true;
}
}
36 changes: 36 additions & 0 deletions src/main/java/org/quiltmc/installer/Intermediary.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2023 QuiltMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.quiltmc.installer;

public class Intermediary {

private final String version;
private final String maven;

public Intermediary(String version, String maven) {
this.version = version;
this.maven = maven;
}

public String getVersion() {
return this.version;
}

public String getMavenNotation() {
return this.maven;
}
}
59 changes: 7 additions & 52 deletions src/main/java/org/quiltmc/installer/LaunchJson.java
Original file line number Diff line number Diff line change
Expand Up @@ -136,37 +136,21 @@ private static Map<String, Object> buildPackJsonMap(
* @return the launch json for a vanilla mc instance
*/
public static CompletableFuture<String> get(VersionManifest.Version gameVersion) {
String rawUrl = String.format(VersionManifest.VERSION_META_URL, gameVersion.id());

return CompletableFuture.supplyAsync(() -> {
try {
URL url = new URL(rawUrl);
URL url = new URL(gameVersion.url());
URLConnection connection = Connections.openConnection(url);
Map<String, Object> map;

try (InputStreamReader input = new InputStreamReader(connection.getInputStream())) {
map = (Map<String, Object>) Gsons.read(JsonReader.json(input));
}

for (String rawManifestUrl : gameVersion.details().manifests()) {
URL manifestUrl = new URL(rawManifestUrl);
URLConnection manifestConnection = Connections.openConnection(manifestUrl);

try (InputStreamReader input = new InputStreamReader(manifestConnection.getInputStream())) {
buildVersionJsonFromManifest(map, (Map<String, Object>) Gsons.read(JsonReader.json(input)));
}
}

// add the -vanilla suffix to the vanilla json 'cause
// we use a different version manifest than mojang and
// some version ids can differ from the official ones
map.put("id", String.format("%s-vanilla", gameVersion.id()));

// remove ASM from the libraries, as it will conflict
// with Loader's ASM dependency!
List<Map<String, String>> libs = (List<Map<String, String>>) map.get("libraries");
libs.removeIf(lib -> lib.get("name").contains("org.ow2.asm"));

StringWriter writer = new StringWriter();
Gsons.write(JsonWriter.json(writer), map);

Expand All @@ -177,32 +161,11 @@ public static CompletableFuture<String> get(VersionManifest.Version gameVersion)
});
}

private static void buildVersionJsonFromManifest(Map<String, Object> versionJson, Map<String, Object> manifest) {
for (String key : manifest.keySet()) {
if (versionJson.containsKey(key)) {
Object versionJsonElement = versionJson.get(key);
Object manifestElement = manifest.get(key);

if (versionJsonElement.equals(manifestElement)) {
// version json already contains this element, continue
} else {
// check if elements are objects and combine them
if (versionJsonElement instanceof Map && manifestElement instanceof Map) {
buildVersionJsonFromManifest((Map<String, Object>) versionJsonElement, (Map<String, Object>) manifestElement);
}
}
} else {
// version json does not have this element yet; add it
versionJson.put(key, manifest.get(key));
}
}
}

/**
* @return the launch json for a modded mc instance
*/
public static CompletableFuture<String> get(GameSide side, VersionManifest.Version gameVersion, LoaderType type, String loaderVersion) {
String rawUrl = OrnitheMeta.ORNITHE_META_URL + String.format(side.launchJsonEndpoint(), type.getName(), gameVersion.id(side), loaderVersion);
public static CompletableFuture<String> get(GameSide side, VersionManifest.Version gameVersion, Intermediary intermediary, LoaderType loaderType, String loaderVersion) {
String rawUrl = OrnitheMeta.ORNITHE_META_URL + String.format(side.launchJsonEndpoint(), loaderType.getName(), intermediary.getVersion(), loaderVersion);

return CompletableFuture.supplyAsync(() -> {
try {
Expand Down Expand Up @@ -240,7 +203,7 @@ public static CompletableFuture<String> get(GameSide side, VersionManifest.Versi
OrnitheMeta meta = OrnitheMeta.create(OrnitheMeta.ORNITHE_META_URL, Collections.singleton(libraryUpgradesEndpoint)).join();
List<Map<String, String>> libraryUpgrades = meta.getEndpoint(libraryUpgradesEndpoint);

if (type == LoaderType.QUILT) {
if (loaderType == LoaderType.QUILT) {
// Prevents a log warning about being unable to reach the active user beacon on stable versions.
switch (loaderVersion) {
case "0.19.2", "0.19.3", "0.19.4" -> {
Expand All @@ -256,17 +219,9 @@ public static CompletableFuture<String> get(GameSide side, VersionManifest.Versi
}
}

@SuppressWarnings("unchecked") List<Map<String, String>> libraries = (List<Map<String, String>>) map.get("libraries");
for (Map<String, String> library : libraries) {
if (library.get("name").startsWith("net.fabricmc:intermediary")) {
library.replace("name", library.get("name").replace("net.fabricmc:intermediary", "net.ornithemc:calamus-intermediary"));
library.replace("url", "https://maven.ornithemc.net/releases/");
}
if (library.get("name").startsWith("org.quiltmc:hashed")) {
library.replace("name", library.get("name").replace("org.quiltmc:hashed", "net.ornithemc:calamus-intermediary"));
library.replace("url", "https://maven.ornithemc.net/releases/");
}
}
@SuppressWarnings("unchecked")
List<Map<String, String>> libraries = (List<Map<String, String>>) map.get("libraries");

libraries.addAll(libraryUpgrades);

StringWriter writer = new StringWriter();
Expand Down
32 changes: 16 additions & 16 deletions src/main/java/org/quiltmc/installer/MmcPackCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,21 @@ public class MmcPackCreator {
//private static final Semver VERSION_1_3 = new Semver("1.3.0-pre+07261249");

private static String findLwjglVersion(VersionManifest manifest, String gameVersion) {
for (String rawUrl : manifest.getVersion(gameVersion).details().manifests()) {
try {
URL url = new URL(rawUrl);
URLConnection connection = Connections.openConnection(url);
VersionManifest.Version version = manifest.getVersion(gameVersion);

try (JsonReader reader = JsonReader.json(new BufferedReader(new InputStreamReader(connection.getInputStream())))) {
String lwjglVersion = findLwjglVersion(reader);
try {
URL url = new URL(version.url());
URLConnection connection = Connections.openConnection(url);

if (lwjglVersion != null) {
return lwjglVersion;
}
try (JsonReader reader = JsonReader.json(new BufferedReader(new InputStreamReader(connection.getInputStream())))) {
String lwjglVersion = findLwjglVersion(reader);

if (lwjglVersion != null) {
return lwjglVersion;
}
} catch (IOException e) {
throw new RuntimeException("issue while finding lwjgl version for Minecraft " + gameVersion, e);
}
} catch (IOException e) {
throw new RuntimeException("issue while finding lwjgl version for Minecraft " + gameVersion, e);
}

throw new RuntimeException("unable to find lwjgl version for Minecraft " + gameVersion);
Expand Down Expand Up @@ -181,7 +181,7 @@ private static String addLibraryUpgrades(Path instanceZipRoot, String gameVersio

}

public static void compileMmcZip(Path outPutDir, String gameVersion, LoaderType loaderType, String loaderVersion, String intermediaryInfo, VersionManifest manifest, boolean copyProfilePath) {
public static void compileMmcZip(Path outPutDir, String gameVersion, LoaderType loaderType, String loaderVersion, Intermediary intermediary, VersionManifest manifest, boolean copyProfilePath) {

String examplePackDir = "/packformat";
String packJsonPath = "mmc-pack.json";
Expand All @@ -191,9 +191,9 @@ public static void compileMmcZip(Path outPutDir, String gameVersion, LoaderType
String minecraftPatchPath = "patches/net.minecraft.json";

VersionManifest.Version version = manifest.getVersion(gameVersion);
String[] intermediaryParts = intermediaryInfo.split("[:]");
String intermediaryMaven = intermediaryParts[0] + ":" + intermediaryParts[1];
String intermediaryVersion = intermediaryParts[2];
String intermediaryMavenNotation = intermediary.getMavenNotation();
String intermediaryArtifact = intermediaryMavenNotation.substring(0, intermediaryMavenNotation.lastIndexOf(':'));
String intermediaryVersion = intermediary.getVersion();

try {
String lwjglVersion = findLwjglVersion(manifest, gameVersion);
Expand All @@ -204,7 +204,7 @@ public static void compileMmcZip(Path outPutDir, String gameVersion, LoaderType
String transformedIntermediaryJson = readResource(examplePackDir, intermediaryJsonPath)
.replaceAll("\\$\\{mc_version}", gameVersion)
.replaceAll("\\$\\{intermediary_ver}", intermediaryVersion)
.replaceAll("\\$\\{intermediary_maven}", intermediaryMaven);
.replaceAll("\\$\\{intermediary_maven}", intermediaryArtifact);

String transformedInstanceCfg = readResource(examplePackDir, instanceCfgPath)
.replaceAll("\\$\\{mc_version}", gameVersion);
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/org/quiltmc/installer/OrnitheMeta.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -62,8 +61,8 @@ public static Endpoint<List<String>> loaderVersionsEndpoint(LoaderType type) {
*
* <p>The returned map has the version as the key and the maven artifact as the value
*/
public static final Endpoint<Map<String, String>> INTERMEDIARY_VERSIONS_ENDPOINT = new Endpoint<>("/v3/versions/intermediary", reader -> {
Map<String, String> ret = new LinkedHashMap<>();
public static final Endpoint<List<Intermediary>> INTERMEDIARY_VERSIONS_ENDPOINT = new Endpoint<>("/v3/versions/intermediary", reader -> {
List<Intermediary> ret = new ArrayList<>();

if (reader.peek() != JsonToken.BEGIN_ARRAY) {
throw new ParseException("Intermediary versions must be in an array", reader);
Expand Down Expand Up @@ -111,7 +110,7 @@ public static Endpoint<List<String>> loaderVersionsEndpoint(LoaderType type) {
throw new ParseException("Intermediary version entry does not have a maven field", reader);
}

ret.put(version, maven);
ret.add(new Intermediary(version, maven));

reader.endObject();
}
Expand Down
Loading
Loading