diff --git a/build.gradle.kts b/build.gradle.kts index f2d4137..b0fdb8c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,9 +2,8 @@ import java.net.URI plugins { java - `java-library` `maven-publish` - // application +// application id("net.kyori.blossom") version "1.3.1" id("com.diffplug.spotless") version "6.19.0" @@ -31,10 +30,6 @@ repositories { } } -sourceSets { - create("java8") -} - dependencies { implementation("org.quiltmc.parsers:json:0.2.1") compileOnly("org.jetbrains:annotations:20.1.0") @@ -52,25 +47,16 @@ blossom { replaceToken("__INSTALLER_VERSION", project.version) } -tasks.compileJava { - options.release.set(17) -} +// Use this instead of compile task args cause this autoconfigures IDEs as well +java.sourceCompatibility = JavaVersion.VERSION_1_8 +java.targetCompatibility = JavaVersion.VERSION_1_8 -tasks.getByName("compileJava8Java", JavaCompile::class) { - options.release.set(8) -} -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(17)) - } -} // Cannot use application for the time being because shadow does not like mainClass being set for some reason. // There is a PR which has fixed this, so update shadow probably when 6.10.1 or 6.11 is out //application { // mainClass.set("org.quiltmc.installer.Main") //} -tasks.jar.get().dependsOn(tasks["compileJava8Java"]) tasks.jar { manifest { attributes["Implementation-Title"] = "Ornithe-Installer" @@ -88,7 +74,6 @@ tasks.shadowJar { // Compiler does not know which set method we are targeting with null value val classifier: String? = null; archiveClassifier.set(classifier) - from(sourceSets["java8"].output) } tasks.assemble { @@ -110,7 +95,6 @@ val copyForNative = tasks.register("copyForNative") { } } - publishing { publications { if (env["TARGET"] == null) { diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java deleted file mode 100644 index 468945d..0000000 --- a/src/main/java/module-info.java +++ /dev/null @@ -1,6 +0,0 @@ -module org.quiltmc.installer { - requires java.desktop; - requires org.jetbrains.annotations; - requires org.quiltmc.parsers.json; - requires jdk.crypto.ec; -} \ No newline at end of file diff --git a/src/main/java/org/quiltmc/installer/IntermediaryGenerations.java b/src/main/java/org/quiltmc/installer/IntermediaryGenerations.java index 8b5935b..918528d 100644 --- a/src/main/java/org/quiltmc/installer/IntermediaryGenerations.java +++ b/src/main/java/org/quiltmc/installer/IntermediaryGenerations.java @@ -16,6 +16,7 @@ package org.quiltmc.installer; +import java.util.HashSet; import java.util.Set; import org.quiltmc.installer.OrnitheMeta.Endpoint; @@ -25,7 +26,7 @@ public class IntermediaryGenerations { static { try { Endpoint endpoint = OrnitheMeta.intermediaryGenerationsEndpoint(); - OrnitheMeta meta = OrnitheMeta.create(OrnitheMeta.ORNITHE_META_URL, Set.of(endpoint)).get(); + OrnitheMeta meta = OrnitheMeta.create(OrnitheMeta.ORNITHE_META_URL, new HashSet>(){{add(endpoint);}}).get(); int[] gens = meta.getEndpoint(endpoint); latest = gens[0]; diff --git a/src/main/java/org/quiltmc/installer/LaunchJson.java b/src/main/java/org/quiltmc/installer/LaunchJson.java index 62764e7..0cdc7c3 100644 --- a/src/main/java/org/quiltmc/installer/LaunchJson.java +++ b/src/main/java/org/quiltmc/installer/LaunchJson.java @@ -43,10 +43,12 @@ public static CompletableFuture getMmcJson(VersionManifest.Version gameV Map> downloads = (Map>) vanillaMap.get("downloads"); Map client = downloads.get("client"); - Map mainJar = Map.of( - "downloads", Map.of("artifact",client), - "name",clientName - ); + Map mainJar = new HashMap() {{ + put("downloads", new HashMap() {{ + put("artifact", client); + }}); + put("name", clientName); + }}; // remove lwjgl as it is handled separately by the pack generator List> vanillaLibraries = (List>) vanillaMap.get("libraries"); @@ -111,7 +113,7 @@ private static Map buildPackJsonMap( } moddedJsonMap.put("assetIndex",vanilaMap.get("assetIndex")); - moddedJsonMap.put("compatibleJavaMajors", List.of(8, 17, 21, 25)); + moddedJsonMap.put("compatibleJavaMajors", Arrays.asList(8, 17, 21, 25)); moddedJsonMap.put("compatibleJavaName", "java-runtime-epsilon"); moddedJsonMap.put("formatVersion", 1); moddedJsonMap.put("libraries", modifiedLibraries); @@ -120,12 +122,12 @@ private static Map buildPackJsonMap( moddedJsonMap.put("minecraftArguments", minecraftArguments); moddedJsonMap.put("name", "Minecraft"); moddedJsonMap.put("releaseTime", vanilaMap.get("releaseTime")); - moddedJsonMap.put("requires",List.of( - Map.of( - "suggests", "${lwjgl_version}", - "uid", "${lwjgl_uid}" - ) - )); + moddedJsonMap.put("requires", Collections.singletonList( + new HashMap() {{ + put("suggests","${lwjgl_version}"); + put("uid","${lwjgl_uid}"); + }} + )); moddedJsonMap.put("type", vanilaMap.get("type")); moddedJsonMap.put("uid", "net.minecraft"); moddedJsonMap.put("version", gameVersion); @@ -144,7 +146,8 @@ public static CompletableFuture get(VersionManifest.Version gameVersion) Map map; try (InputStreamReader input = new InputStreamReader(connection.getInputStream())) { - map = (Map) Gsons.read(JsonReader.json(input)); + //noinspection unchecked + map = (Map) Gsons.read(JsonReader.json(input)); } // add the -vanilla suffix to the vanilla json 'cause @@ -199,6 +202,10 @@ public static CompletableFuture get(GameSide side, VersionManifest.Versi throw new UncheckedIOException(e); // Handled via .exceptionally(...) } + if (map == null) { + throw new RuntimeException("Read meta json is null?"); + } + // we apply the library upgrades only to the Ornithe instance, not the Vanilla instance OrnitheMeta.Endpoint>> libraryUpgradesEndpoint = OrnitheMeta.libraryUpgradesEndpoint(intermediaryGen, gameVersion.id()); OrnitheMeta meta = OrnitheMeta.create(OrnitheMeta.ORNITHE_META_URL, Collections.singleton(libraryUpgradesEndpoint)).join(); @@ -207,16 +214,10 @@ public static CompletableFuture get(GameSide side, VersionManifest.Versi 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" -> { - @SuppressWarnings("unchecked") - Map> arguments = (Map>)map.get("arguments"); - arguments - .computeIfAbsent("jvm", (key) -> new ArrayList<>()) - .add("-Dloader.disable_beacon=true"); - } - default -> { - // do nothing - } + case "0.19.2": + case "0.19.4": + case "0.19.3": + disableBeacon(map); } } @@ -235,6 +236,14 @@ public static CompletableFuture get(GameSide side, VersionManifest.Versi }); } + private static void disableBeacon(Map map) { + @SuppressWarnings("unchecked") + Map> arguments = (Map>)map.get("arguments"); + arguments + .computeIfAbsent("jvm", (key) -> new ArrayList<>()) + .add("-Dloader.disable_beacon=true"); + } + private LaunchJson() { } } diff --git a/src/java8/java/org/quiltmc/installer/Main.java b/src/main/java/org/quiltmc/installer/Main.java similarity index 100% rename from src/java8/java/org/quiltmc/installer/Main.java rename to src/main/java/org/quiltmc/installer/Main.java diff --git a/src/main/java/org/quiltmc/installer/MmcPackCreator.java b/src/main/java/org/quiltmc/installer/MmcPackCreator.java index 3db87d0..a60a55e 100644 --- a/src/main/java/org/quiltmc/installer/MmcPackCreator.java +++ b/src/main/java/org/quiltmc/installer/MmcPackCreator.java @@ -25,12 +25,15 @@ import java.io.*; import java.net.URL; import java.net.URLConnection; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; public class MmcPackCreator { private static final String ENV_WRAPPER_COMMAND = "WrapperCommand=env __GL_THREADED_OPTIMIZATIONS=0"; @@ -167,9 +170,13 @@ private static String addLibraryUpgrades(Path instanceZipRoot, String gameVersio String libName = name.substring(name.indexOf(':')+1, name.lastIndexOf(':')); String version = name.substring(name.lastIndexOf(':')+1); - Files.writeString(instanceZipRoot.resolve("patches").resolve(uid + ".json"), - String.format(patch, name, url, libName, uid, version)); - components.add(Map.of("cachedName", libName,"cachedVersion", version,"uid", uid)); + Files.write(instanceZipRoot.resolve("patches").resolve(uid + ".json"), + String.format(patch, name, url, libName, uid, version).getBytes(StandardCharsets.UTF_8)); + components.add(new HashMap() {{ + put("cachedName", libName); + put("cachedVersion", version); + put("uid", uid); + }}); } @@ -222,16 +229,27 @@ public static void compileMmcZip(Path outPutDir, String gameVersion, LoaderType Path zipFile = outPutDir.resolve("Ornithe Gen" + intermediaryGen.orElseGet(IntermediaryGenerations::stable) + " " + loaderType.getLocalizedName() + " " + gameVersion + ".zip"); Files.deleteIfExists(zipFile); - try (FileSystem fs = FileSystems.newFileSystem(zipFile, Map.of("create", "true"))) { + // This is a god awful workaround, because paths can't be cleanly converted to URIs in j8, and for some reason, you can't pass parameters into newFileSystem with a path argument. + // Thanks Java :) + ZipOutputStream dummyZipOutputStream = new ZipOutputStream(Files.newOutputStream(zipFile.toFile().toPath())); + // I need to put an entry inside, or it creates a 0-byte file, which filesystem doesn't like + dummyZipOutputStream.putNextEntry(new ZipEntry("mmc-pack.json")); + dummyZipOutputStream.write("if you see this, this didn't work".getBytes(StandardCharsets.UTF_8)); + dummyZipOutputStream.closeEntry(); + dummyZipOutputStream.close(); + // End god awful workaround + + // And now we load that dummy zip as a filesystem and actually make it real. + try (FileSystem fs = FileSystems.newFileSystem(zipFile, (ClassLoader) null)) { Files.copy(MmcPackCreator.class.getResourceAsStream(examplePackDir + "/" + iconPath), fs.getPath(iconPath)); - Files.writeString(fs.getPath(instanceCfgPath), transformedInstanceCfg); + Files.write(fs.getPath(instanceCfgPath), transformedInstanceCfg.getBytes(StandardCharsets.UTF_8)); Files.createDirectory(fs.getPath("patches")); - Files.writeString(fs.getPath(intermediaryJsonPath), transformedIntermediaryJson); - Files.writeString(fs.getPath(minecraftPatchPath), transformedMinecraftJson); + Files.write(fs.getPath(intermediaryJsonPath), transformedIntermediaryJson.getBytes(StandardCharsets.UTF_8)); + Files.write(fs.getPath(minecraftPatchPath), transformedMinecraftJson.getBytes(StandardCharsets.UTF_8)); String packJsonWithLibraries = addLibraryUpgrades(fs.getPath("/"), gameVersion, loaderType, loaderVersion, intermediaryGen, intermediary, transformedPackJson); - Files.writeString(fs.getPath(packJsonPath), packJsonWithLibraries); + Files.write(fs.getPath(packJsonPath), packJsonWithLibraries.getBytes(StandardCharsets.UTF_8)); } if (copyProfilePath) { @@ -250,7 +268,7 @@ private static String readResource(String dir, String path) throws IOException { for (int length; (length = resource.read(buffer)) != -1; ) { os.write(buffer, 0, length); } - return os.toString(StandardCharsets.UTF_8); + return os.toString(StandardCharsets.UTF_8.name()); } static { diff --git a/src/main/java/org/quiltmc/installer/OrnitheMeta.java b/src/main/java/org/quiltmc/installer/OrnitheMeta.java index 298d110..5054adc 100644 --- a/src/main/java/org/quiltmc/installer/OrnitheMeta.java +++ b/src/main/java/org/quiltmc/installer/OrnitheMeta.java @@ -53,19 +53,20 @@ public static Endpoint intermediaryGenerationsEndpoint() { continue; } switch (reader.nextName()) { - case "latestIntermediaryGeneration" -> { + case "latestIntermediaryGeneration": if (reader.peek() != JsonToken.NUMBER) { throw new ParseException("Version must be a number", reader); } gens[0] = reader.nextInt(); - } - case "stableIntermediaryGeneration" -> { + break; + case "stableIntermediaryGeneration": if (reader.peek() != JsonToken.NUMBER) { throw new ParseException("maven must be a number", reader); } gens[1] = reader.nextInt(); - } - default -> reader.skipValue(); + break; + default: + reader.skipValue(); } } @@ -125,19 +126,20 @@ public static final Endpoint> intermediaryVersionsEndpoint(Op continue; } switch (reader.nextName()) { - case "version" -> { + case "version": if (reader.peek() != JsonToken.STRING) { throw new ParseException("Version must be a string", reader); } version = reader.nextString(); - } - case "maven" -> { + break; + case "maven": if (reader.peek() != JsonToken.STRING) { throw new ParseException("maven must be a string", reader); } maven = reader.nextString(); - } - case "stable" -> reader.nextBoolean(); // TODO + break; + case "stable": + reader.nextBoolean(); // TODO } } @@ -161,7 +163,7 @@ public static final Endpoint> intermediaryVersionsEndpoint(Op } public static String launchJsonEndpointPath(GameSide side, LoaderType loaderType, String loaderVersion, OptionalInt intermediaryGen, Intermediary intermediary) { - return "/v3/versions" + (intermediaryGen.isEmpty() ? "" : ("/gen" + intermediaryGen.getAsInt())) + String.format(side.launchJsonEndpoint(), loaderType.getName(), intermediary.getVersion(), loaderVersion); + return "/v3/versions" + (!intermediaryGen.isPresent() ? "" : ("/gen" + intermediaryGen.getAsInt())) + String.format(side.launchJsonEndpoint(), loaderType.getName(), intermediary.getVersion(), loaderVersion); } @SuppressWarnings("unchecked") @@ -275,7 +277,7 @@ public static final class Endpoint { private final ThrowingFunction deserializer; Endpoint(OptionalInt intermediaryGen, String endpointPath, ThrowingFunction deserializer) { - this((intermediaryGen.isEmpty() ? "" : ("/gen" + intermediaryGen.getAsInt())) + endpointPath, deserializer); + this((!intermediaryGen.isPresent() ? "" : ("/gen" + intermediaryGen.getAsInt())) + endpointPath, deserializer); } Endpoint(String endpointPath, ThrowingFunction deserializer) { diff --git a/src/main/java/org/quiltmc/installer/VersionManifest.java b/src/main/java/org/quiltmc/installer/VersionManifest.java index 8b845eb..730a4cc 100644 --- a/src/main/java/org/quiltmc/installer/VersionManifest.java +++ b/src/main/java/org/quiltmc/installer/VersionManifest.java @@ -46,7 +46,7 @@ public final class VersionManifest implements Collection create(OptionalInt intermediaryGen) { return CompletableFuture.supplyAsync(() -> { try { - URL url = new URL(intermediaryGen.isEmpty() + URL url = new URL(!intermediaryGen.isPresent() ? LAUNCHER_META_URL : String.format(LAUNCHER_META_BY_GEN_URL, intermediaryGen.getAsInt())); URLConnection connection = Connections.openConnection(url);