refactor providers to not use optionals
All checks were successful
Publish to snapshot maven / build (push) Successful in 19s

This commit is contained in:
moehreag 2024-08-28 12:37:37 +02:00
parent d68f4abea0
commit f74fbc5248
6 changed files with 71 additions and 75 deletions

View file

@ -8,7 +8,7 @@ plugins {
} }
group = "dev.frogmc" group = "dev.frogmc"
version = "0.0.1-alpha.13" version = "0.0.1-alpha.14"
repositories { repositories {
mavenCentral() mavenCentral()

View file

@ -1,9 +1,14 @@
package dev.frogmc.thyroxine; package dev.frogmc.thyroxine;
import java.util.Objects;
import com.electronwill.nightconfig.json.JsonParser; import com.electronwill.nightconfig.json.JsonParser;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
public final class Constants { public final class Constants {
public static final String USER_AGENT = "FrogMC Thyroxine/" +
Objects.requireNonNullElse(Constants.class.getPackage().getImplementationVersion(), "development") +
" <frogmc.dev>";
public static final String VERSION_MANIFEST = "https://piston-meta.mojang.com/mc/game/version_manifest_v2.json"; public static final String VERSION_MANIFEST = "https://piston-meta.mojang.com/mc/game/version_manifest_v2.json";
public static final JsonParser JSON_PARSER = new JsonParser(); public static final JsonParser JSON_PARSER = new JsonParser();
public static final int ASM_VERSION = Opcodes.ASM9; public static final int ASM_VERSION = Opcodes.ASM9;

View file

@ -1,13 +1,11 @@
package dev.frogmc.thyroxine; package dev.frogmc.thyroxine;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.http.HttpClient;
import java.nio.charset.StandardCharsets; import java.net.http.HttpRequest;
import java.util.HashMap; import java.net.http.HttpResponse;
import java.util.Map; import java.nio.file.Path;
import java.util.Optional;
import com.electronwill.nightconfig.core.UnmodifiableConfig; import com.electronwill.nightconfig.core.UnmodifiableConfig;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
@ -17,21 +15,29 @@ import static dev.frogmc.thyroxine.Constants.JSON_PARSER;
@UtilityClass @UtilityClass
public class HttpHelper { public class HttpHelper {
private static final Map<String, String> requestCache = new HashMap<>(); public static UnmodifiableConfig getJson(String url) throws IOException {
return JSON_PARSER.parse(getString(url)).unmodifiable();
public static Optional<UnmodifiableConfig> getJson(String url) {
return getString(url).map(s -> JSON_PARSER.parse(s).unmodifiable());
} }
public static Optional<String> getString(String url) { public static String getString(String url) throws IOException {
return Optional.ofNullable(requestCache.computeIfAbsent(url, s -> { return request(url, HttpResponse.BodyHandlers.ofString()).body();
try (InputStream in = URI.create(url).parseServerAuthority().toURL().openStream()) { }
return new String(in.readAllBytes(), StandardCharsets.UTF_8);
} catch (IOException | URISyntaxException e) { public static void download(String url, Path file) throws IOException {
e.printStackTrace(); request(url, HttpResponse.BodyHandlers.ofFile(file));
// TODO }
}
return null; private static <T> HttpResponse<T> request(String url, HttpResponse.BodyHandler<T> handler) throws IOException {
})); try (HttpClient client = HttpClient.newHttpClient()) {
HttpRequest request = HttpRequest.newBuilder()
.header("User-Agent", Constants.USER_AGENT)
.header("Accept", "application/json")
.GET()
.uri(URI.create(url))
.build();
return client.send(request, handler);
} catch (InterruptedException e) {
throw new IOException(e);
}
} }
} }

View file

@ -33,7 +33,7 @@ public class Thyroxine {
public static void run(String minecraftVersion, Path inputJar, Path outputJar, boolean skipMetaInf, boolean renameParameters) throws IOException, InterruptedException { public static void run(String minecraftVersion, Path inputJar, Path outputJar, boolean skipMetaInf, boolean renameParameters) throws IOException, InterruptedException {
Path out = outputJar.toAbsolutePath(); Path out = outputJar.toAbsolutePath();
MappingBundle data = MojmapProvider.get(minecraftVersion, MappingBundle data = MojmapProvider.get(minecraftVersion,
out.resolveSibling("client-" + minecraftVersion + ".txt")).orElseThrow().reverse(); out.resolveSibling("client-" + minecraftVersion + ".txt")).reverse();
MappingBundle parchment = null; MappingBundle parchment = null;
if (renameParameters) { if (renameParameters) {

View file

@ -1,66 +1,53 @@
package dev.frogmc.thyroxine.provider; package dev.frogmc.thyroxine.provider;
import com.electronwill.nightconfig.core.UnmodifiableConfig;
import dev.frogmc.thyroxine.Constants;
import dev.frogmc.thyroxine.HttpHelper;
import dev.frogmc.thyroxine.api.data.MappingBundle;
import dev.frogmc.thyroxine.parser.ProguardParser;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import com.electronwill.nightconfig.core.UnmodifiableConfig;
import dev.frogmc.thyroxine.Constants;
import dev.frogmc.thyroxine.HttpHelper;
import dev.frogmc.thyroxine.api.data.MappingBundle;
import dev.frogmc.thyroxine.parser.ProguardParser;
public class MojmapProvider { public class MojmapProvider {
public static Optional<MappingBundle> get(String gameVersion, Path cacheFile) { public static MappingBundle get(String gameVersion, Path cacheFile) throws IOException {
return getMappings(gameVersion, cacheFile).map(ProguardParser::read).map(MappingBundle::new); return new MappingBundle(ProguardParser.read(getMappings(gameVersion, cacheFile)));
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static Optional<String> getMappings(String gameVersion, Path cacheFile) { private static String getMappings(String gameVersion, Path cacheFile) throws IOException {
if (Files.exists(cacheFile)){ if (Files.exists(cacheFile)) {
try { return Files.readString(cacheFile, StandardCharsets.UTF_8);
return Optional.of(Files.readString(cacheFile, StandardCharsets.UTF_8)); }
} catch (IOException e) { UnmodifiableConfig manifest = HttpHelper.getJson(Constants.VERSION_MANIFEST);
// TODO String versionName;
e.printStackTrace(); if (gameVersion.startsWith("latest-")) {
} versionName = (String) ((Map<?, ?>) manifest.get("latest")).get(gameVersion.split("-")[1]);
} else {
versionName = gameVersion;
} }
return HttpHelper.getJson(Constants.VERSION_MANIFEST).flatMap(manifest -> {
String versionName;
if (gameVersion.startsWith("latest-")) {
versionName = (String) ((Map<?, ?>) manifest.get("latest")).get(gameVersion.split("-")[1]);
} else {
versionName = gameVersion;
}
System.out.println("Loading version: " + versionName); System.out.println("Loading version: " + versionName);
for (UnmodifiableConfig version : (List<UnmodifiableConfig>) manifest.get("versions")) { for (UnmodifiableConfig version : (List<UnmodifiableConfig>) manifest.get("versions")) {
if (version.get("id").equals(versionName)) { if (version.get("id").equals(versionName)) {
UnmodifiableConfig versionManifest = HttpHelper.getJson(version.get("url")).orElseThrow(); UnmodifiableConfig versionManifest = HttpHelper.getJson(version.get("url"));
String mappingsUrl = ((UnmodifiableConfig) ((UnmodifiableConfig) versionManifest String mappingsUrl = ((UnmodifiableConfig) ((UnmodifiableConfig) versionManifest
.get("downloads")).get("client_mappings")).get("url"); .get("downloads")).get("client_mappings")).get("url");
return HttpHelper.getString(mappingsUrl).map(s -> { String s = HttpHelper.getString(mappingsUrl);
try { Files.createDirectories(cacheFile.getParent());
Files.createDirectories(cacheFile.getParent()); Files.writeString(cacheFile, s);
Files.writeString(cacheFile, s); return s;
} catch (IOException e) {
// TODO
e.printStackTrace();
}
return s;
});
}
} }
return Optional.empty(); }
}); throw new IllegalArgumentException("Could not find mojmap for the specified version: " + gameVersion + "!");
} }
} }

View file

@ -2,12 +2,9 @@ package dev.frogmc.thyroxine.provider;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI; import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem; import java.nio.file.FileSystem;
import java.nio.file.FileSystems; import java.nio.file.FileSystems;
import java.nio.file.Files; import java.nio.file.Files;
@ -18,6 +15,7 @@ import java.util.*;
import com.electronwill.nightconfig.core.UnmodifiableConfig; import com.electronwill.nightconfig.core.UnmodifiableConfig;
import dev.frogmc.thyroxine.Constants; import dev.frogmc.thyroxine.Constants;
import dev.frogmc.thyroxine.HttpHelper;
import dev.frogmc.thyroxine.api.data.DocumentationData; import dev.frogmc.thyroxine.api.data.DocumentationData;
import dev.frogmc.thyroxine.api.data.MappingBundle; import dev.frogmc.thyroxine.api.data.MappingBundle;
import dev.frogmc.thyroxine.api.data.MappingData; import dev.frogmc.thyroxine.api.data.MappingData;
@ -36,9 +34,9 @@ public class ParchmentProvider {
private static String findParchmentVersion(String gameVersion) throws IOException { private static String findParchmentVersion(String gameVersion) throws IOException {
String url = getParchmentUrl(gameVersion) + "/maven-metadata.xml"; String url = getParchmentUrl(gameVersion) + "/maven-metadata.xml";
try (InputStream try (InputStream
stream = URI.create(url).toURL().openStream()) { stream = URI.create(url).toURL().openStream()) {
Document document = DocumentBuilderFactory.newInstance() Document document = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().parse(stream); .newDocumentBuilder().parse(stream);
return document.getElementsByTagName("release").item(0).getTextContent(); return document.getElementsByTagName("release").item(0).getTextContent();
} catch (IOException | SAXException | ParserConfigurationException e) { } catch (IOException | SAXException | ParserConfigurationException e) {
throw new IOException(e); throw new IOException(e);
@ -61,12 +59,12 @@ public class ParchmentProvider {
var url = "%s/%s/parchment-%s-%s.zip".formatted(getParchmentUrl(gameVersion), parchmentVer, gameVersion, parchmentVer); var url = "%s/%s/parchment-%s-%s.zip".formatted(getParchmentUrl(gameVersion), parchmentVer, gameVersion, parchmentVer);
if (forceDownload || Files.notExists(cachePath)) { if (forceDownload || Files.notExists(cachePath)) {
Files.copy(URI.create(url).toURL().openStream(), cachePath); HttpHelper.download(url, cachePath);
} }
{ {
try (InputStream input = URI.create(url+".sha512").toURL().openStream()) { try {
var hash = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)).readLine(); var hash = HttpHelper.getString(url + ".sha512").split("\n", 2)[0];
MessageDigest digest = MessageDigest.getInstance("SHA-512"); MessageDigest digest = MessageDigest.getInstance("SHA-512");
byte[] out = digest.digest(Files.readAllBytes(cachePath)); byte[] out = digest.digest(Files.readAllBytes(cachePath));
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@ -75,10 +73,10 @@ public class ParchmentProvider {
} }
String local = sb.toString(); String local = sb.toString();
if (!hash.equals(local)) { if (!hash.equals(local)) {
System.out.println("Hashes do not match for "+cachePath+": "+local+" != "+hash+"; redownloading!"); System.out.println("Hashes do not match for " + cachePath + ": " + local + " != " + hash + "; redownloading!");
return getParchment(gameVersion, parchmentVer, cacheDir, true); return getParchment(gameVersion, parchmentVer, cacheDir, true);
} }
} catch (NoSuchAlgorithmException e){ } catch (NoSuchAlgorithmException e) {
throw new IOException(e); throw new IOException(e);
} }
} }
@ -92,7 +90,7 @@ public class ParchmentProvider {
List<DocumentationData.Package> packages = new ArrayList<>(); List<DocumentationData.Package> packages = new ArrayList<>();
packagesList.forEach(config -> packagesList.forEach(config ->
packages.add(new DocumentationData.Package(config.get("name"), new ArrayList<>(Objects.requireNonNullElse(c.get("javadoc"), packages.add(new DocumentationData.Package(config.get("name"), new ArrayList<>(Objects.requireNonNullElse(c.get("javadoc"),
Collections.emptyList()))))); Collections.emptyList())))));
List<DocumentationData.Class> classes = new ArrayList<>(); List<DocumentationData.Class> classes = new ArrayList<>();
List<UnmodifiableConfig> classesList = Objects.requireNonNullElse(c.get("classes"), Collections.emptyList()); List<UnmodifiableConfig> classesList = Objects.requireNonNullElse(c.get("classes"), Collections.emptyList());