Refactor to use manifold and records for models
This commit is contained in:
parent
3370495207
commit
18810b255b
|
@ -12,8 +12,10 @@ allprojects {
|
|||
val lwjglVersion by extra("3.3.1")
|
||||
val imguiVersion by extra("1.86.4")
|
||||
val jfCommonsVersion by extra("1.0-SNAPSHOT")
|
||||
val gsonCompileVersion by extra("1.0-SNAPSHOT")
|
||||
val gsonCompileVersion by extra("1.1-SNAPSHOT")
|
||||
val manifoldVersion by extra("2022.1.25")
|
||||
val jlhttpVersion by extra("2.6")
|
||||
|
||||
val flavorProp: String by extra(prop("flavor", "custom"))
|
||||
if (!setOf("custom", "maven", "fat", "windows", "linux", "macos").contains(flavorProp)) throw IllegalStateException("Unsupported flavor: $flavorProp")
|
||||
val flavor: String by extra(if (flavorProp != "custom") flavorProp else OS.TYPE.codename)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
plugins {
|
||||
id("inceptum.java-conventions")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
val manifoldVersion: String by rootProject.extra
|
||||
|
||||
implementation("systems.manifold:manifold-props-rt:$manifoldVersion")
|
||||
|
||||
testAnnotationProcessor(annotationProcessor("systems.manifold:manifold-ext:$manifoldVersion")!!)
|
||||
testAnnotationProcessor(annotationProcessor("systems.manifold:manifold-props:$manifoldVersion")!!)
|
||||
}
|
||||
|
||||
if (sourceSets.main.get().allJava.files.any {it.name == "module-info.java"}) {
|
||||
tasks.withType<JavaCompile> {
|
||||
options.compilerArgs.addAll(arrayOf("-Xplugin:Manifold no-bootstrap", "--module-path", classpath.asPath))
|
||||
}
|
||||
} else {
|
||||
tasks.withType<JavaCompile> {
|
||||
options.compilerArgs.addAll(arrayOf("-Xplugin:Manifold no-bootstrap"))
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ plugins {
|
|||
id("inceptum.library-conventions")
|
||||
id("jf.codegen")
|
||||
id("inceptum.gson-compile")
|
||||
id("inceptum.manifold")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
@ -18,6 +19,7 @@ sourceSets {
|
|||
main {
|
||||
generate(project) {
|
||||
`class`("io.gitlab.jfronny.inceptum.common", "BuildMetadata") {
|
||||
modifiers(Modifier.PUBLIC)
|
||||
val modifiers = arrayOf(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
||||
|
||||
field("VERSION", versionS, *modifiers)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package extensions.java.lang.Iterable;
|
||||
|
||||
import manifold.ext.rt.api.Extension;
|
||||
import manifold.ext.rt.api.Structural;
|
||||
|
||||
@Extension
|
||||
@Structural
|
||||
public class StructuralIterable {
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package extensions.java.util.Map;
|
||||
|
||||
import manifold.ext.rt.api.Extension;
|
||||
import manifold.ext.rt.api.This;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Extension
|
||||
public abstract class MapExt<K, V> implements Iterable<Map.Entry<K, V>> {
|
||||
public static <K, V> Iterator<Map.Entry<K,V>> iterator(@This Map<K, V> thiz) {
|
||||
return thiz.entrySet().iterator();
|
||||
}
|
||||
|
||||
public static <K, V> V set(@This Map<K, V> thiz, K key, V value) {
|
||||
return thiz.put(key, value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package extensions.java.util.stream.BaseStream;
|
||||
|
||||
import manifold.ext.rt.api.Extension;
|
||||
|
||||
@Extension
|
||||
public abstract class BaseStreamExt<T> implements Iterable<T> {
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package extensions.java.util.stream.Stream;
|
||||
|
||||
import manifold.ext.rt.api.Extension;
|
||||
import manifold.ext.rt.api.This;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Extension
|
||||
public abstract class StreamExt<T> {
|
||||
public static <T> Set<T> toSet(@This Stream<T> thiz) {
|
||||
return thiz.collect(LinkedHashSet::new, Set::add, Set::addAll);
|
||||
}
|
||||
|
||||
public static <T, K, V> Map<K, V> toMap(@This Stream<T> thiz, Function<? super T, K> keyMapper, Function<? super T, V> valueMapper) {
|
||||
return thiz.collect(Collectors.toMap(keyMapper, valueMapper));
|
||||
}
|
||||
|
||||
public static <T, K> Map<K, T> toMap(@This Stream<T> thiz, Function<? super T, K> keyMapper) {
|
||||
return thiz.toMap(keyMapper, Function.identity());
|
||||
}
|
||||
|
||||
public static <T, V> Map<V, List<T>> groupingBy(@This Stream<T> thiz, Function<? super T, V> valueMapper) {
|
||||
return thiz.collect(Collectors.groupingBy(valueMapper));
|
||||
}
|
||||
|
||||
public static String join(@This Stream<String> thiz) {
|
||||
return thiz.collect(Collectors.joining());
|
||||
}
|
||||
|
||||
public static String join(@This Stream<String> thiz, String delimiter) {
|
||||
return thiz.collect(Collectors.joining(delimiter));
|
||||
}
|
||||
|
||||
public static String join(@This Stream<String> thiz, char delimiter) {
|
||||
return thiz.join("" + delimiter);
|
||||
}
|
||||
|
||||
public static <T> Stream<T> concat(@This Stream<T> thiz, Stream<T> other) {
|
||||
return Stream.concat(thiz, other);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package extensions.org.w3c.dom.Node;
|
||||
|
||||
import manifold.ext.rt.api.Extension;
|
||||
import manifold.ext.rt.api.This;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
@Extension
|
||||
public class NodeExt {
|
||||
public static boolean isWhitespace(@This Node thiz) {
|
||||
if (thiz.nodeType == Node.TEXT_NODE && thiz.textContent.isBlank()) return true;
|
||||
if (thiz.nodeType == Node.COMMENT_NODE) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package extensions.org.w3c.dom.NodeList;
|
||||
|
||||
import manifold.ext.rt.api.*;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Extension
|
||||
public abstract class NodeListExt implements Iterable<Node> {
|
||||
public static Iterator<Node> iterator(@This NodeList thiz) {
|
||||
return new Iterator<>() {
|
||||
private int index = 0;
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
while (index < thiz.length && thiz[index].isWhitespace()) {
|
||||
index++;
|
||||
}
|
||||
return index < thiz.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node next() {
|
||||
if (!hasNext()) throw new NoSuchElementException();
|
||||
return thiz[index++];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Node get(@This NodeList thiz, int index) {
|
||||
return thiz.item(index);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package io.gitlab.jfronny.inceptum.common;
|
||||
|
||||
import io.gitlab.jfronny.gson.stream.JsonReader;
|
||||
import io.gitlab.jfronny.gson.stream.JsonWriter;
|
||||
|
||||
public class GsonPreset {
|
||||
public static class Config {
|
||||
public static void configure(JsonReader reader) {
|
||||
reader.isSerializeSpecialFloatingPointValues = true;
|
||||
reader.isLenient = true;
|
||||
}
|
||||
|
||||
public static void configure(JsonWriter writer) {
|
||||
writer.serializeNulls = true;
|
||||
writer.isSerializeSpecialFloatingPointValues = true;
|
||||
writer.isLenient = true;
|
||||
writer.indent = " ";
|
||||
writer.omitQuotes = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Api {
|
||||
public static void configure(JsonReader reader) {
|
||||
reader.isSerializeSpecialFloatingPointValues = true;
|
||||
reader.isLenient = true;
|
||||
}
|
||||
|
||||
public static void configure(JsonWriter writer) {
|
||||
writer.serializeNulls = false;
|
||||
writer.isSerializeSpecialFloatingPointValues = true;
|
||||
writer.isLenient = false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,8 +18,8 @@ public class InceptumConfig {
|
|||
public static String authorName = "Inceptum";
|
||||
|
||||
public static void load() throws IOException {
|
||||
if (!Files.exists(MetaHolder.CONFIG_PATH.getParent()))
|
||||
Files.createDirectories(MetaHolder.CONFIG_PATH.getParent());
|
||||
if (!Files.exists(MetaHolder.CONFIG_PATH.parent))
|
||||
Files.createDirectories(MetaHolder.CONFIG_PATH.parent);
|
||||
if (!Files.exists(MetaHolder.CONFIG_PATH)) {
|
||||
Path gLaunch2 = MetaHolder.BASE_PATH.resolve("glaunch2.json");
|
||||
Path json = MetaHolder.BASE_PATH.resolve("inceptum.json");
|
||||
|
@ -32,7 +32,7 @@ public class InceptumConfig {
|
|||
}
|
||||
}
|
||||
try (JsonReader jr = new JsonReader(Files.newBufferedReader(MetaHolder.CONFIG_PATH))) {
|
||||
jr.setLenient(true);
|
||||
GsonPreset.Config.configure(jr);
|
||||
jr.beginObject();
|
||||
while (jr.peek() != JsonToken.END_OBJECT) {
|
||||
String name = null;
|
||||
|
@ -70,9 +70,7 @@ public class InceptumConfig {
|
|||
|
||||
public static void saveConfig() {
|
||||
try (JsonWriter jw = new JsonWriter(Files.newBufferedWriter(MetaHolder.CONFIG_PATH))) {
|
||||
jw.setLenient(true);
|
||||
jw.setOmitQuotes(true);
|
||||
jw.setIndent(" ");
|
||||
GsonPreset.Config.configure(jw);
|
||||
jw.beginObject()
|
||||
.comment("Whether to show snapshots in the version selector for new instances")
|
||||
.name("snapshots").value(snapshots)
|
||||
|
|
|
@ -9,11 +9,11 @@ import java.io.IOException;
|
|||
public class InceptumEnvironmentInitializer {
|
||||
public static void initialize() throws IOException {
|
||||
Logger.registerFactory(InceptumEnvironmentInitializer::defaultFactory);
|
||||
HttpUtils.setUserAgent("jfmods/inceptum/" + BuildMetadata.VERSION);
|
||||
HttpUtils.userAgent = "jfmods/inceptum/" + BuildMetadata.VERSION;
|
||||
InceptumConfig.load();
|
||||
}
|
||||
|
||||
public static Logger defaultFactory(String name) {
|
||||
return new StdoutLogger(name, true, true, true);
|
||||
return StdoutLogger.fancy(name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ public class MetaHolder {
|
|||
case WINDOWS -> getPath(System.getenv("APPDATA"));
|
||||
case MAC_OS -> getPath(System.getProperty("user.home")).resolve("Library").resolve("Application Support");
|
||||
case LINUX -> {
|
||||
String s = System.getenv().get("XDG_CONFIG_HOME");
|
||||
String s = System.getenv("XDG_CONFIG_HOME");
|
||||
if (s == null)
|
||||
yield getPath(System.getProperty("user.home")).resolve(".config");
|
||||
else
|
||||
|
|
|
@ -65,11 +65,11 @@ public class Net {
|
|||
if (url.startsWith("/")) res.append(url);
|
||||
else res.append("/").append(url);
|
||||
int i = 0;
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
for (Map.Entry<String, String> entry : params) {
|
||||
res.append(i++ == 0 ? '?' : '&')
|
||||
.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8))
|
||||
.append(URLEncoder.encode(entry.key, StandardCharsets.UTF_8))
|
||||
.append('=')
|
||||
.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
|
||||
.append(URLEncoder.encode(entry.value, StandardCharsets.UTF_8));
|
||||
}
|
||||
return res.toString();
|
||||
}
|
||||
|
@ -83,12 +83,12 @@ public class Net {
|
|||
}
|
||||
|
||||
public static void downloadFile(String url, Path path) throws IOException, URISyntaxException {
|
||||
if (!Files.exists(path.getParent())) Files.createDirectories(path.getParent());
|
||||
if (!Files.exists(path.parent)) Files.createDirectories(path.parent);
|
||||
Files.write(path, downloadData(url));
|
||||
}
|
||||
|
||||
public static void downloadFile(String url, String sha1, Path path) throws IOException, URISyntaxException {
|
||||
if (!Files.exists(path.getParent())) Files.createDirectories(path.getParent());
|
||||
if (!Files.exists(path.parent)) Files.createDirectories(path.parent);
|
||||
Files.write(path, downloadData(url, sha1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,10 +30,10 @@ public class ObjectCache {
|
|||
public <T, TEx extends Throwable> T get(String key, ThrowingSupplier<String, ? extends TEx> download, ThrowingFunction<String, T, ? extends TEx> builder) throws IOException, TEx {
|
||||
if (!container.containsKey(key)) {
|
||||
Path cd = cacheDir.resolve(key);
|
||||
if (Files.exists(cd)) container.put(key, builder.apply(Files.readString(cd)));
|
||||
else container.put(key, builder.apply(download.get()));
|
||||
if (Files.exists(cd)) container[key] = builder.apply(Files.readString(cd));
|
||||
else container[key] = builder.apply(download.get());
|
||||
}
|
||||
//noinspection unchecked
|
||||
return (T) container.get(key);
|
||||
return (T) container[key];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
package io.gitlab.jfronny.inceptum.common;
|
||||
|
||||
public class OutdatedException extends RuntimeException {
|
||||
public OutdatedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -5,11 +5,14 @@ package io.gitlab.jfronny.inceptum.common;
|
|||
*/
|
||||
public class R {
|
||||
public static void nop() {
|
||||
// No-Op
|
||||
}
|
||||
|
||||
public static void nop(Object a1) {
|
||||
// No-Op
|
||||
}
|
||||
|
||||
public static void nop(Object a1, Object a2) {
|
||||
// No-Op
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Updater {
|
||||
|
@ -33,35 +32,36 @@ public class Updater {
|
|||
public static void update(UpdateMetadata source, boolean relaunch) throws IOException, URISyntaxException {
|
||||
Utils.LOGGER.info("Downloading version " + source.version);
|
||||
|
||||
WrapperConfig config = new WrapperConfig();
|
||||
config.natives = new HashMap<>();
|
||||
config.libraries = new LinkedHashSet<>();
|
||||
config.repositories = new LinkedHashSet<>(source.repositories);
|
||||
source.natives.forEach((k, v) -> config.natives.put(k, new LinkedHashSet<>(v)));
|
||||
WrapperConfig config = new WrapperConfig(
|
||||
new LinkedHashSet<>(),
|
||||
new LinkedHashSet<>(source.repositories),
|
||||
new HashMap<>()
|
||||
);
|
||||
source.natives.forEach((k, v) -> config.natives[k] = new LinkedHashSet<>(v));
|
||||
|
||||
DependencyNode node = downloadLibrary(source.repositories, "io.gitlab.jfronny.inceptum:launcher-dist:" + source.version, config.libraries);
|
||||
Utils.LOGGER.info("Downloaded Dependencies:\n" + node);
|
||||
|
||||
List<String> currentLibraries = new LinkedList<>(config.libraries);
|
||||
if (source.natives.containsKey(Utils.getCurrentFlavor())) {
|
||||
if (source.natives.containsKey(Utils.currentFlavor)) {
|
||||
Set<String> natives = new LinkedHashSet<>();
|
||||
for (String lib : source.natives.get(Utils.getCurrentFlavor())) {
|
||||
for (String lib : source.natives[Utils.currentFlavor]) {
|
||||
downloadLibrary(source.repositories, lib, natives);
|
||||
}
|
||||
currentLibraries.addAll(natives);
|
||||
config.natives.put(Utils.getCurrentFlavor(), natives);
|
||||
config.natives[Utils.currentFlavor] = natives;
|
||||
}
|
||||
|
||||
GC_WrapperConfig.write(MetaHolder.WRAPPER_CONFIG_PATH, config);
|
||||
|
||||
if (relaunch) {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
Runtime.runtime.addShutdownHook(new Thread(() -> {
|
||||
try {
|
||||
new ProcessBuilder(OSUtils.getJvmBinary(),
|
||||
new ProcessBuilder(OSUtils.jvmBinary,
|
||||
"-cp",
|
||||
buildClasspath(currentLibraries.stream())
|
||||
.map(Path::toString)
|
||||
.collect(Collectors.joining("" + File.pathSeparatorChar))
|
||||
.join(File.pathSeparatorChar)
|
||||
).inheritIO().start();
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not relaunch", e);
|
||||
|
@ -71,7 +71,7 @@ public class Updater {
|
|||
}
|
||||
|
||||
public static List<Path> getLaunchClasspath(WrapperConfig wrapperConfig) throws IOException, URISyntaxException {
|
||||
Set<String> natives = wrapperConfig.natives.get(Utils.getCurrentFlavor());
|
||||
Set<String> natives = wrapperConfig.natives[Utils.currentFlavor];
|
||||
if (natives == null) natives = new LinkedHashSet<>();
|
||||
Set<String> libs = wrapperConfig.libraries;
|
||||
if (libs == null) libs = new LinkedHashSet<>();
|
||||
|
@ -79,14 +79,14 @@ public class Updater {
|
|||
boolean configChanged = false;
|
||||
|
||||
for (String lib : libs) {
|
||||
Path p = ArtifactMeta.parse(lib).getLocalPath();
|
||||
Path p = ArtifactMeta.parse(lib).localPath;
|
||||
if (!Files.exists(p)) {
|
||||
configChanged = true;
|
||||
downloadLibrary(wrapperConfig.repositories, lib, libs);
|
||||
}
|
||||
}
|
||||
for (String lib : natives) {
|
||||
Path p = ArtifactMeta.parse(lib).getLocalPath();
|
||||
Path p = ArtifactMeta.parse(lib).localPath;
|
||||
if (!Files.exists(p)) {
|
||||
configChanged = true;
|
||||
downloadLibrary(wrapperConfig.repositories, lib, natives);
|
||||
|
@ -95,7 +95,7 @@ public class Updater {
|
|||
|
||||
if (configChanged) GC_WrapperConfig.write(MetaHolder.WRAPPER_CONFIG_PATH, wrapperConfig);
|
||||
|
||||
return buildClasspath(Stream.concat(libs.stream(), natives.stream())).toList();
|
||||
return buildClasspath(libs.stream().concat(natives.stream())).toList();
|
||||
}
|
||||
|
||||
private static Stream<Path> buildClasspath(Stream<String> libraries) {
|
||||
|
@ -104,7 +104,7 @@ public class Updater {
|
|||
|
||||
private static DependencyNode downloadLibrary(Set<String> repositories, final String artifact, Set<String> libraries) throws IOException, URISyntaxException {
|
||||
List<FileNotFoundException> suppressed = new LinkedList<>();
|
||||
for (String repository : Stream.concat(Stream.of(PROJECT_MAVEN), repositories.stream()).toList()) {
|
||||
for (String repository : Stream.of(PROJECT_MAVEN).concat(repositories.stream())) {
|
||||
ArtifactMeta meta;
|
||||
try {
|
||||
meta = MavenApi.getMetadata(repository, artifact);
|
||||
|
@ -120,7 +120,7 @@ public class Updater {
|
|||
suppressed.add(notFound);
|
||||
continue;
|
||||
} catch (IOException | URISyntaxException | XMLStreamException | SAXException e) {
|
||||
throw new IOException("Could not download artifact " + meta.getMavenNotation() + " from " + repository, e);
|
||||
throw new IOException("Could not download artifact " + meta.mavenNotation + " from " + repository, e);
|
||||
}
|
||||
Set<DependencyNode> dependencies = new LinkedHashSet<>();
|
||||
if (pom.dependencies != null) {
|
||||
|
@ -175,7 +175,7 @@ public class Updater {
|
|||
return switch (channel) {
|
||||
case CI -> ARTIFACTS_URL;
|
||||
case Stable -> STABLE_URL;
|
||||
} + "/Inceptum-" + Utils.getCurrentFlavor() + ".jar";
|
||||
} + "/Inceptum-" + Utils.currentFlavor + ".jar";
|
||||
}
|
||||
|
||||
public static class UpdateCheckException extends Exception {
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
public class Utils {
|
||||
public static final int CACHE_SIZE = 128;
|
||||
public static final Pattern NEW_LINE = Pattern.compile("[\r\n]+");
|
||||
public static final Pattern VALID_FILENAME = Pattern.compile("[a-zA-Z0-9_\\-.][a-zA-Z0-9 _\\-.]*[a-zA-Z0-9_\\-.]");
|
||||
public static final Logger LOGGER = Logger.forName("Inceptum");
|
||||
private static ClassLoader SYSTEM_LOADER = ClassLoader.getSystemClassLoader();
|
||||
|
@ -24,9 +25,9 @@ public class Utils {
|
|||
public static void openWebBrowser(URI uri) {
|
||||
try {
|
||||
if (OSUtils.TYPE == OSUtils.Type.LINUX && OSUtils.executablePathContains("xdg-open")) {
|
||||
Runtime.getRuntime().exec(new String[]{"xdg-open", uri.toString()});
|
||||
} else if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
|
||||
Desktop.getDesktop().browse(uri);
|
||||
Runtime.runtime.exec(new String[]{"xdg-open", uri.toString()});
|
||||
} else if (Desktop.isDesktopSupported && Desktop.desktop.isSupported(Desktop.Action.BROWSE)) {
|
||||
Desktop.desktop.browse(uri);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Utils.LOGGER.error("Error opening web browser!", e);
|
||||
|
@ -36,9 +37,9 @@ public class Utils {
|
|||
public static void openFile(File file) {
|
||||
try {
|
||||
if (OSUtils.TYPE == OSUtils.Type.LINUX && OSUtils.executablePathContains("xdg-open")) {
|
||||
Runtime.getRuntime().exec(new String[]{"xdg-open", file.getAbsoluteFile().toString()});
|
||||
} else if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
|
||||
Desktop.getDesktop().open(file);
|
||||
Runtime.runtime.exec(new String[]{"xdg-open", file.absoluteFile.toString()});
|
||||
} else if (Desktop.isDesktopSupported && Desktop.desktop.isSupported(Desktop.Action.BROWSE)) {
|
||||
Desktop.desktop.open(file);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Utils.LOGGER.error("Error opening web browser!", e);
|
||||
|
@ -67,8 +68,8 @@ public class Utils {
|
|||
return Arrays.stream(segments)
|
||||
.map(s -> s.startsWith(separator) ? s.substring(separator.length()) : s)
|
||||
.map(s -> s.endsWith(separator) ? s.substring(0, s.length() - separator.length()) : s)
|
||||
.filter(s -> !s.isEmpty())
|
||||
.collect(Collectors.joining(separator));
|
||||
.filter(s -> !s.isEmpty)
|
||||
.join(separator);
|
||||
}
|
||||
|
||||
public static String getCurrentFlavor() {
|
||||
|
|
|
@ -29,202 +29,147 @@ public class MavenApi {
|
|||
}
|
||||
|
||||
public static Path downloadLibrary(String repo, ArtifactMeta meta) throws IOException, URISyntaxException {
|
||||
Path res = meta.getLocalPath();
|
||||
Path res = meta.localPath;
|
||||
Net.downloadFile(Utils.join("/", repo, meta.getJarPath(true)), res);
|
||||
return res;
|
||||
}
|
||||
|
||||
public static Pom getPom(String repo, ArtifactMeta meta) throws IOException, SAXException, URISyntaxException, XMLStreamException {
|
||||
try (InputStream is = HttpUtils.get(Utils.join("/", repo, meta.getPomPath())).sendInputStream()) {
|
||||
try (InputStream is = HttpUtils.get(Utils.join("/", repo, meta.pomPath)).sendInputStream()) {
|
||||
Document doc = FACTORY.parse(is);
|
||||
doc.getDocumentElement().normalize();
|
||||
Pom result = new Pom();
|
||||
if (!"project".equals(doc.getDocumentElement().getNodeName())) throw new IOException("Illegal document name");
|
||||
boolean hasModelVersion = false;
|
||||
boolean hasGroupId = false;
|
||||
boolean hasArtifactId = false;
|
||||
boolean hasVersion = false;
|
||||
for (Node node : iterable(doc.getDocumentElement().getChildNodes())) {
|
||||
switch (node.getNodeName()) {
|
||||
case "modelVersion" -> {
|
||||
hasModelVersion = true;
|
||||
result.modelVersion = node.getTextContent();
|
||||
}
|
||||
doc.documentElement.normalize();
|
||||
if (!"project".equals(doc.documentElement.nodeName)) throw new IOException("Illegal document name");
|
||||
String modelVersion = null;
|
||||
String groupId = null;
|
||||
String artifactId = null;
|
||||
String version = null;
|
||||
String packaging = null;
|
||||
List<MavenDependency> dependencies = null;
|
||||
String classifier = null;
|
||||
for (Node node : doc.documentElement.childNodes) {
|
||||
switch (node.nodeName) {
|
||||
case "modelVersion" -> modelVersion = node.textContent;
|
||||
case "parent" -> {
|
||||
// Dirty hack to get slf4j working: simply assume the groupId and version of the parent is also the groupId of this
|
||||
if (!hasGroupId) {
|
||||
for (Node child : iterable(node.getChildNodes())) {
|
||||
switch (child.getNodeName()) {
|
||||
if (groupId == null) {
|
||||
for (Node child : node.childNodes) {
|
||||
switch (child.nodeName) {
|
||||
case "groupId" -> {
|
||||
if (!hasGroupId) {
|
||||
hasGroupId = true;
|
||||
result.groupId = node.getTextContent();
|
||||
if (groupId == null) {
|
||||
groupId = node.textContent;
|
||||
}
|
||||
}
|
||||
case "version" -> {
|
||||
if (!hasVersion) {
|
||||
hasVersion = true;
|
||||
result.version = node.getTextContent();
|
||||
if (version == null) {
|
||||
version = node.textContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case "groupId" -> {
|
||||
hasGroupId = true;
|
||||
result.groupId = node.getTextContent();
|
||||
}
|
||||
case "groupId" -> groupId = node.textContent;
|
||||
case "artifactId" -> {
|
||||
hasArtifactId = true;
|
||||
result.artifactId = node.getTextContent();
|
||||
artifactId = node.textContent;
|
||||
}
|
||||
case "version" -> {
|
||||
hasVersion = true;
|
||||
result.version = node.getTextContent();
|
||||
version = node.textContent;
|
||||
}
|
||||
case "packaging" -> result.packaging = node.getTextContent();
|
||||
case "packaging" -> packaging = node.textContent;
|
||||
case "dependencies" -> {
|
||||
result.dependencies = new LinkedList<>();
|
||||
for (Node dep : iterable(node.getChildNodes())) {
|
||||
dependencies = new LinkedList<>();
|
||||
for (Node dep : node.childNodes) {
|
||||
MavenDependency resolved = parseDependency(dep);
|
||||
if (resolved != null) {
|
||||
result.dependencies.add(resolved);
|
||||
dependencies.add(resolved);
|
||||
}
|
||||
}
|
||||
}
|
||||
case "classifier" -> result.classifier = node.getTextContent();
|
||||
case "classifier" -> classifier = node.textContent;
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
if (!hasModelVersion) throw new IOException("Pom lacks modelVersion");
|
||||
if (!hasGroupId) throw new IOException("Pom lacks groupId");
|
||||
if (!hasArtifactId) throw new IOException("Pom lacks artifactId");
|
||||
if (!hasVersion) throw new IOException("Pom lacks version");
|
||||
return result;
|
||||
if (modelVersion == null) throw new IOException("Pom lacks modelVersion");
|
||||
if (groupId == null) throw new IOException("Pom lacks groupId");
|
||||
if (artifactId == null) throw new IOException("Pom lacks artifactId");
|
||||
if (version == null) throw new IOException("Pom lacks version");
|
||||
return new Pom(modelVersion, groupId, artifactId, version, classifier, null, packaging, dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
private static @Nullable MavenDependency parseDependency(Node doc) throws IOException {
|
||||
MavenDependency result = new MavenDependency();
|
||||
boolean hasGroupId = false;
|
||||
boolean hasArtifactId = false;
|
||||
boolean hasVersion = false;
|
||||
boolean hasScope = false;
|
||||
for (Node node : iterable(doc.getChildNodes())) {
|
||||
switch (node.getNodeName()) {
|
||||
case "groupId" -> {
|
||||
hasGroupId = true;
|
||||
result.groupId = node.getTextContent();
|
||||
}
|
||||
case "artifactId" -> {
|
||||
hasArtifactId = true;
|
||||
result.artifactId = node.getTextContent();
|
||||
}
|
||||
case "version" -> {
|
||||
hasVersion = true;
|
||||
result.version = node.getTextContent();
|
||||
}
|
||||
String groupId = null;
|
||||
String artifactId = null;
|
||||
String version = null;
|
||||
String scope = null;
|
||||
for (Node node : doc.childNodes) {
|
||||
switch (node.nodeName) {
|
||||
case "groupId" -> groupId = node.textContent;
|
||||
case "artifactId" -> artifactId = node.textContent;
|
||||
case "version" -> version = node.textContent;
|
||||
case "scope" -> {
|
||||
hasScope = true;
|
||||
result.scope = node.getTextContent();
|
||||
if (!RUNTIME_SCOPES.contains(result.scope)) return null;
|
||||
scope = node.textContent;
|
||||
if (!RUNTIME_SCOPES.contains(scope)) return null;
|
||||
}
|
||||
case "optional" -> {
|
||||
if (node.getTextContent().equals("true")) return null;
|
||||
if (node.textContent.equals("true")) return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasGroupId) throw new IOException("Pom lacks groupId");
|
||||
if (!hasArtifactId) throw new IOException("Pom lacks artifactId");
|
||||
if (!hasVersion) {
|
||||
if (result.groupId.equals("org.lwjgl")) {
|
||||
if (groupId == null) throw new IOException("Pom lacks groupId");
|
||||
if (artifactId == null) throw new IOException("Pom lacks artifactId");
|
||||
if (version == null) {
|
||||
if (groupId.equals("org.lwjgl")) {
|
||||
// Lwjgl uses a shared bom for versions which I don't want to support
|
||||
// The required modules are explicit dependencies of launcher-imgui anyway
|
||||
return null;
|
||||
}
|
||||
throw new IOException("Dependency " + result.groupId + ":" + result.artifactId + " lacks version");
|
||||
throw new IOException("Dependency " + groupId + ":" + artifactId + " lacks version");
|
||||
}
|
||||
if (!hasScope) throw new IOException("Pom lacks scope");
|
||||
return result;
|
||||
if (scope == null) throw new IOException("Pom lacks scope");
|
||||
return new MavenDependency(groupId, artifactId, version, scope);
|
||||
}
|
||||
|
||||
public static ArtifactMeta getMetadata(String repo, String artifact) throws IOException, SAXException, URISyntaxException {
|
||||
ArtifactMeta sourceMeta = ArtifactMeta.parse(artifact);
|
||||
try (InputStream is = HttpUtils.get(Utils.join("/", repo, sourceMeta.getMetadataPath())).sendInputStream()) {
|
||||
try (InputStream is = HttpUtils.get(Utils.join("/", repo, sourceMeta.metadataPath)).sendInputStream()) {
|
||||
Document doc = FACTORY.parse(is);
|
||||
doc.getDocumentElement().normalize();
|
||||
ArtifactMeta result = new ArtifactMeta();
|
||||
if (!"metadata".equals(doc.getDocumentElement().getNodeName())) throw new IOException("Illegal document name");
|
||||
boolean hasGroupId = false;
|
||||
boolean hasArtifactId = false;
|
||||
boolean hasVersion = false;
|
||||
for (Node node : iterable(doc.getDocumentElement().getChildNodes())) {
|
||||
switch (node.getNodeName()) {
|
||||
case "groupId" -> {
|
||||
hasGroupId = true;
|
||||
result.groupId = node.getTextContent();
|
||||
}
|
||||
case "artifactId" -> {
|
||||
hasArtifactId = true;
|
||||
result.artifactId = node.getTextContent();
|
||||
}
|
||||
case "version" -> {
|
||||
hasVersion = true;
|
||||
result.version = node.getTextContent();
|
||||
}
|
||||
doc.documentElement.normalize();
|
||||
if (!"metadata".equals(doc.documentElement.nodeName)) throw new IOException("Illegal document name");
|
||||
String groupId = null;
|
||||
String artifactId = null;
|
||||
String version = null;
|
||||
String snapshotVersion = null;
|
||||
for (Node node : doc.documentElement.childNodes) {
|
||||
switch (node.nodeName) {
|
||||
case "groupId" -> groupId = node.textContent;
|
||||
case "artifactId" -> artifactId = node.textContent;
|
||||
case "version" -> version = node.textContent;
|
||||
case "versioning" -> {
|
||||
for (Node node1 : iterable(node.getChildNodes())) {
|
||||
if (node1.getNodeName().equals("snapshot")) {
|
||||
for (Node node1 : node.childNodes) {
|
||||
if (node1.nodeName.equals("snapshot")) {
|
||||
String timestamp = null;
|
||||
String buildNumber = null;
|
||||
for (Node node2 : iterable(node1.getChildNodes())) {
|
||||
switch (node2.getNodeName()) {
|
||||
case "timestamp" -> timestamp = node2.getTextContent();
|
||||
case "buildNumber" -> buildNumber = node2.getTextContent();
|
||||
for (Node node2 : node1.childNodes) {
|
||||
switch (node2.nodeName) {
|
||||
case "timestamp" -> timestamp = node2.textContent;
|
||||
case "buildNumber" -> buildNumber = node2.textContent;
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
if (timestamp == null) throw new IOException("Pom snapshots lack timestamp");
|
||||
if (buildNumber == null) throw new IOException("Pom snapshots lack buildNumber");
|
||||
result.snapshotVersion = timestamp + '-' + buildNumber;
|
||||
snapshotVersion = timestamp + '-' + buildNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
if (!hasGroupId) throw new IOException("Pom lacks groupId");
|
||||
if (!hasArtifactId) throw new IOException("Pom lacks artifactId");
|
||||
if (!hasVersion) throw new IOException("Pom lacks version");
|
||||
result.classifier = sourceMeta.classifier;
|
||||
return result;
|
||||
if (groupId == null) throw new IOException("Pom lacks groupId");
|
||||
if (artifactId == null) throw new IOException("Pom lacks artifactId");
|
||||
if (version == null) throw new IOException("Pom lacks version");
|
||||
return new ArtifactMeta(groupId, artifactId, version, sourceMeta.classifier, snapshotVersion);
|
||||
}
|
||||
}
|
||||
|
||||
private static Iterable<Node> iterable(NodeList list) {
|
||||
return () -> new Iterator<>() {
|
||||
int index = 0;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
while (index < list.getLength() && isWhitespace(list.item(index))) {
|
||||
index++;
|
||||
}
|
||||
return index < list.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node next() {
|
||||
if (!hasNext()) throw new NoSuchElementException();
|
||||
return list.item(index++);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static boolean isWhitespace(Node node) {
|
||||
if (node.getNodeType() == Node.TEXT_NODE && node.getTextContent().isBlank()) return true;
|
||||
if (node.getNodeType() == Node.COMMENT_NODE) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
package io.gitlab.jfronny.inceptum.common.model.inceptum;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@GSerializable
|
||||
public class UpdateMetadata {
|
||||
public Integer wrapperVersion;
|
||||
public String version;
|
||||
public Long buildTime;
|
||||
public Boolean isPublic;
|
||||
public Boolean isRelease;
|
||||
public Integer jvm;
|
||||
public Set<String> repositories;
|
||||
public Map<String, Set<String>> natives;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record UpdateMetadata(int wrapperVersion,
|
||||
String version,
|
||||
long buildTime,
|
||||
boolean isPublic,
|
||||
boolean isRelease,
|
||||
int jvm,
|
||||
Set<String> repositories,
|
||||
Map<String, Set<String>> natives) {
|
||||
}
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
package io.gitlab.jfronny.inceptum.common.model.inceptum;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@GSerializable
|
||||
public class WrapperConfig {
|
||||
public Set<String> libraries;
|
||||
public Set<String> repositories;
|
||||
public Map<String, Set<String>> natives;
|
||||
@GSerializable(configure = GsonPreset.Config.class)
|
||||
public record WrapperConfig(Set<String> libraries, Set<String> repositories, Map<String, Set<String>> natives) {
|
||||
}
|
||||
|
|
|
@ -1,32 +1,25 @@
|
|||
package io.gitlab.jfronny.inceptum.common.model.maven;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.common.MetaHolder;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ArtifactMeta {
|
||||
public record ArtifactMeta(String groupId, String artifactId, String version, @Nullable String classifier, @Nullable String snapshotVersion) {
|
||||
public ArtifactMeta(String groupId, String artifactId, String version) {
|
||||
this(groupId, artifactId, version, null, null);
|
||||
}
|
||||
|
||||
public static ArtifactMeta parse(String mavenNotation) {
|
||||
if (Objects.requireNonNull(mavenNotation).isEmpty()) throw new IllegalArgumentException("The notation is empty");
|
||||
String[] lib = mavenNotation.split(":");
|
||||
if (lib.length <= 1) throw new IllegalArgumentException("Not in maven notation");
|
||||
if (lib.length == 2) throw new IllegalArgumentException("Skipping versions is not supported");
|
||||
if (lib.length >= 5) throw new IllegalArgumentException("Unkown elements in maven notation");
|
||||
ArtifactMeta meta = new ArtifactMeta();
|
||||
meta.groupId = lib[0];
|
||||
meta.artifactId = lib[1];
|
||||
meta.version = lib[2];
|
||||
if (lib.length > 3) meta.classifier = lib[3];
|
||||
return meta;
|
||||
return new ArtifactMeta(lib[0], lib[1], lib[2], lib.length > 3 ? lib[3] : null, null);
|
||||
}
|
||||
|
||||
public String groupId;
|
||||
public String artifactId;
|
||||
public String version;
|
||||
|
||||
public String classifier;
|
||||
public String snapshotVersion;
|
||||
|
||||
public String getPomPath() {
|
||||
String path = groupId.replace('.', '/') + '/';
|
||||
path += artifactId + '/';
|
||||
|
|
|
@ -2,28 +2,7 @@ package io.gitlab.jfronny.inceptum.common.model.maven;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
public class DependencyNode {
|
||||
private final String name;
|
||||
private final Set<DependencyNode> dependencies;
|
||||
|
||||
public DependencyNode(String name, Set<DependencyNode> dependencies) {
|
||||
this.name = Objects.requireNonNull(name);
|
||||
this.dependencies = Objects.requireNonNull(dependencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
DependencyNode that = (DependencyNode) o;
|
||||
return name.equals(that.name) && dependencies.equals(that.dependencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, dependencies);
|
||||
}
|
||||
|
||||
public record DependencyNode(String name, Set<DependencyNode> dependencies) {
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.common.model.maven;
|
||||
|
||||
public class MavenDependency {
|
||||
public String groupId;
|
||||
public String artifactId;
|
||||
public String version;
|
||||
public String scope;
|
||||
public record MavenDependency(String groupId, String artifactId, String version, String scope) {
|
||||
}
|
||||
|
|
|
@ -4,13 +4,12 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
public class Pom {
|
||||
public String modelVersion;
|
||||
public String groupId;
|
||||
public String artifactId;
|
||||
public String version;
|
||||
public String classifier;
|
||||
public String snapshotVersion;
|
||||
@Nullable public String packaging;
|
||||
@Nullable public List<MavenDependency> dependencies;
|
||||
public record Pom(String modelVersion,
|
||||
String groupId,
|
||||
String artifactId,
|
||||
String version,
|
||||
String classifier,
|
||||
String snapshotVersion,
|
||||
@Nullable String packaging,
|
||||
@Nullable List<MavenDependency> dependencies) {
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
plugins {
|
||||
id("inceptum.application-conventions")
|
||||
id("inceptum.manifold")
|
||||
}
|
||||
|
||||
application {
|
||||
|
|
|
@ -11,11 +11,7 @@ import java.nio.file.Path;
|
|||
import java.util.List;
|
||||
|
||||
public abstract class BaseInstanceCommand extends Command {
|
||||
public BaseInstanceCommand(String help, String usage, String... aliases) {
|
||||
super(help, mutateUsage(usage), aliases);
|
||||
}
|
||||
|
||||
public BaseInstanceCommand(String help, String usage, List<String> aliases, List<Command> subCommands) {
|
||||
protected BaseInstanceCommand(String help, String usage, List<String> aliases, List<Command> subCommands) {
|
||||
super(help, mutateUsage(usage), aliases, subCommands);
|
||||
}
|
||||
|
||||
|
@ -36,9 +32,9 @@ public abstract class BaseInstanceCommand extends Command {
|
|||
Utils.LOGGER.error("You must specify an instance to commit in");
|
||||
return;
|
||||
}
|
||||
Path instancePath = MetaHolder.INSTANCE_DIR.resolve(args.get(0));
|
||||
Path instancePath = MetaHolder.INSTANCE_DIR.resolve(args[0]);
|
||||
if (!Files.exists(instancePath)) {
|
||||
Utils.LOGGER.error("Invalid instance: \"" + args.get(0) + "\"");
|
||||
Utils.LOGGER.error("Invalid instance: \"" + args[0] + "\"");
|
||||
return;
|
||||
}
|
||||
Instance instance;
|
||||
|
|
|
@ -22,7 +22,7 @@ public class CliMain {
|
|||
public static final Command COMMANDS_ROOT = new Command("Root command", "<command>", List.of(), KNOWN_COMMANDS) {
|
||||
@Override
|
||||
protected void invoke(CommandArgs args) {
|
||||
throw new RuntimeException("Could not find command: " + args.get(0));
|
||||
throw new RuntimeException("Could not find command: " + args[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,7 +24,7 @@ public abstract class Command {
|
|||
}
|
||||
|
||||
public String getName() {
|
||||
return aliases.get(0);
|
||||
return aliases[0];
|
||||
}
|
||||
|
||||
public boolean enableLog() {
|
||||
|
@ -36,22 +36,22 @@ public abstract class Command {
|
|||
public CommandResolution resolve(CommandArgs args) {
|
||||
if (args.length != 0) {
|
||||
for (Command command : subCommands) {
|
||||
if (command.isAlias(args.get(0))) {
|
||||
if (command.isAlias(args[0])) {
|
||||
CommandResolution resolution = command.resolve(args.subArgs());
|
||||
if (!aliases.isEmpty()) resolution.resolvePath().add(0, aliases.get(0));
|
||||
if (!aliases.isEmpty) resolution.resolvePath.add(0, aliases[0]);
|
||||
return resolution;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new CommandResolution(this, args, aliases.isEmpty()
|
||||
return new CommandResolution(this, args, aliases.isEmpty
|
||||
? new ArrayList<>()
|
||||
: new ArrayList<>(List.of(aliases.get(0))));
|
||||
: new ArrayList<>(List.of(aliases[0])));
|
||||
}
|
||||
|
||||
public void buildHelp(HelpBuilder builder) {
|
||||
builder.writeCommand(aliases, help, usage);
|
||||
for (Command command : subCommands) {
|
||||
command.buildHelp(aliases.isEmpty() ? builder : builder.beginSubcommand(aliases.get(0)));
|
||||
command.buildHelp(aliases.isEmpty ? builder : builder.beginSubcommand(aliases[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,11 @@ public class CommandArgs implements Iterable<String> {
|
|||
}
|
||||
|
||||
public String last() {
|
||||
return args.get(args.size() - 1);
|
||||
return args[args.size() - 1];
|
||||
}
|
||||
|
||||
public String get(int index) {
|
||||
return args.get(index);
|
||||
return args[index];
|
||||
}
|
||||
|
||||
public List<String> after(String param) {
|
||||
|
|
|
@ -31,22 +31,22 @@ public class HelpBuilder {
|
|||
}
|
||||
|
||||
public void writeCommand(List<String> aliases, String help, String usage) {
|
||||
if (aliases.isEmpty()) return;
|
||||
if (aliases.isEmpty) return;
|
||||
String indent = " ".repeat(level * 2);
|
||||
builder.append('\n').append(indent).append("- ");
|
||||
for (int i = 0, aliasesSize = aliases.size(); i < aliasesSize; i++) {
|
||||
String alias = aliases.get(i);
|
||||
String alias = aliases[i];
|
||||
builder.append(alias);
|
||||
if (i < aliasesSize - 1)
|
||||
builder.append(", ");
|
||||
}
|
||||
builder.append(": ").append(help.replace("\n", "\n " + indent));
|
||||
if (level == 0 && !usage.isBlank() && !aliases.isEmpty()) {
|
||||
if (level == 0 && !usage.isBlank()) {
|
||||
StringBuilder usagePrefix = new StringBuilder("inceptum");
|
||||
for (String s : upper) {
|
||||
usagePrefix.append(" ").append(s);
|
||||
}
|
||||
usagePrefix.append(" ").append(aliases.get(0)).append(" ");
|
||||
usagePrefix.append(" ").append(aliases[0]).append(" ");
|
||||
builder.append("\n ")
|
||||
.append(indent)
|
||||
.append("Usage: ")
|
||||
|
|
|
@ -26,7 +26,7 @@ public class ExportCommand extends BaseInstanceCommand {
|
|||
if (args.length == 0) throw new IllegalAccessException("You must specify a target path");
|
||||
if (args.length == 1) throw new IllegalAccessException("You must specify a version number");
|
||||
if (args.length != 2) throw new IllegalAccessException("Too many arguments");
|
||||
Exporters.CURSE_FORGE.generate(new ProcessState(), instance, Paths.get(args.get(0)), args.get(1));
|
||||
Exporters.CURSE_FORGE.generate(new ProcessState(), instance, Paths.get(args[0]), args[1]);
|
||||
}
|
||||
|
||||
private static class MultiMCExportCommand extends BaseInstanceCommand {
|
||||
|
@ -38,7 +38,7 @@ public class ExportCommand extends BaseInstanceCommand {
|
|||
protected void invoke(CommandArgs args, Instance instance) throws Exception {
|
||||
if (args.length == 0) throw new IllegalAccessException("You must specify a target path");
|
||||
if (args.length != 1) throw new IllegalAccessException("Too many arguments");
|
||||
Exporters.MULTI_MC.generate(new ProcessState(), instance, Paths.get(args.get(0)), "1.0");
|
||||
Exporters.MULTI_MC.generate(new ProcessState(), instance, Paths.get(args[0]), "1.0");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ public class ExportCommand extends BaseInstanceCommand {
|
|||
if (args.length == 0) throw new IllegalAccessException("You must specify a target path");
|
||||
if (args.length == 1) throw new IllegalAccessException("You must specify a version number");
|
||||
if (args.length != 2) throw new IllegalAccessException("Too many arguments");
|
||||
Exporters.MODRINTH.generate(new ProcessState(), instance, Paths.get(args.get(0)), args.get(1));
|
||||
Exporters.MODRINTH.generate(new ProcessState(), instance, Paths.get(args[0]), args[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,16 +19,16 @@ public class HelpCommand extends Command {
|
|||
CliMain.COMMANDS_ROOT.buildHelp(help);
|
||||
} else {
|
||||
CommandResolution resolution = CliMain.COMMANDS_ROOT.resolve(args);
|
||||
if (resolution.resolvePath().isEmpty()) {
|
||||
if (resolution.resolvePath.isEmpty) {
|
||||
System.err.println("Could not find command matching your input");
|
||||
invoke(new CommandArgs(List.of()));
|
||||
return;
|
||||
}
|
||||
printHeader();
|
||||
System.out.println("\nFound matching: \"" + String.join(" ", resolution.resolvePath()) + "\"");
|
||||
resolution.command().buildHelp(help);
|
||||
System.out.println("\nFound matching: \"" + String.join(" ", resolution.resolvePath) + "\"");
|
||||
resolution.command.buildHelp(help);
|
||||
}
|
||||
System.out.println(help.getResult());
|
||||
System.out.println(help.result);
|
||||
}
|
||||
|
||||
private static void printHeader() {
|
||||
|
|
|
@ -19,7 +19,7 @@ public class ImportCommand extends Command {
|
|||
if (args.length == 0) throw new IllegalAccessException("You must specify a pack file");
|
||||
if (args.length != 1) throw new IllegalAccessException("Too many arguments");
|
||||
ProcessState state = new ProcessState();
|
||||
String name = Importers.importPack(Paths.get(args.get(0)), state).getFileName().toString();
|
||||
String name = Importers.importPack(Paths.get(args[0]), state).fileName.toString();
|
||||
System.out.println(OutputColors.GREEN_BOLD + "Imported as " + name + OutputColors.RESET);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,11 +21,10 @@ public class JvmStateCommand extends Command {
|
|||
System.out.println("Classloader " + loader + ":");
|
||||
|
||||
if (loader instanceof URLClassLoader uc)
|
||||
System.out.println("\t" + Arrays.toString(uc.getURLs()));
|
||||
System.out.println("\t" + Arrays.toString(uc.uRLs));
|
||||
else
|
||||
System.out.println("\t(cannot display components as not a URLClassLoader)");
|
||||
|
||||
if (loader.getParent() != null)
|
||||
dumpClasspath(loader.getParent());
|
||||
if (loader.getParent() != null) dumpClasspath(loader.getParent());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,11 +46,13 @@ public class LaunchCommand extends BaseInstanceCommand {
|
|||
return;
|
||||
}
|
||||
if (args.length > 1) {
|
||||
InstanceMeta meta = instance.meta();
|
||||
if (meta.arguments == null) meta.arguments = new InstanceMeta.Arguments();
|
||||
meta.arguments.client = meta.arguments.client == null ? new ArrayList<>() : new ArrayList<>(meta.arguments.client);
|
||||
meta.arguments.server = meta.arguments.server == null ? new ArrayList<>() : new ArrayList<>(meta.arguments.server);
|
||||
meta.arguments.jvm = meta.arguments.jvm == null ? new ArrayList<>() : new ArrayList<>(meta.arguments.jvm);
|
||||
InstanceMeta meta = instance.meta;
|
||||
if (meta.arguments == null) meta.arguments = new InstanceMeta.Arguments(new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
|
||||
else meta.arguments = new InstanceMeta.Arguments(
|
||||
meta.arguments.jvm == null ? new ArrayList<>() : new ArrayList<>(meta.arguments.jvm),
|
||||
meta.arguments.client == null ? new ArrayList<>() : new ArrayList<>(meta.arguments.client),
|
||||
meta.arguments.server == null ? new ArrayList<>() : new ArrayList<>(meta.arguments.server)
|
||||
);
|
||||
meta.arguments.client.addAll(args.after(0));
|
||||
meta.arguments.server.addAll(args.after(0));
|
||||
}
|
||||
|
|
|
@ -21,13 +21,13 @@ public class ListCommand extends Command {
|
|||
@Override
|
||||
protected void invoke(CommandArgs args) throws IOException {
|
||||
List<Path> paths = JFiles.list(MetaHolder.INSTANCE_DIR);
|
||||
if (paths.isEmpty()) System.out.println("No instances are currently present");
|
||||
if (paths.isEmpty) System.out.println("No instances are currently present");
|
||||
for (Path path : paths) {
|
||||
if (!Files.exists(path.resolve("instance.json"))) {
|
||||
System.out.println("- Invalid instance: " + path + " (no instance metadata)");
|
||||
continue;
|
||||
}
|
||||
System.out.println("- \"" + path.getFileName().toString() + "\"");
|
||||
System.out.println("- \"" + path.fileName.toString() + "\"");
|
||||
Instance instance;
|
||||
try {
|
||||
instance = InstanceList.read(path);
|
||||
|
@ -39,13 +39,13 @@ public class ListCommand extends Command {
|
|||
System.out.println(" Status: Setting up");
|
||||
continue;
|
||||
}
|
||||
System.out.println(" Status: " + (instance.isRunningLocked() ? "Running" : "Stopped"));
|
||||
System.out.println(" Version: " + instance.getGameVersion());
|
||||
if (instance.isFabric()) System.out.println(" Fabric Loader: " + instance.getLoaderVersion());
|
||||
if (instance.meta().java != null) System.out.println(" Custom Java: " + instance.meta().java);
|
||||
if (instance.meta().minMem != null || instance.meta().maxMem != null)
|
||||
System.out.println(" Memory:" + (instance.meta().minMem != null ? " Minimum: " + instance.meta().minMem : "")
|
||||
+ (instance.meta().maxMem != null ? " Maximum: " + instance.meta().maxMem : ""));
|
||||
System.out.println(" Status: " + (instance.isRunningLocked ? "Running" : "Stopped"));
|
||||
System.out.println(" Version: " + instance.gameVersion);
|
||||
if (instance.isFabric) System.out.println(" Fabric Loader: " + instance.loaderVersion);
|
||||
if (instance.meta.java != null) System.out.println(" Custom Java: " + instance.meta.java);
|
||||
if (instance.meta.minMem != null || instance.meta().maxMem != null)
|
||||
System.out.println(" Memory:" + (instance.meta.minMem != null ? " Minimum: " + instance.meta.minMem : "")
|
||||
+ (instance.meta.maxMem != null ? " Maximum: " + instance.meta.maxMem : ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import io.gitlab.jfronny.inceptum.common.Utils;
|
|||
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
|
||||
import io.gitlab.jfronny.inceptum.launcher.system.instance.Mod;
|
||||
import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner;
|
||||
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.launcher.util.Unchecked;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -47,27 +46,26 @@ public class ModCommand extends Command {
|
|||
|
||||
@Override
|
||||
protected void invoke(CommandArgs args, Instance instance) throws IOException {
|
||||
if (!instance.isFabric()) {
|
||||
if (!instance.isFabric) {
|
||||
System.err.println("This is not a fabric instance");
|
||||
return;
|
||||
}
|
||||
System.out.println("Scanning installed mods, this might take a while");
|
||||
instance.mds().runOnce((path, mod) -> {
|
||||
boolean hasSources = !mod.getMetadata().sources.isEmpty();
|
||||
boolean updatable = hasSources && mod.getMetadata().sources.values().stream().anyMatch(Optional::isPresent);
|
||||
instance.mds.runOnce((path, mod) -> {
|
||||
boolean hasSources = !mod.metadata.sources.isEmpty;
|
||||
boolean updatable = hasSources && mod.metadata.sources.values().stream().anyMatch(Optional::isPresent);
|
||||
if (filterUpdatable && !updatable) return;
|
||||
System.out.println("- " + path.getFileName().toString());
|
||||
System.out.println(" " + mod.getName());
|
||||
for (String s : mod.getDescription()) {
|
||||
System.out.println("- " + path.fileName.toString());
|
||||
System.out.println(" " + mod.name);
|
||||
for (String s : mod.description) {
|
||||
System.out.println(" " + s);
|
||||
}
|
||||
if (hasSources) {
|
||||
System.out.println(" Sources:");
|
||||
for (Map.Entry<ModSource, Optional<ModSource>> entry : mod.getMetadata().sources.entrySet()) {
|
||||
System.out.println(" - " + entry.getKey().getName() + " (" + entry.getKey().getVersion() + ")");
|
||||
System.out.println(" Local: " + entry.getKey().getJarPath().toString());
|
||||
if (entry.getValue().isPresent())
|
||||
System.out.println(" Updatable to: " + entry.getValue().get().getVersion());
|
||||
for (var entry : mod.metadata.sources) {
|
||||
System.out.println(" - " + entry.key.name + " (" + entry.key.version + ")");
|
||||
System.out.println(" Local: " + entry.key.jarPath.toString());
|
||||
if (entry.value.isPresent) System.out.println(" Updatable to: " + entry.value.get().version);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -100,22 +98,22 @@ public class ModCommand extends Command {
|
|||
}
|
||||
Set<Path> mods = new HashSet<>();
|
||||
for (String arg : args) {
|
||||
Path p = instance.modsDir().resolve(arg);
|
||||
if (!Files.exists(p)) p = instance.modsDir().resolve(arg + ".imod");
|
||||
Path p = instance.modsDir.resolve(arg);
|
||||
if (!Files.exists(p)) p = instance.modsDir.resolve(arg + ".imod");
|
||||
if (!Files.exists(p)) {
|
||||
Utils.LOGGER.error("Nonexistant mod file: " + instance.modsDir().resolve(arg));
|
||||
Utils.LOGGER.error("Nonexistant mod file: " + instance.modsDir.resolve(arg));
|
||||
return;
|
||||
}
|
||||
mods.add(p);
|
||||
}
|
||||
ModsDirScanner mds = instance.mds();
|
||||
if (!ignoreDependencies && !mds.isComplete()) {
|
||||
ModsDirScanner mds = instance.mds;
|
||||
if (!ignoreDependencies && !mds.isComplete) {
|
||||
Utils.LOGGER.error("Scanning mods dir to search for dependencies. This might take a while");
|
||||
mds.runOnce((path, mod) -> System.out.println("Scanned " + path));
|
||||
}
|
||||
for (Path mod : mods) {
|
||||
try {
|
||||
mds.get(mod).delete();
|
||||
mds[mod].delete();
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not delete " + mod, e);
|
||||
return;
|
||||
|
@ -157,23 +155,23 @@ public class ModCommand extends Command {
|
|||
if (args.length == 0) {
|
||||
throw new IllegalArgumentException("You must specify mods to remove");
|
||||
}
|
||||
Set<Path> mods = pathSupplier.apply(args, instance.path());
|
||||
ModsDirScanner mds = instance.mds();
|
||||
if (!mds.isComplete()) {
|
||||
Set<Path> mods = pathSupplier.apply(args, instance.path);
|
||||
ModsDirScanner mds = instance.mds;
|
||||
if (!mds.isComplete) {
|
||||
Utils.LOGGER.error("Scanning mods dir to search for dependencies. This might take a while");
|
||||
mds.runOnce((path, mod) -> System.out.println("Scanned " + path));
|
||||
}
|
||||
for (Path mod : mods) {
|
||||
try {
|
||||
mds.get(mod).delete();
|
||||
Mod md = mds.get(mod);
|
||||
md.getMetadata().sources.values().stream()
|
||||
Mod md = mds[mod];
|
||||
md.delete();
|
||||
md.metadata.sources.values().stream()
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.findFirst()
|
||||
.ifPresentOrElse(update -> {
|
||||
try {
|
||||
Utils.LOGGER.info("Updating " + mod + " to " + update.getVersion());
|
||||
Utils.LOGGER.info("Updating " + mod + " to " + update.version);
|
||||
md.update(update);
|
||||
Utils.LOGGER.info("Update completed");
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -10,7 +10,7 @@ public class AboutWindow extends AboutDialog {
|
|||
public AboutWindow() {
|
||||
setProgramName(new Str("Inceptum"));
|
||||
setCopyright(new Str("Copyright (C) 2021 JFronny"));
|
||||
setVersion(new Str(BuildMetadata.VERSION.toString()));
|
||||
setVersion(new Str(BuildMetadata.VERSION));
|
||||
setLicenseType(License.MIT_X11);
|
||||
setLicense(I18n.str("about.license"));
|
||||
setWebsiteLabel(I18n.str("about.contact"));
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
plugins {
|
||||
id("inceptum.application-conventions")
|
||||
id("inceptum.manifold")
|
||||
}
|
||||
|
||||
application {
|
||||
|
|
|
@ -65,7 +65,7 @@ public class GuiMain {
|
|||
AccountManager.loadAccounts();
|
||||
Utils.LOGGER.info("Initializing UI");
|
||||
try {
|
||||
InstanceList.forEach(instance -> instance.mds().start());
|
||||
InstanceList.forEach(instance -> instance.mds.start());
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not initialize MDS", e);
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ public class GuiMain {
|
|||
|
||||
GLFW.glfwGetWindowSize(handle, pWidth, pHeight);
|
||||
final GLFWVidMode vidmode = Objects.requireNonNull(GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor()));
|
||||
GLFW.glfwSetWindowPos(handle, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight.get(0)) / 2);
|
||||
GLFW.glfwSetWindowPos(handle, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight[0]) / 2);
|
||||
}
|
||||
|
||||
GLFW.glfwMakeContextCurrent(handle);
|
||||
|
@ -186,7 +186,7 @@ public class GuiMain {
|
|||
io.addConfigFlags(ImGuiConfigFlags.ViewportsEnable);
|
||||
io.setConfigViewportsNoAutoMerge(true);
|
||||
try (InputStream is = LauncherEnv.class.getClassLoader().getResourceAsStream("font.ttf")) {
|
||||
io.setFontDefault(io.getFonts().addFontFromMemoryTTF(Objects.requireNonNull(is).readAllBytes(), 16f));
|
||||
io.fontDefault = io.fonts.addFontFromMemoryTTF(Objects.requireNonNull(is).readAllBytes(), 16f);
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not load font", e);
|
||||
}
|
||||
|
@ -206,24 +206,24 @@ public class GuiMain {
|
|||
if (WINDOWS.isEmpty()) exit();
|
||||
else {
|
||||
for (Window window : WINDOWS.toArray(new Window[0])) {
|
||||
if (window.isNew()) window.preFirstDraw();
|
||||
String title = window.getName() + "##" + System.identityHashCode(window);
|
||||
if (window.isCloseable()) {
|
||||
if (ImGui.begin(title, window.getOpenState(), window.getFlags())) {
|
||||
if (window.isNew) window.preFirstDraw();
|
||||
String title = window.name + "##" + System.identityHashCode(window);
|
||||
if (window.isCloseable) {
|
||||
if (ImGui.begin(title, window.openState, window.flags)) {
|
||||
window.draw();
|
||||
}
|
||||
} else {
|
||||
if (ImGui.begin(title, window.getFlags())) {
|
||||
if (ImGui.begin(title, window.flags)) {
|
||||
window.draw();
|
||||
}
|
||||
}
|
||||
ImGui.end();
|
||||
if (!window.getOpenState().get() && !window.isClosed()) window.close();
|
||||
if (!window.openState.get() && !window.isClosed) window.close();
|
||||
}
|
||||
}
|
||||
//end frame
|
||||
ImGui.render();
|
||||
imGuiGl3.renderDrawData(ImGui.getDrawData());
|
||||
imGuiGl3.renderDrawData(ImGui.drawData);
|
||||
|
||||
if (ImGui.getIO().hasConfigFlags(ImGuiConfigFlags.ViewportsEnable)) {
|
||||
final long backupWindowPtr = GLFW.glfwGetCurrentContext();
|
||||
|
|
|
@ -34,21 +34,21 @@ public class InstanceManageControls {
|
|||
private FabricVersionLoaderInfo selectedFabric;
|
||||
|
||||
public InstanceManageControls(@Nullable Instance instance) {
|
||||
selected = getVersions(false).get(0);
|
||||
selected = getVersions(false)[0];
|
||||
if (instance != null) {
|
||||
for (VersionsListInfo ver : getVersions(true)) {
|
||||
if (ver.id.equals(instance.getGameVersion()))
|
||||
if (ver.id.equals(instance.gameVersion))
|
||||
selected = ver;
|
||||
}
|
||||
}
|
||||
version.set(getVersions(snapshots.get()).indexOf(selected));
|
||||
name.set(instance == null ? InstanceNameTool.getDefaultName(selected.id, fabric.get()) : instance.getName());
|
||||
fabric.set(instance == null || instance.isFabric());
|
||||
List<FabricVersionLoaderInfo> versions = getFabricLoaderInfo();
|
||||
name.set(instance == null ? InstanceNameTool.getDefaultName(selected.id, fabric.get()) : instance.name);
|
||||
fabric.set(instance == null || instance.isFabric);
|
||||
List<FabricVersionLoaderInfo> versions = fabricLoaderInfo;
|
||||
for (int i = 0, fabricLoaderInfoSize = versions.size(); i < fabricLoaderInfoSize; i++) {
|
||||
FabricVersionLoaderInfo version = versions.get(i);
|
||||
if (instance != null && instance.isFabric()
|
||||
? version.loader.version.equals(instance.getLoaderVersion())
|
||||
FabricVersionLoaderInfo version = versions[i];
|
||||
if (instance != null && instance.isFabric
|
||||
? version.loader.version.equals(instance.loaderVersion)
|
||||
: version.loader.stable) {
|
||||
selectedFabric = version;
|
||||
fabricVersion.set(i);
|
||||
|
@ -74,7 +74,7 @@ public class InstanceManageControls {
|
|||
InceptumConfig.snapshots = snapshots.get();
|
||||
InceptumConfig.saveConfig();
|
||||
//fix version index
|
||||
int i = getVersions(InceptumConfig.snapshots).indexOf(getVersions(prev).get(version.get()));
|
||||
int i = getVersions(InceptumConfig.snapshots).indexOf(getVersions(prev)[version.get()]);
|
||||
if (i == -1) version.set(0);
|
||||
else version.set(i);
|
||||
}
|
||||
|
@ -84,16 +84,16 @@ public class InstanceManageControls {
|
|||
List<VersionsListInfo> vil = getVersions(InceptumConfig.snapshots);
|
||||
String originalStr = null;
|
||||
try {
|
||||
originalStr = getVersionInfo().id;
|
||||
originalStr = versionInfo.id;
|
||||
} catch (Throwable e) {
|
||||
Utils.LOGGER.error("Could not get version string", e);
|
||||
}
|
||||
if (ImGui.combo("Version", version, vil.stream().map(info -> info.id).toArray(String[]::new))) {
|
||||
VersionsListInfo prev = selected;
|
||||
selected = vil.get(version.get());
|
||||
selected = vil[version.get()];
|
||||
exchangeNameIfDefault(prev.id, fabric.get());
|
||||
}
|
||||
if (getFabricLoaderInfo().isEmpty()) {
|
||||
if (fabricLoaderInfo.isEmpty()) {
|
||||
fabric.set(false);
|
||||
exchangeNameIfDefault(selected.id, true);
|
||||
} else {
|
||||
|
@ -102,7 +102,7 @@ public class InstanceManageControls {
|
|||
}
|
||||
if (fabric.get()) {
|
||||
ImGui.sameLine();
|
||||
List<FabricVersionLoaderInfo> versions = getFabricLoaderInfo();
|
||||
List<FabricVersionLoaderInfo> versions = fabricLoaderInfo;
|
||||
if (ImGui.combo("Loader", fabricVersion, versions.stream().map(info -> info.loader.version).toArray(String[]::new))) {
|
||||
selectedFabric = versions.get(fabricVersion.get());
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ public class InstanceManageControls {
|
|||
}
|
||||
try {
|
||||
if (originalStr != null && !originalStr.equals(getVersionInfo().id))
|
||||
modifiedVersion.accept(getVersionInfo().id);
|
||||
modifiedVersion.accept(versionInfo.id);
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not compare version string", e);
|
||||
}
|
||||
|
|
|
@ -15,26 +15,26 @@ import java.nio.file.Files;
|
|||
|
||||
public class InstanceView {
|
||||
public static void draw() throws IOException {
|
||||
if (InstanceList.isEmpty()) {
|
||||
if (InstanceList.isEmpty) {
|
||||
ImGui.text("You have not yet created an instance");
|
||||
ImGui.text("Use File->New Instance to do so");
|
||||
return;
|
||||
}
|
||||
if (ImGui.beginTable("Instances", 2, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders)) {
|
||||
for (Instance instance : InstanceList.ordered()) {
|
||||
if (instance.isSetupLocked()) {
|
||||
if (instance.isSetupLocked) {
|
||||
ImGui.tableNextColumn();
|
||||
ImGui.text("Setting up");
|
||||
ImGui.tableNextColumn();
|
||||
ImGui.text("This instance is currently being set up");
|
||||
continue;
|
||||
}
|
||||
if (!Files.exists(instance.path().resolve("instance.json"))) {
|
||||
if (!Files.exists(instance.path.resolve("instance.json"))) {
|
||||
Utils.LOGGER.error("Invalid instance (doesn't contain instance.json): " + instance);
|
||||
continue;
|
||||
}
|
||||
ImGui.tableNextColumn();
|
||||
boolean runDisabled = instance.isRunningLocked();
|
||||
boolean runDisabled = instance.isRunningLocked;
|
||||
if (runDisabled) ImGui.beginDisabled();
|
||||
if (ImGui.button(instance.toString())) {
|
||||
try {
|
||||
|
@ -46,7 +46,7 @@ public class InstanceView {
|
|||
}
|
||||
if (runDisabled) ImGui.endDisabled();
|
||||
ImGui.tableNextColumn();
|
||||
if (ImGui.button("Edit##" + instance.id())) {
|
||||
if (ImGui.button("Edit##" + instance.id)) {
|
||||
try {
|
||||
GuiMain.open(new InstanceEditWindow(instance));
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -12,13 +12,13 @@ public abstract class Tab {
|
|||
protected abstract void renderInner();
|
||||
|
||||
public void render() {
|
||||
if (canShow() && ImGui.beginTabItem(name)) {
|
||||
if (isVisible && ImGui.beginTabItem(name)) {
|
||||
renderInner();
|
||||
ImGui.endTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean canShow() {
|
||||
protected boolean isVisible() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,19 +26,19 @@ public class AddModWindow extends Window {
|
|||
private ModrinthSearchResult mr = null;
|
||||
private List<CurseforgeMod> cf = null;
|
||||
|
||||
public AddModWindow(Instance instance) throws IOException {
|
||||
super(instance.getName() + " - Add Mods");
|
||||
public AddModWindow(Instance instance) {
|
||||
super(instance.name + " - Add Mods");
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
private void reSearch() throws IOException {
|
||||
private void reSearch() {
|
||||
String query = this.query.get();
|
||||
new Thread(() -> {
|
||||
try {
|
||||
ModrinthSearchResult ms = ModrinthApi.search(query, mrPage, instance.getGameVersion(), ModrinthProjectType.mod);
|
||||
ModrinthSearchResult ms = ModrinthApi.search(query, mrPage, instance.gameVersion, ModrinthProjectType.mod);
|
||||
if (!this.query.get().equals(query)) return;
|
||||
mr = ms;
|
||||
List<CurseforgeMod> cs = CurseforgeApi.search(instance.getGameVersion(), query, cfPage, "Popularity");
|
||||
List<CurseforgeMod> cs = CurseforgeApi.search(instance.gameVersion, query, cfPage, "Popularity");
|
||||
if (!this.query.get().equals(query)) return;
|
||||
cf = cs;
|
||||
} catch (IOException e) {
|
||||
|
@ -71,12 +71,11 @@ public class AddModWindow extends Window {
|
|||
reSearch();
|
||||
}
|
||||
}
|
||||
if (mr != null && ImGui.beginTable("mods" + instance.id(), 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders)) {
|
||||
if (mr != null && ImGui.beginTable("mods" + instance.id, 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders)) {
|
||||
for (ModrinthSearchResult.ModResult mod : mr.hits) {
|
||||
String modId = (mod.slug != null ? mod.slug : mod.project_id);
|
||||
final String idPrefix = "local-";
|
||||
if (mod.project_id.startsWith(idPrefix))
|
||||
mod.project_id = mod.project_id.substring(idPrefix.length());
|
||||
String projectId = mod.project_id.startsWith(idPrefix) ? mod.project_id.substring(idPrefix.length()) : mod.project_id;
|
||||
//TODO detail view
|
||||
ImGui.tableNextColumn();
|
||||
ImGui.text(mod.title);
|
||||
|
@ -84,22 +83,21 @@ public class AddModWindow extends Window {
|
|||
ImGui.text(mod.description);
|
||||
ImGui.tableNextColumn();
|
||||
boolean alreadyPresent = false;
|
||||
for (Mod mdsMod : instance.getMods()) {
|
||||
alreadyPresent = mdsMod.getMetadata().sources.keySet().stream()
|
||||
.anyMatch(s -> s instanceof ModrinthModSource ms
|
||||
&& ms.getModId().equals(mod.project_id));
|
||||
for (Mod mdsMod : instance.mods) {
|
||||
alreadyPresent = mdsMod.metadata.sources.keySet().stream()
|
||||
.anyMatch(s -> s instanceof ModrinthModSource ms && ms.modId.equals(projectId));
|
||||
if (alreadyPresent)
|
||||
break;
|
||||
}
|
||||
if (alreadyPresent) {
|
||||
ImGui.text("Installed");
|
||||
} else {
|
||||
if (ImGui.button("Add##" + mod.project_id)) {
|
||||
if (ImGui.button("Add##" + projectId)) {
|
||||
ModrinthVersion stable = null;
|
||||
ModrinthVersion beta = null;
|
||||
ModrinthVersion latest = null;
|
||||
for (ModrinthVersion version : ModrinthApi.getVersions(mod.project_id)) {
|
||||
if (version.game_versions.contains(instance.getGameVersion()) && version.loaders.contains("fabric")) {
|
||||
for (ModrinthVersion version : ModrinthApi.getVersions(projectId)) {
|
||||
if (version.game_versions.contains(instance.gameVersion) && version.loaders.contains("fabric")) {
|
||||
latest = version;
|
||||
if (version.version_type == ModrinthVersion.VersionType.beta || version.version_type == ModrinthVersion.VersionType.release) {
|
||||
beta = version;
|
||||
|
@ -117,7 +115,7 @@ public class AddModWindow extends Window {
|
|||
ModrinthVersion finalLatest = latest;
|
||||
new Thread(() -> {
|
||||
try {
|
||||
ModManager.download(new ModrinthModSource(finalLatest.id), instance.modsDir().resolve((mod.slug == null ? mod.project_id : mod.slug) + ModPath.EXT_IMOD), instance.mds()).write();
|
||||
ModManager.download(new ModrinthModSource(finalLatest.id), instance.modsDir.resolve((mod.slug == null ? projectId : mod.slug) + ModPath.EXT_IMOD), instance.mds).write();
|
||||
} catch (IOException e) {
|
||||
LauncherEnv.showError("Could not download mod", e);
|
||||
}
|
||||
|
@ -126,7 +124,7 @@ public class AddModWindow extends Window {
|
|||
}
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (ImGui.button("Web##" + mod.project_id)) {
|
||||
if (ImGui.button("Web##" + projectId)) {
|
||||
Utils.openWebBrowser(new URI("https://modrinth.com/mod/" + modId));
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +148,7 @@ public class AddModWindow extends Window {
|
|||
reSearch();
|
||||
}
|
||||
}
|
||||
if (cf != null && ImGui.beginTable("curseforge" + instance.id(), 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders)) {
|
||||
if (cf != null && ImGui.beginTable("curseforge" + instance.id, 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders)) {
|
||||
for (CurseforgeMod mod : cf) {
|
||||
//TODO detail view
|
||||
ImGui.tableNextColumn();
|
||||
|
@ -159,10 +157,9 @@ public class AddModWindow extends Window {
|
|||
ImGui.text(mod.summary);
|
||||
ImGui.tableNextColumn();
|
||||
boolean alreadyPresent = false;
|
||||
for (Mod mdsMod : instance.mds().getMods()) {
|
||||
alreadyPresent = mdsMod.getMetadata().sources.keySet().stream()
|
||||
.anyMatch(s -> s instanceof CurseforgeModSource ms
|
||||
&& ms.getProjectId() == mod.id);
|
||||
for (Mod mdsMod : instance.mds.mods) {
|
||||
alreadyPresent = mdsMod.metadata.sources.keySet().stream()
|
||||
.anyMatch(s -> s instanceof CurseforgeModSource ms && ms.projectId == mod.id);
|
||||
if (alreadyPresent)
|
||||
break;
|
||||
}
|
||||
|
@ -172,7 +169,7 @@ public class AddModWindow extends Window {
|
|||
if (ImGui.button("Add##" + mod.id)) {
|
||||
CurseforgeMod.LatestFileIndex latest = null;
|
||||
for (CurseforgeMod.LatestFileIndex file : mod.latestFilesIndexes) {
|
||||
if (file.gameVersion.equals(instance.getGameVersion())) {
|
||||
if (file.gameVersion.equals(instance.gameVersion)) {
|
||||
if (latest == null) latest = file;
|
||||
}
|
||||
}
|
||||
|
@ -182,7 +179,7 @@ public class AddModWindow extends Window {
|
|||
CurseforgeMod.LatestFileIndex finalLatest = latest;
|
||||
new Thread(() -> {
|
||||
try {
|
||||
ModManager.download(new CurseforgeModSource(mod.id, finalLatest.fileId), instance.modsDir().resolve((mod.slug == null ? mod.id : mod.slug) + ModPath.EXT_IMOD), instance.mds()).write();
|
||||
ModManager.download(new CurseforgeModSource(mod.id, finalLatest.fileId), instance.modsDir.resolve((mod.slug == null ? mod.id : mod.slug) + ModPath.EXT_IMOD), instance.mds).write();
|
||||
} catch (IOException e) {
|
||||
LauncherEnv.showError("Could not download mod", e);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ public class GuiUtil {
|
|||
LauncherEnv.showInfo("The instance was successfully created. You can now launch it using the main menu", "Successfully installed");
|
||||
}, () -> {
|
||||
try {
|
||||
JFiles.deleteRecursive(MetaHolder.INSTANCE_DIR.resolve(state.name()));
|
||||
JFiles.deleteRecursive(MetaHolder.INSTANCE_DIR.resolve(state.name));
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not delete instance dir", e);
|
||||
}
|
||||
|
|
|
@ -49,11 +49,11 @@ public class MainWindow extends Window {
|
|||
}
|
||||
if (ImGui.beginMenu("Account")) {
|
||||
if (ImGui.menuItem("New")) GuiMain.open(new MicrosoftLoginWindow());
|
||||
AuthInfo selected = AccountManager.getSelectedAccount();
|
||||
List<MicrosoftAccount> accounts = AccountManager.getAccounts();
|
||||
AuthInfo selected = AccountManager.selectedAccount;
|
||||
List<MicrosoftAccount> accounts = AccountManager.accounts;
|
||||
int accountsSize = accounts.size();
|
||||
for (int i = 0; i < accountsSize; i++) {
|
||||
MicrosoftAccount account = accounts.get(i);
|
||||
MicrosoftAccount account = accounts[i];
|
||||
if (selected.equals(account)) accountIndex.set(i);
|
||||
if (ImGui.radioButton(account.minecraftUsername, accountIndex, i)) {
|
||||
AccountManager.switchAccount(account);
|
||||
|
|
|
@ -32,7 +32,7 @@ public class NewInstanceWindow extends Window {
|
|||
imc.nameBox("OK", name -> {
|
||||
try {
|
||||
GuiUtil.createInstance(new SetupStepInfo(imc.getVersionInfo(),
|
||||
imc.getLoaderInfo(),
|
||||
imc.loaderInfo,
|
||||
name,
|
||||
Steps.createProcessState()));
|
||||
} catch (IOException e) {
|
||||
|
@ -54,7 +54,7 @@ public class NewInstanceWindow extends Window {
|
|||
GuiMain.open(new ProcessStateWatcherWindow("Importing", "Could not import packs", state, cToken -> {
|
||||
for (Path pack : packs) {
|
||||
Path imported = Importers.importPack(pack, state);
|
||||
LauncherEnv.showInfo(pack.getFileName() + " has been successfully imported as " + imported.getFileName(), "Imported pack");
|
||||
LauncherEnv.showInfo(pack.fileName + " has been successfully imported as " + imported.fileName, "Imported pack");
|
||||
}
|
||||
}, null));
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@ public class ProcessStateWatcherWindow extends Window {
|
|||
|
||||
@Override
|
||||
public void draw() {
|
||||
ImGui.progressBar(state.getProgress());
|
||||
ImGui.textUnformatted(state.getCurrentStep());
|
||||
ImGui.progressBar(state.progress);
|
||||
ImGui.textUnformatted(state.currentStep);
|
||||
if (cancel != null && ImGui.button("Cancel")) {
|
||||
canceled.set(true);
|
||||
close();
|
||||
|
|
|
@ -2,12 +2,15 @@ package io.gitlab.jfronny.inceptum.imgui.window.edit;
|
|||
|
||||
import imgui.ImGui;
|
||||
import imgui.type.ImString;
|
||||
import io.gitlab.jfronny.inceptum.common.Utils;
|
||||
import io.gitlab.jfronny.inceptum.imgui.control.Tab;
|
||||
import io.gitlab.jfronny.inceptum.imgui.window.GuiUtil;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ArgumentsTab extends Tab {
|
||||
private final InstanceEditWindow window;
|
||||
|
@ -18,28 +21,29 @@ public class ArgumentsTab extends Tab {
|
|||
public ArgumentsTab(InstanceEditWindow window) {
|
||||
super("Arguments");
|
||||
this.window = window;
|
||||
InstanceMeta meta = window.instance.meta();
|
||||
if (meta.arguments == null) meta.arguments = new InstanceMeta.Arguments();
|
||||
if (meta.arguments.jvm == null) meta.arguments.jvm = new LinkedList<>();
|
||||
InstanceMeta meta = window.instance.meta;
|
||||
if (meta.arguments == null) meta.arguments = new InstanceMeta.Arguments(new LinkedList<>(), new LinkedList<>(), new LinkedList<>());
|
||||
if (meta.arguments.jvm == null) meta.arguments = meta.arguments.withJvm(new LinkedList<>());
|
||||
jvm.set(String.join("\n", meta.arguments.jvm));
|
||||
if (meta.arguments.client == null) meta.arguments.client = new LinkedList<>();
|
||||
if (meta.arguments.client == null) meta.arguments = meta.arguments.withClient(new LinkedList<>());
|
||||
client.set(String.join("\n", meta.arguments.client));
|
||||
if (meta.arguments.server == null) meta.arguments.server = new LinkedList<>();
|
||||
if (meta.arguments.server == null) meta.arguments = meta.arguments.withServer(new LinkedList<>());
|
||||
server.set(String.join("\n", meta.arguments.server));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderInner() {
|
||||
InstanceMeta meta = window.instance.meta;
|
||||
if (ImGui.inputTextMultiline("JVM", jvm)) {
|
||||
window.instance.meta().arguments.jvm = List.of(jvm.get().split("[\r\n]+"));
|
||||
meta.arguments = meta.arguments.withJvm(List.of(Utils.NEW_LINE.split(jvm.get())));
|
||||
window.instance.writeMeta();
|
||||
}
|
||||
if (ImGui.inputTextMultiline("Client", client)) {
|
||||
window.instance.meta().arguments.client = List.of(client.get().split("[\r\n]+"));
|
||||
meta.arguments = meta.arguments.withClient(List.of(Utils.NEW_LINE.split(client.get())));
|
||||
window.instance.writeMeta();
|
||||
}
|
||||
if (ImGui.inputTextMultiline("Server", server)) {
|
||||
window.instance.meta().arguments.server = List.of(server.get().split("[\r\n]+"));
|
||||
meta.arguments = meta.arguments.withServer(List.of(Utils.NEW_LINE.split(server.get())));
|
||||
window.instance.writeMeta();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,18 +23,18 @@ public class ExportTab extends Tab {
|
|||
|
||||
@Override
|
||||
protected void renderInner() {
|
||||
if (window.instance.mds().isComplete()) {
|
||||
if (window.instance.mds.isComplete) {
|
||||
for (Exporter<?> exporter : Exporters.EXPORTERS) {
|
||||
if (ImGui.button(exporter.getName())) {
|
||||
if (ImGui.button(exporter.name)) {
|
||||
GuiMain.open(new TextBoxWindow("Version", "Please enter the current version of your modpack", "1.0", version -> {
|
||||
String defaultName = window.instance.getName() + " " + version + " (" + exporter.getName() + ")." + exporter.getFileExtension();
|
||||
String filter = "*." + exporter.getFileExtension();
|
||||
Path exportPath = GuiMain.saveFileDialog("Export " + exporter.getName() + " Pack", defaultName, new String[]{filter}, exporter.getName() + " packs (" + filter + ")");
|
||||
String defaultName = window.instance.name + " " + version + " (" + exporter.name + ")." + exporter.fileExtension;
|
||||
String filter = "*." + exporter.fileExtension;
|
||||
Path exportPath = GuiMain.saveFileDialog("Export " + exporter.name + " Pack", defaultName, new String[]{filter}, exporter.name + " packs (" + filter + ")");
|
||||
if (exportPath != null) {
|
||||
ProcessState state = new ProcessState(Exporters.STEP_COUNT, "Initializing...");
|
||||
GuiMain.open(new ProcessStateWatcherWindow("Exporting", "Could not export pack", state, cToken -> {
|
||||
exporter.generate(state, window.instance, exportPath, version);
|
||||
LauncherEnv.showInfo(window.instance.getName() + " has been successfully exported to " + exportPath, "Successfully exported");
|
||||
LauncherEnv.showInfo(window.instance.name + " has been successfully exported to " + exportPath, "Successfully exported");
|
||||
}, null));
|
||||
}
|
||||
}, R::nop));
|
||||
|
|
|
@ -26,7 +26,7 @@ public class GeneralTab extends Tab {
|
|||
super("General");
|
||||
this.window = window;
|
||||
imc = new InstanceManageControls(window.instance);
|
||||
String java = window.instance.meta().java;
|
||||
String java = window.instance.meta.java;
|
||||
customJava = new ImBoolean(java != null);
|
||||
if (java != null) customJavaPath.set(java);
|
||||
}
|
||||
|
@ -34,12 +34,12 @@ public class GeneralTab extends Tab {
|
|||
@Override
|
||||
protected void renderInner() {
|
||||
if (ImGui.button("Open Directory")) {
|
||||
Utils.openFile(window.instance.path().toFile());
|
||||
Utils.openFile(window.instance.path.toFile());
|
||||
}
|
||||
imc.nameBox("Rename", name -> {
|
||||
try {
|
||||
Path newPath = MetaHolder.INSTANCE_DIR.resolve(name);
|
||||
Files.move(window.instance.path(), newPath);
|
||||
Files.move(window.instance.path, newPath);
|
||||
GuiMain.open(new InstanceEditWindow(window.instance));
|
||||
window.close();
|
||||
} catch (IOException e) {
|
||||
|
@ -55,7 +55,7 @@ public class GeneralTab extends Tab {
|
|||
if (ImGui.button("Delete"))
|
||||
LauncherEnv.showOkCancel("This instance will be removed forever (a long time)", "Are you sure?", () -> {
|
||||
try {
|
||||
JFiles.deleteRecursive(window.instance.path());
|
||||
JFiles.deleteRecursive(window.instance.path);
|
||||
} catch (IOException e) {
|
||||
LauncherEnv.showError("Could not delete the instance", e);
|
||||
}
|
||||
|
@ -63,15 +63,15 @@ public class GeneralTab extends Tab {
|
|||
}, R::nop);
|
||||
if (ImGui.checkbox("Custom Java", customJava)) {
|
||||
if (customJava.get()) {
|
||||
window.instance.meta().java = OSUtils.getJvmBinary();
|
||||
customJavaPath.set(window.instance.meta().java);
|
||||
window.instance.meta.java = OSUtils.jvmBinary;
|
||||
customJavaPath.set(window.instance.meta.java);
|
||||
} else {
|
||||
window.instance.meta().java = null;
|
||||
window.instance.meta.java = null;
|
||||
}
|
||||
window.instance.writeMeta();
|
||||
}
|
||||
if (customJava.get() && ImGui.inputText("Path", customJavaPath)) {
|
||||
window.instance.meta().java = customJavaPath.get();
|
||||
window.instance.meta.java = customJavaPath.get();
|
||||
window.instance.writeMeta();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ public class InstanceEditWindow extends Window {
|
|||
protected boolean lastTabWasMods = false;
|
||||
|
||||
public InstanceEditWindow(Instance instance) throws IOException {
|
||||
super(instance.getName() + " - Edit");
|
||||
super(instance.name + " - Edit");
|
||||
this.instance = instance;
|
||||
this.instance.mds().start();
|
||||
this.instance.mds.start();
|
||||
this.tabs = List.of(
|
||||
new GeneralTab(this),
|
||||
new ArgumentsTab(this),
|
||||
|
@ -29,15 +29,15 @@ public class InstanceEditWindow extends Window {
|
|||
|
||||
@Override
|
||||
public void draw() {
|
||||
if (instance.isSetupLocked()) {
|
||||
if (instance.isSetupLocked) {
|
||||
ImGui.text("This instance is still being set up.");
|
||||
return;
|
||||
}
|
||||
if (instance.isRunningLocked()) {
|
||||
if (instance.isRunningLocked) {
|
||||
ImGui.text("This instance is running. Edits in this state will result in breakage.");
|
||||
}
|
||||
lastTabWasMods = false;
|
||||
if (ImGui.beginTabBar("InstanceEdit" + instance.id())) {
|
||||
if (ImGui.beginTabBar("InstanceEdit" + instance.id)) {
|
||||
for (Tab tab : tabs) tab.render();
|
||||
ImGui.endTabBar();
|
||||
}
|
||||
|
|
|
@ -29,28 +29,24 @@ public class ModsTab extends Tab {
|
|||
@Override
|
||||
protected void renderInner() {
|
||||
window.lastTabWasMods = true;
|
||||
if (!Files.exists(window.instance.modsDir())) {
|
||||
if (!Files.exists(window.instance.modsDir)) {
|
||||
try {
|
||||
Files.createDirectories(window.instance.modsDir());
|
||||
Files.createDirectories(window.instance.modsDir);
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not create mods directory which was missing from this modded instance", e);
|
||||
}
|
||||
}
|
||||
ImGui.beginChild("mods select", 200, 0);
|
||||
if (ImGui.button("Add")) {
|
||||
try {
|
||||
GuiMain.WINDOWS.add(new AddModWindow(window.instance));
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not open window", e);
|
||||
}
|
||||
GuiMain.WINDOWS.add(new AddModWindow(window.instance));
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (Files.exists(window.instance.modsDir()) && ImGui.button("Show")) {
|
||||
Utils.openFile(window.instance.modsDir().toFile());
|
||||
if (Files.exists(window.instance.modsDir) && ImGui.button("Show")) {
|
||||
Utils.openFile(window.instance.modsDir.toFile());
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (Files.exists(window.instance.configDir()) && ImGui.button("Configs")) {
|
||||
Utils.openFile(window.instance.configDir().toFile());
|
||||
if (Files.exists(window.instance.configDir) && ImGui.button("Configs")) {
|
||||
Utils.openFile(window.instance.configDir.toFile());
|
||||
}
|
||||
try {
|
||||
Set<Mod> modSet = window.instance.getMods();
|
||||
|
@ -58,10 +54,10 @@ public class ModsTab extends Tab {
|
|||
float scannedPercentage = 0;
|
||||
boolean hasUnScanned = false;
|
||||
for (Mod mod : modSet) {
|
||||
if (window.instance.mds().hasScanned(mod)) scannedPercentage++;
|
||||
if (window.instance.mds.hasScanned(mod)) scannedPercentage++;
|
||||
else hasUnScanned = true;
|
||||
for (Optional<ModSource> value : mod.getMetadata().sources.values()) {
|
||||
if (value.isPresent()) {
|
||||
for (Optional<ModSource> value : mod.metadata.sources.values()) {
|
||||
if (value.isPresent) {
|
||||
updatesFound = true;
|
||||
break;
|
||||
}
|
||||
|
@ -78,21 +74,21 @@ public class ModsTab extends Tab {
|
|||
ImGui.separator();
|
||||
for (Mod mod : modSet) {
|
||||
updatesFound = false;
|
||||
for (Optional<ModSource> value : mod.getMetadata().sources.values()) {
|
||||
updatesFound |= value.isPresent();
|
||||
for (Optional<ModSource> value : mod.metadata.sources.values()) {
|
||||
updatesFound |= value.isPresent;
|
||||
}
|
||||
if (filterUpdates.get() && !updatesFound) continue;
|
||||
if (ImGui.checkbox("##" + mod.getName(), mod.isEnabled())) {
|
||||
Path newSel = ModPath.toggle(mod.getMetadataPath());
|
||||
if (ImGui.checkbox("##" + mod.name, mod.isEnabled)) {
|
||||
Path newSel = ModPath.toggle(mod.metadataPath);
|
||||
try {
|
||||
Files.move(mod.getMetadataPath(), newSel);
|
||||
if (mod.getMetadataPath().equals(selected)) selected = newSel;
|
||||
Files.move(mod.metadataPath, newSel);
|
||||
if (mod.metadataPath.equals(selected)) selected = newSel;
|
||||
} catch (IOException e) {
|
||||
LauncherEnv.showError("Could not change disabled state", e);
|
||||
}
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (ImGui.button(mod.getName())) selected = mod.getMetadataPath();
|
||||
if (ImGui.button(mod.name)) selected = mod.metadataPath;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not show mod list", e);
|
||||
|
@ -102,24 +98,24 @@ public class ModsTab extends Tab {
|
|||
ImGui.beginGroup();
|
||||
if (selected == null) {
|
||||
ImGui.text("Select a mod to view settings");
|
||||
} else if (window.instance.mds().hasScanned(selected)) {
|
||||
Mod md = window.instance.mds().get(selected);
|
||||
ImGui.text(md.getName());
|
||||
} else if (window.instance.mds.hasScanned(selected)) {
|
||||
Mod md = window.instance.mds[selected];
|
||||
ImGui.text(md.name);
|
||||
ImGui.separator();
|
||||
for (String s : md.getDescription()) {
|
||||
for (String s : md.description) {
|
||||
ImGui.text(s);
|
||||
}
|
||||
ImGui.separator();
|
||||
Map<ModSource, Optional<ModSource>> sources = md.getMetadata().sources;
|
||||
Map<ModSource, Optional<ModSource>> sources = md.metadata.sources;
|
||||
ImGui.text("Sources:");
|
||||
if (sources.isEmpty())
|
||||
if (sources.isEmpty)
|
||||
ImGui.bulletText("Local Drive");
|
||||
else {
|
||||
for (Map.Entry<ModSource, Optional<ModSource>> source : sources.entrySet()) {
|
||||
ImGui.bulletText(source.getKey().getName());
|
||||
source.getValue().ifPresent(update -> {
|
||||
for (var source : sources) {
|
||||
ImGui.bulletText(source.key.name);
|
||||
source.value.ifPresent(update -> {
|
||||
ImGui.sameLine();
|
||||
if (ImGui.button("Update to " + update.getVersion())) {
|
||||
if (ImGui.button("Update to " + update.version)) {
|
||||
try {
|
||||
selected = md.update(update);
|
||||
} catch (IOException e) {
|
||||
|
@ -130,8 +126,8 @@ public class ModsTab extends Tab {
|
|||
}
|
||||
}
|
||||
if (ImGui.button("Delete")) {
|
||||
if (!md.getMetadata().dependents.isEmpty())
|
||||
LauncherEnv.showError("This mod still has the following dependent mods installed: " + String.join(", ", md.getMetadata().dependents), "Dependents present");
|
||||
if (!md.metadata.dependents.isEmpty)
|
||||
LauncherEnv.showError("This mod still has the following dependent mods installed: " + String.join(", ", md.metadata.dependents), "Dependents present");
|
||||
else {
|
||||
try {
|
||||
md.delete();
|
||||
|
@ -148,7 +144,7 @@ public class ModsTab extends Tab {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean canShow() {
|
||||
return window.instance.isFabric();
|
||||
protected boolean isVisible() {
|
||||
return window.instance.isFabric;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
plugins {
|
||||
id("inceptum.library-conventions")
|
||||
id("inceptum.gson-compile")
|
||||
id("inceptum.manifold")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -50,7 +50,7 @@ public class CurseforgeApi {
|
|||
if (response.pagination.totalCount != 1) {
|
||||
throw new FileNotFoundException("Could not find mod with slug \"" + slug + "\"");
|
||||
}
|
||||
return checkDistribution(response.data.get(0));
|
||||
return checkDistribution(response.data[0]);
|
||||
}
|
||||
|
||||
public static CurseforgeMod getMod(int id) throws IOException {
|
||||
|
|
|
@ -5,6 +5,7 @@ import io.gitlab.jfronny.gson.stream.JsonReader;
|
|||
import io.gitlab.jfronny.inceptum.common.Net;
|
||||
import io.gitlab.jfronny.inceptum.common.model.maven.ArtifactMeta;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.fabric.*;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricVersionLoaderInfo.WithMeta.LauncherMeta.Libraries.Library;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.mojang.*;
|
||||
import io.gitlab.jfronny.inceptum.launcher.util.GameVersionParser;
|
||||
|
||||
|
@ -40,40 +41,45 @@ public class FabricMetaApi {
|
|||
if (meta.version != 1) throw new IOException("Unsupported fabric launcherMeta version: " + meta.version);
|
||||
result.mainClass = type == FabricVersionInfoType.Server ? meta.mainClass.server : meta.mainClass.client;
|
||||
List<VersionInfo.Library> libs = new ArrayList<>(version.libraries);
|
||||
for (FabricVersionLoaderInfo.WithMeta.LauncherMeta.Libraries.Library library : meta.libraries.common)
|
||||
for (Library library : meta.libraries.common)
|
||||
libs.add(convertLib(library));
|
||||
if (type == FabricVersionInfoType.Client || type == FabricVersionInfoType.Both) {
|
||||
for (FabricVersionLoaderInfo.WithMeta.LauncherMeta.Libraries.Library library : meta.libraries.client)
|
||||
for (Library library : meta.libraries.client)
|
||||
libs.add(convertLib(library));
|
||||
}
|
||||
if (type == FabricVersionInfoType.Server || type == FabricVersionInfoType.Both) {
|
||||
for (FabricVersionLoaderInfo.WithMeta.LauncherMeta.Libraries.Library library : meta.libraries.server)
|
||||
for (Library library : meta.libraries.server)
|
||||
libs.add(convertLib(library));
|
||||
}
|
||||
var floader = new FabricVersionLoaderInfo.WithMeta.LauncherMeta.Libraries.Library();
|
||||
floader.name = "net.fabricmc:fabric-loader:" + fabricVersion;
|
||||
floader.url = "https://maven.fabricmc.net/";
|
||||
libs.add(convertLib(floader));
|
||||
floader.name = ver.intermediary.maven;
|
||||
libs.add(convertLib(floader));
|
||||
libs.add(convertLib(new Library(
|
||||
"net.fabricmc:fabric-loader:" + fabricVersion,
|
||||
"https://maven.fabricmc.net/"
|
||||
)));
|
||||
libs.add(convertLib(new Library(
|
||||
ver.intermediary.maven,
|
||||
"https://maven.fabricmc.net/"
|
||||
)));
|
||||
result.libraries = List.copyOf(libs);
|
||||
result.id = GameVersionParser.createVersionWithFabric(version.id, fabricVersion);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static VersionInfo.Library convertLib(FabricVersionLoaderInfo.WithMeta.LauncherMeta.Libraries.Library library) {
|
||||
VersionInfo.Library res = new VersionInfo.Library();
|
||||
res.name = library.name;
|
||||
res.rules = new Rules(true);
|
||||
res.natives = new HashMap<>();
|
||||
res.downloads = new VersionInfo.Library.Downloads();
|
||||
res.downloads.classifiers = null;
|
||||
res.downloads.artifact = new VersionInfo.Library.Downloads.Artifact();
|
||||
res.downloads.artifact.path = ArtifactMeta.parse(library.name).getJarPath(true);
|
||||
res.downloads.artifact.size = -1;
|
||||
res.downloads.artifact.sha1 = null;
|
||||
res.downloads.artifact.url = library.url + res.downloads.artifact.path;
|
||||
return res;
|
||||
private static VersionInfo.Library convertLib(Library library) {
|
||||
String path = ArtifactMeta.parse(library.name).getJarPath(true);
|
||||
return new VersionInfo.Library(
|
||||
new VersionInfo.Library.Downloads(
|
||||
new VersionInfo.Library.Downloads.Artifact(
|
||||
path,
|
||||
-1,
|
||||
null,
|
||||
library.url + path
|
||||
),
|
||||
null
|
||||
),
|
||||
library.name,
|
||||
new HashMap<>(),
|
||||
new Rules(true)
|
||||
);
|
||||
}
|
||||
|
||||
public enum FabricVersionInfoType {
|
||||
|
|
|
@ -47,7 +47,7 @@ public class McApi {
|
|||
case LINUX -> info.linux;
|
||||
case MAC_OS -> info.macOs;
|
||||
};
|
||||
List<JvmInfo.Jvm> vmList = vms.get(component);
|
||||
List<JvmInfo.Jvm> vmList = vms[component];
|
||||
if (vmList == null)
|
||||
throw new IOException("Invalid component: " + component + " (available: " + String.join(", ", vms.keySet()));
|
||||
for (JvmInfo.Jvm jvm : vmList) {
|
||||
|
|
|
@ -26,7 +26,7 @@ public class AccountManager {
|
|||
}
|
||||
|
||||
public static boolean accountMissing() {
|
||||
return ACCOUNTS.isEmpty();
|
||||
return ACCOUNTS.isEmpty;
|
||||
}
|
||||
|
||||
public static List<MicrosoftAccount> getAccounts() {
|
||||
|
@ -40,6 +40,7 @@ public class AccountManager {
|
|||
|
||||
public static void saveAccounts() {
|
||||
try (JsonWriter w = new JsonWriter(Files.newBufferedWriter(MetaHolder.ACCOUNTS_PATH))) {
|
||||
GsonPreset.Config.configure(w);
|
||||
GList.write(w, ACCOUNTS, GC_MicrosoftAccount::write);
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not save accounts", e);
|
||||
|
@ -50,6 +51,7 @@ public class AccountManager {
|
|||
Utils.LOGGER.info("Loading accounts");
|
||||
if (Files.exists(MetaHolder.ACCOUNTS_PATH)) {
|
||||
try (JsonReader r = new JsonReader(Files.newBufferedReader(MetaHolder.ACCOUNTS_PATH))) {
|
||||
GsonPreset.Config.configure(r);
|
||||
ACCOUNTS.addAll(GList.read(r, GC_MicrosoftAccount::read));
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not load accounts", e);
|
||||
|
@ -77,7 +79,7 @@ public class AccountManager {
|
|||
if (ACCOUNTS.size() == 1)
|
||||
switchAccount(null);
|
||||
else
|
||||
switchAccount(ACCOUNTS.get(0));
|
||||
switchAccount(ACCOUNTS[0]);
|
||||
}
|
||||
ACCOUNTS.remove(account);
|
||||
saveAccounts();
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.api.account;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.R;
|
||||
import io.gitlab.jfronny.inceptum.common.Utils;
|
||||
import io.gitlab.jfronny.inceptum.common.*;
|
||||
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.microsoft.response.*;
|
||||
import io.gitlab.jfronny.inceptum.launcher.gson.MicrosoftAccountMeta;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.microsoft.*;
|
||||
|
||||
|
@ -11,13 +11,8 @@ import java.io.IOException;
|
|||
import java.net.URISyntaxException;
|
||||
import java.util.*;
|
||||
|
||||
@GSerializable(with = MicrosoftAccountMeta.class)
|
||||
@GSerializable(with = MicrosoftAccountMeta.class, configure = GsonPreset.Config.class)
|
||||
public class MicrosoftAccount {
|
||||
/**
|
||||
* Auto generated serial.
|
||||
*/
|
||||
private static final long serialVersionUID = 5483749902584257559L;
|
||||
|
||||
/**
|
||||
* The username/email/id of the account.
|
||||
*/
|
||||
|
@ -60,14 +55,14 @@ public class MicrosoftAccount {
|
|||
public boolean mustLogin;
|
||||
|
||||
public MicrosoftAccount(MicrosoftAccountMeta meta) {
|
||||
this.accountId = meta.accountId();
|
||||
this.minecraftUsername = meta.minecraftUsername();
|
||||
this.uuid = meta.uuid();
|
||||
this.accessToken = meta.accessToken();
|
||||
this.oauthToken = meta.oauthToken();
|
||||
this.xstsAuth = meta.xstsAuth();
|
||||
this.accessTokenExpiresAt = meta.accessTokenExpiresAt();
|
||||
this.mustLogin = meta.mustLogin();
|
||||
this.accountId = meta.accountId;
|
||||
this.minecraftUsername = meta.minecraftUsername;
|
||||
this.uuid = meta.uuid;
|
||||
this.accessToken = meta.accessToken;
|
||||
this.oauthToken = meta.oauthToken;
|
||||
this.xstsAuth = meta.xstsAuth;
|
||||
this.accessTokenExpiresAt = meta.accessTokenExpiresAt;
|
||||
this.mustLogin = meta.mustLogin;
|
||||
}
|
||||
|
||||
public MicrosoftAccountMeta toMeta() {
|
||||
|
@ -92,14 +87,14 @@ public class MicrosoftAccount {
|
|||
LoginResponse loginResponse, Profile profile) {
|
||||
this.oauthToken = oauthTokenResponse;
|
||||
this.xstsAuth = xstsAuthResponse;
|
||||
this.accessToken = loginResponse.accessToken();
|
||||
this.accessToken = loginResponse.accessToken;
|
||||
this.minecraftUsername = profile.name;
|
||||
this.uuid = profile.id;
|
||||
this.accountId = loginResponse.username();
|
||||
this.accountId = loginResponse.username;
|
||||
this.mustLogin = false;
|
||||
|
||||
this.accessTokenExpiresAt = new Date();
|
||||
this.accessTokenExpiresAt.setTime(this.accessTokenExpiresAt.getTime() + (loginResponse.expiresIn() * 1000));
|
||||
this.accessTokenExpiresAt.time += loginResponse.expiresIn * 1000;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
|
@ -152,10 +147,10 @@ public class MicrosoftAccount {
|
|||
AccountManager.saveAccounts();
|
||||
}
|
||||
|
||||
if (force || new Date().after(this.xstsAuth.notAfter())) {
|
||||
if (force || new Date().after(this.xstsAuth.notAfter)) {
|
||||
Utils.LOGGER.info("xsts auth expired. Attempting to get new auth");
|
||||
XboxLiveAuthResponse xboxLiveAuthResponse = MicrosoftAuthAPI.getXBLToken(this.oauthToken.accessToken);
|
||||
this.xstsAuth = MicrosoftAuthAPI.getXstsToken(xboxLiveAuthResponse.token());
|
||||
this.xstsAuth = MicrosoftAuthAPI.getXstsToken(xboxLiveAuthResponse.token);
|
||||
|
||||
if (xstsAuth == null) {
|
||||
mustLogin = true;
|
||||
|
@ -168,7 +163,7 @@ public class MicrosoftAccount {
|
|||
}
|
||||
|
||||
if (force || new Date().after(this.accessTokenExpiresAt)) {
|
||||
LoginResponse loginResponse = MicrosoftAuthAPI.loginToMinecraft(this.getIdentityToken());
|
||||
LoginResponse loginResponse = MicrosoftAuthAPI.loginToMinecraft(identityToken);
|
||||
|
||||
if (loginResponse == null) {
|
||||
mustLogin = true;
|
||||
|
@ -177,12 +172,11 @@ public class MicrosoftAccount {
|
|||
return false;
|
||||
}
|
||||
|
||||
this.accessToken = loginResponse.accessToken();
|
||||
this.accountId = loginResponse.username();
|
||||
this.accessToken = loginResponse.accessToken;
|
||||
this.accountId = loginResponse.username;
|
||||
|
||||
this.accessTokenExpiresAt = new Date();
|
||||
this.accessTokenExpiresAt
|
||||
.setTime(this.accessTokenExpiresAt.getTime() + (loginResponse.expiresIn() * 1000));
|
||||
this.accessTokenExpiresAt.time += loginResponse.expiresIn * 1000;
|
||||
|
||||
AccountManager.saveAccounts();
|
||||
}
|
||||
|
@ -198,7 +192,7 @@ public class MicrosoftAccount {
|
|||
}
|
||||
|
||||
private String getIdentityToken() {
|
||||
return "XBL3.0 x=" + xstsAuth.displayClaims().xui().get(0).uhs() + ";" + xstsAuth.token();
|
||||
return "XBL3.0 x=" + xstsAuth.displayClaims.xui[0].uhs + ";" + xstsAuth.token;
|
||||
}
|
||||
|
||||
public boolean ensureAccessTokenValid() {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.api.account;
|
||||
|
||||
import io.gitlab.jfronny.commons.HttpUtils;
|
||||
import io.gitlab.jfronny.inceptum.launcher.api.account.request.*;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.microsoft.*;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.microsoft.request.*;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.microsoft.response.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.gitlab.jfronny.inceptum.launcher.api.account;
|
|||
|
||||
import io.gitlab.jfronny.inceptum.common.Utils;
|
||||
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.microsoft.response.*;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.microsoft.*;
|
||||
import net.freeutils.httpserver.HTTPServer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -24,33 +25,33 @@ public class MicrosoftAuthServer implements Closeable {
|
|||
|
||||
public void start() throws IOException {
|
||||
host.addContext("/", (req, res) -> {
|
||||
if (req.getParams().containsKey("error")) {
|
||||
res.getHeaders().add("Content-Type", "text/plain");
|
||||
if (req.params.containsKey("error")) {
|
||||
res.headers.add("Content-Type", "text/plain");
|
||||
res.send(500, "Error logging in. Check console for more information");
|
||||
Utils.LOGGER.error("Error logging into Microsoft account: " + URLDecoder
|
||||
.decode(req.getParams().get("error_description"), StandardCharsets.UTF_8));
|
||||
.decode(req.params["error_description"], StandardCharsets.UTF_8));
|
||||
close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!req.getParams().containsKey("code")) {
|
||||
res.getHeaders().add("Content-Type", "text/plain");
|
||||
if (!req.params.containsKey("code")) {
|
||||
res.headers.add("Content-Type", "text/plain");
|
||||
res.send(400, "Code is missing");
|
||||
close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
acquireAccessToken(req.getParams().get("code"));
|
||||
acquireAccessToken(req.params["code"]);
|
||||
} catch (Exception e) {
|
||||
Utils.LOGGER.error("Error acquiring accessToken", e);
|
||||
res.getHeaders().add("Content-Type", "text/html");
|
||||
res.headers.add("Content-Type", "text/html");
|
||||
res.send(500, "Error logging in. Check console for more information");
|
||||
close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
res.getHeaders().add("Content-Type", "text/plain");
|
||||
res.headers.add("Content-Type", "text/plain");
|
||||
// #. {0} is the name of the launcher
|
||||
res.send(200, "Login complete. You can now close this window and go back to the Launcher");
|
||||
close();
|
||||
|
@ -61,8 +62,8 @@ public class MicrosoftAuthServer implements Closeable {
|
|||
}
|
||||
|
||||
private void addAccount(OauthTokenResponse oauthTokenResponse, XboxLiveAuthResponse xstsAuthResponse, LoginResponse loginResponse, Profile profile) {
|
||||
if (this.previous != null || AccountManager.isAccountByName(loginResponse.username())) {
|
||||
MicrosoftAccount account = (MicrosoftAccount) AccountManager.getAccountByName(loginResponse.username());
|
||||
if (this.previous != null || AccountManager.isAccountByName(loginResponse.username)) {
|
||||
MicrosoftAccount account = (MicrosoftAccount) AccountManager.getAccountByName(loginResponse.username);
|
||||
|
||||
if (account == null) {
|
||||
return;
|
||||
|
@ -103,16 +104,13 @@ public class MicrosoftAuthServer implements Closeable {
|
|||
}
|
||||
|
||||
private void acquireMinecraftToken(OauthTokenResponse oauthTokenResponse, XboxLiveAuthResponse xstsAuthResponse) throws Exception {
|
||||
String xblUhs = xstsAuthResponse.displayClaims().xui().get(0).uhs();
|
||||
String xblXsts = xstsAuthResponse.token();
|
||||
|
||||
LoginResponse loginResponse = MicrosoftAuthAPI.loginToMinecraft("XBL3.0 x=" + xblUhs + ";" + xblXsts);
|
||||
LoginResponse loginResponse = MicrosoftAuthAPI.loginToMinecraft("XBL3.0 x=" + xstsAuthResponse.displayClaims.xui[0].uhs + ";" + xstsAuthResponse.token);
|
||||
|
||||
if (loginResponse == null) {
|
||||
throw new Exception("Failed to login to Minecraft");
|
||||
}
|
||||
|
||||
Entitlements entitlements = MicrosoftAuthAPI.getEntitlements(loginResponse.accessToken());
|
||||
Entitlements entitlements = MicrosoftAuthAPI.getEntitlements(loginResponse.accessToken);
|
||||
|
||||
if (!(entitlements.items.stream().anyMatch(i -> i.name.equalsIgnoreCase("product_minecraft"))
|
||||
&& entitlements.items.stream().anyMatch(i -> i.name.equalsIgnoreCase("game_minecraft")))) {
|
||||
|
@ -123,7 +121,7 @@ public class MicrosoftAuthServer implements Closeable {
|
|||
Profile profile = null;
|
||||
|
||||
try {
|
||||
profile = MicrosoftAuthAPI.getMcProfile(loginResponse.accessToken());
|
||||
profile = MicrosoftAuthAPI.getMcProfile(loginResponse.accessToken);
|
||||
} catch (Exception e) {
|
||||
LauncherEnv.showError("""
|
||||
No Minecraft profiles were found for this account. Have you purchased Minecraft?
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.api.account.request;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
|
||||
@GSerializable
|
||||
public record LoginRequest(String xtoken, String platform) {
|
||||
}
|
|
@ -3,17 +3,16 @@ package io.gitlab.jfronny.inceptum.launcher.gson;
|
|||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.gson.stream.JsonReader;
|
||||
import io.gitlab.jfronny.gson.stream.JsonWriter;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
import io.gitlab.jfronny.inceptum.launcher.api.account.MicrosoftAccount;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.microsoft.OauthTokenResponse;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.microsoft.XboxLiveAuthResponse;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.microsoft.response.OauthTokenResponse;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.microsoft.response.XboxLiveAuthResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
@GSerializable
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record MicrosoftAccountMeta(String accountId, String minecraftUsername, String uuid, String accessToken, OauthTokenResponse oauthToken, XboxLiveAuthResponse xstsAuth, Date accessTokenExpiresAt, boolean mustLogin) {
|
||||
public static final long SERIAL_VERSION_UID = 5483749902584257559L;
|
||||
|
||||
public static void write(JsonWriter writer, MicrosoftAccount value) throws IOException {
|
||||
GC_MicrosoftAccountMeta.write(writer, value == null ? null : value.toMeta());
|
||||
}
|
||||
|
|
|
@ -14,25 +14,25 @@ public class ModSourceAdapter {
|
|||
writer.beginObject();
|
||||
if (src instanceof ModrinthModSource mo) {
|
||||
writer.name("type").value("modrinth")
|
||||
.name("id").value(mo.getVersionId());
|
||||
.name("id").value(mo.versionId);
|
||||
} else if (src instanceof DirectModSource di) {
|
||||
writer.name("type").value("direct")
|
||||
.name("fileName").value(di.fileName())
|
||||
.name("url").value(di.url())
|
||||
.name("fileName").value(di.fileName)
|
||||
.name("url").value(di.url)
|
||||
.name("dependencies");
|
||||
writer.beginArray();
|
||||
for (ModSource dependency : di.dependencies()) {
|
||||
for (ModSource dependency : di.dependencies) {
|
||||
write(writer, dependency);
|
||||
}
|
||||
writer.endArray();
|
||||
} else if (src instanceof CurseforgeModSource cu) {
|
||||
writer.name("type").value("curseforge");
|
||||
if (cu.getShortName().matches("\\d+")) {
|
||||
writer.name("projectId").value(cu.getProjectId());
|
||||
if (cu.shortName.matches("\\d+")) {
|
||||
writer.name("projectId").value(cu.projectId);
|
||||
} else {
|
||||
writer.name("project").value(cu.getShortName());
|
||||
writer.name("project").value(cu.shortName);
|
||||
}
|
||||
writer.name("fileId").value(cu.getFileId());
|
||||
writer.name("fileId").value(cu.fileId);
|
||||
} else throw new RuntimeException("ModSources with the type " + src.getClass() + " are not supported");
|
||||
writer.endObject();
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public class RulesAdapter {
|
|||
throw new JsonParseException("Unexpected action in argument: " + actionType);
|
||||
}
|
||||
if (hasFeatures) valid = false;
|
||||
if (osName != null && !OSUtils.TYPE.getMojName().equals(osName)) valid = false;
|
||||
if (osName != null && !OSUtils.TYPE.mojName.equals(osName)) valid = false;
|
||||
if (osVersion != null && !System.getProperty("os.version").matches(osVersion)) valid = false;
|
||||
if (actionType.equals("disallow")) valid = !valid;
|
||||
}
|
||||
|
|
|
@ -1,87 +1,81 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.curseforge;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@GSerializable
|
||||
public class CurseforgeFile {
|
||||
public Integer id;
|
||||
public Integer gameId;
|
||||
public Integer modId;
|
||||
public Boolean isAvailable;
|
||||
public String displayName;
|
||||
public String fileName;
|
||||
/* Possible values:
|
||||
1=Release
|
||||
2=Beta
|
||||
3=Alpha*/
|
||||
public Integer releaseType;
|
||||
/* Possible values:
|
||||
1=Processing
|
||||
2=ChangesRequired
|
||||
3=UnderReview
|
||||
4=Approved
|
||||
5=Rejected
|
||||
6=MalwareDetected
|
||||
7=Deleted
|
||||
8=Archived
|
||||
9=Testing
|
||||
10=Released
|
||||
11=ReadyForReview
|
||||
12=Deprecated
|
||||
13=Baking
|
||||
14=AwaitingPublishing
|
||||
15=FailedPublishing*/
|
||||
public Integer fileStatus;
|
||||
public List<Hash> hashes;
|
||||
public Date fileDate;
|
||||
public Integer fileLength;
|
||||
public Long downloadCount;
|
||||
public String downloadUrl;
|
||||
public List<String> gameVersions;
|
||||
public List<GameVersion> sortableGameVersions;
|
||||
public List<Dependency> dependencies;
|
||||
public Integer alternateFileId;
|
||||
public Boolean isServerPack;
|
||||
public Long fileFingerprint; // murmur5 hash
|
||||
public List<Module> modules;
|
||||
|
||||
@GSerializable
|
||||
public static class Hash {
|
||||
public String value;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record CurseforgeFile(
|
||||
int id,
|
||||
int gameId,
|
||||
int modId,
|
||||
boolean isAvailable,
|
||||
String displayName,
|
||||
String fileName,
|
||||
/* Possible values:
|
||||
1=Sha1
|
||||
2=Md5*/
|
||||
public Integer algo;
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class GameVersion {
|
||||
public String gameVersionName;
|
||||
public String gameVersionPadded;
|
||||
public String gameVersion;
|
||||
public Date gameVersionReleaseDate;
|
||||
public Integer gameVersionTypeId;
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class Dependency {
|
||||
public Integer modId;
|
||||
1=Release
|
||||
2=Beta
|
||||
3=Alpha*/
|
||||
int releaseType,
|
||||
/* Possible values:
|
||||
1=EmbeddedLibrary
|
||||
2=OptionalDependency
|
||||
3=RequiredDependency
|
||||
4=Tool
|
||||
5=Incompatible
|
||||
6=Include*/
|
||||
public Integer relationType;
|
||||
1=Processing
|
||||
2=ChangesRequired
|
||||
3=UnderReview
|
||||
4=Approved
|
||||
5=Rejected
|
||||
6=MalwareDetected
|
||||
7=Deleted
|
||||
8=Archived
|
||||
9=Testing
|
||||
10=Released
|
||||
11=ReadyForReview
|
||||
12=Deprecated
|
||||
13=Baking
|
||||
14=AwaitingPublishing
|
||||
15=FailedPublishing*/
|
||||
int fileStatus,
|
||||
List<Hash> hashes,
|
||||
Date fileDate,
|
||||
int fileLength,
|
||||
long downloadCount,
|
||||
String downloadUrl,
|
||||
List<String> gameVersions,
|
||||
List<GameVersion> sortableGameVersions,
|
||||
List<Dependency> dependencies,
|
||||
int alternateFileId,
|
||||
boolean isServerPack,
|
||||
long fileFingerprint, // murmur5 hash
|
||||
List<Module> modules
|
||||
) {
|
||||
/* Possible algorithms:
|
||||
1=Sha1
|
||||
2=Md5*/
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Hash(String value, int algo) {
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class Module {
|
||||
public String name;
|
||||
public Long fingerprint;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record GameVersion(String gameVersionName,
|
||||
String gameVersionPadded,
|
||||
String gameVersion,
|
||||
Date gameVersionReleaseDate,
|
||||
int gameVersionTypeId) {
|
||||
}
|
||||
|
||||
/* Possible relationship types:
|
||||
1=EmbeddedLibrary
|
||||
2=OptionalDependency
|
||||
3=RequiredDependency
|
||||
4=Tool
|
||||
5=Incompatible
|
||||
6=Include*/
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Dependency(int modId, int relationType) {
|
||||
}
|
||||
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Module(String name, long fingerprint) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,105 +1,95 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.curseforge;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@GSerializable
|
||||
public class CurseforgeMod {
|
||||
public Integer id;
|
||||
public Integer gameId;
|
||||
public String name;
|
||||
public String slug;
|
||||
public Links links;
|
||||
public String summary;
|
||||
/* Possible values:
|
||||
1=New
|
||||
2=ChangesRequired
|
||||
3=UnderSoftReview
|
||||
4=Approved
|
||||
5=Rejected
|
||||
6=ChangesMade
|
||||
7=Inactive
|
||||
8=Abandoned
|
||||
9=Deleted
|
||||
10=UnderReview*/
|
||||
public Integer status;
|
||||
public Long downloadCount;
|
||||
public Boolean isFeatured;
|
||||
public Integer primaryCategoryId;
|
||||
public List<Category> categories;
|
||||
public Integer classId;
|
||||
public List<Author> authors;
|
||||
public Logo logo;
|
||||
public List<Screenshot> screenshots;
|
||||
public Integer mainFileId;
|
||||
public List<CurseforgeFile> latestFiles;
|
||||
public List<LatestFileIndex> latestFilesIndexes;
|
||||
public Date dateCreated;
|
||||
public Date dateModified;
|
||||
public Date dateReleased;
|
||||
public Boolean allowModDistribution;
|
||||
public Integer gamePopularityRank;
|
||||
public Boolean isAvailable;
|
||||
public Integer thumbsUpCount;
|
||||
|
||||
@GSerializable
|
||||
public static class Links {
|
||||
public String websiteUrl;
|
||||
public String wikiUrl;
|
||||
public String issuesUrl;
|
||||
public String sourcesUrl;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record CurseforgeMod(
|
||||
int id,
|
||||
int gameId,
|
||||
String name,
|
||||
String slug,
|
||||
Links links,
|
||||
String summary, // optional
|
||||
/* Possible values:
|
||||
1=New
|
||||
2=ChangesRequired
|
||||
3=UnderSoftReview
|
||||
4=Approved
|
||||
5=Rejected
|
||||
6=ChangesMade
|
||||
7=Inactive
|
||||
8=Abandoned
|
||||
9=Deleted
|
||||
10=UnderReview*/
|
||||
int status,
|
||||
long downloadCount,
|
||||
boolean isFeatured,
|
||||
int primaryCategoryId,
|
||||
List<Category> categories,
|
||||
int classId,
|
||||
List<Author> authors,
|
||||
Logo logo,
|
||||
List<Screenshot> screenshots,
|
||||
int mainFileId,
|
||||
List<CurseforgeFile> latestFiles,
|
||||
List<LatestFileIndex> latestFilesIndexes,
|
||||
Date dateCreated,
|
||||
Date dateModified,
|
||||
Date dateReleased,
|
||||
boolean allowModDistribution,
|
||||
int gamePopularityRank,
|
||||
boolean isAvailable,
|
||||
int thumbsUpCount
|
||||
) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Links(String websiteUrl, String wikiUrl, String issuesUrl, String sourcesUrl) {
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class Category {
|
||||
public Integer id;
|
||||
public Integer gameId;
|
||||
public String name;
|
||||
public String slug;
|
||||
public String url;
|
||||
public String iconUrl;
|
||||
public Date dateModified;
|
||||
public Boolean isClass;
|
||||
public Integer classId;
|
||||
public Integer primaryCategoryId;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Category(int id,
|
||||
int gameId,
|
||||
String name,
|
||||
String slug,
|
||||
String url,
|
||||
String iconUrl,
|
||||
Date dateModified,
|
||||
boolean isClass,
|
||||
int classId,
|
||||
int primaryCategoryId) {
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class Author {
|
||||
public Integer id;
|
||||
public String name;
|
||||
public String url;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Author(int id, String name, String url) {
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class Logo {
|
||||
public Integer id;
|
||||
public Integer modId;
|
||||
public String title;
|
||||
public String description;
|
||||
public String thumbnailUrl;
|
||||
public String url;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Logo(int id,
|
||||
int modId,
|
||||
String title,
|
||||
String description,
|
||||
String thumbnailUrl,
|
||||
String url) {
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class Screenshot {
|
||||
public Integer id;
|
||||
public Integer modId;
|
||||
public String title;
|
||||
public String description;
|
||||
public String thumbnailUrl;
|
||||
public String url;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Screenshot(int id,
|
||||
int modId,
|
||||
String title,
|
||||
String description,
|
||||
String thumbnailUrl,
|
||||
String url) {
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class LatestFileIndex {
|
||||
public String gameVersion;
|
||||
public Integer fileId;
|
||||
public String filename;
|
||||
public Integer releaseType;
|
||||
public Integer gameVersionTypeId;
|
||||
public Integer modLoader;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record LatestFileIndex(String gameVersion,
|
||||
int fileId,
|
||||
String filename,
|
||||
int releaseType,
|
||||
int gameVersionTypeId,
|
||||
Integer modLoader) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,36 +1,27 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.curseforge;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@GSerializable
|
||||
public class CurseforgeModpackManifest {
|
||||
public Minecraft minecraft;
|
||||
public String manifestType;
|
||||
public Integer manifestVersion;
|
||||
public String name;
|
||||
public String version;
|
||||
public String author;
|
||||
public Set<File> files;
|
||||
public String overrides;
|
||||
|
||||
@GSerializable
|
||||
public static class Minecraft {
|
||||
public String version;
|
||||
public Set<ModLoader> modLoaders;
|
||||
|
||||
@GSerializable
|
||||
public static class ModLoader {
|
||||
public String id;
|
||||
public Boolean primary;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record CurseforgeModpackManifest(Minecraft minecraft,
|
||||
String manifestType,
|
||||
int manifestVersion,
|
||||
String name,
|
||||
String version,
|
||||
String author,
|
||||
Set<File> files,
|
||||
String overrides) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Minecraft(String version, Set<ModLoader> modLoaders) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record ModLoader(String id, boolean primary) {
|
||||
}
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class File {
|
||||
public Integer projectID;
|
||||
public Integer fileID;
|
||||
public Boolean required;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record File(int projectID, int fileID, boolean required) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,22 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.curseforge.response;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.curseforge.CurseforgeFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@GSerializable
|
||||
public class FingerprintMatchesResponse {
|
||||
public Result data;
|
||||
|
||||
@GSerializable
|
||||
public static class Result {
|
||||
public Boolean isCacheBuilt;
|
||||
public List<Match> exactMatches;
|
||||
public List<Integer> exactFingerprints;
|
||||
public List<Match> partialMatches;
|
||||
public List<Integer> installedFingerprints;
|
||||
public List<Integer> unmatchedFingerprints;
|
||||
|
||||
@GSerializable
|
||||
public static class Match {
|
||||
public Integer id;
|
||||
public CurseforgeFile file;
|
||||
public List<CurseforgeFile> latestFiles;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record FingerprintMatchesResponse(Result data) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Result(boolean isCacheBuilt,
|
||||
List<Match> exactMatches,
|
||||
List<Integer> exactFingerprints,
|
||||
List<Match> partialMatches,
|
||||
List<Integer> installedFingerprints,
|
||||
List<Integer> unmatchedFingerprints) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Match(int id, CurseforgeFile file, List<CurseforgeFile> latestFiles) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.curseforge.response;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.curseforge.CurseforgeFile;
|
||||
|
||||
@GSerializable
|
||||
public class GetModFileResponse {
|
||||
public CurseforgeFile data;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record GetModFileResponse(CurseforgeFile data) {
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.curseforge.response;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.curseforge.CurseforgeMod;
|
||||
|
||||
@GSerializable
|
||||
public class GetModResponse {
|
||||
public CurseforgeMod data;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record GetModResponse(CurseforgeMod data) {
|
||||
}
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.curseforge.response;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.curseforge.CurseforgeMod;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@GSerializable
|
||||
public class SearchResponse {
|
||||
public List<CurseforgeMod> data;
|
||||
public Pagination pagination;
|
||||
|
||||
@GSerializable
|
||||
public static class Pagination {
|
||||
public Integer index;
|
||||
public Integer pageSite;
|
||||
public Integer resultCount;
|
||||
public Integer totalCount;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record SearchResponse(List<CurseforgeMod> data, Pagination pagination) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Pagination(int index, int pageSite, int resultCount, int totalCount) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.fabric;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
@GSerializable
|
||||
public class FabricLoaderVersion {
|
||||
public String separator;
|
||||
public Integer build;
|
||||
public String maven;
|
||||
public String version;
|
||||
public Boolean stable;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record FabricLoaderVersion(String separator, int build, String maven, String version, boolean stable) {
|
||||
}
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.fabric;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
@GSerializable
|
||||
public class FabricModJson {
|
||||
public String id;
|
||||
public String name;
|
||||
public String description;
|
||||
public String version;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record FabricModJson(String id, String name, String description, String version) {
|
||||
}
|
||||
|
|
|
@ -1,41 +1,30 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.fabric;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@GSerializable
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public class FabricVersionLoaderInfo {
|
||||
public FabricLoaderVersion loader;
|
||||
public IntermediaryVersion intermediary;
|
||||
|
||||
@GSerializable
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public static class WithMeta extends FabricVersionLoaderInfo {
|
||||
public LauncherMeta launcherMeta;
|
||||
|
||||
@GSerializable
|
||||
public static class LauncherMeta {
|
||||
public int version;
|
||||
public Libraries libraries;
|
||||
public MainClass mainClass;
|
||||
|
||||
@GSerializable
|
||||
public static class Libraries {
|
||||
public List<Library> client;
|
||||
public List<Library> common;
|
||||
public List<Library> server;
|
||||
|
||||
@GSerializable
|
||||
public static class Library {
|
||||
public String name;
|
||||
public String url;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record LauncherMeta(int version, Libraries libraries, MainClass mainClass) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Libraries(List<Library> client, List<Library> common, List<Library> server) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Library(String name, String url) {
|
||||
}
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class MainClass {
|
||||
public String client;
|
||||
public String server;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record MainClass(String client, String server) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.fabric;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
@GSerializable
|
||||
public class IntermediaryVersion {
|
||||
public String maven;
|
||||
public String version;
|
||||
public boolean stable;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record IntermediaryVersion(String maven, String version, boolean stable) {
|
||||
}
|
||||
|
|
|
@ -2,18 +2,8 @@ package io.gitlab.jfronny.inceptum.launcher.model.inceptum;
|
|||
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionInfo;
|
||||
|
||||
public class ArtifactInfo {
|
||||
public final String path;
|
||||
public final String sha1;
|
||||
public final int size;
|
||||
public final String url;
|
||||
public final boolean isNative;
|
||||
|
||||
public record ArtifactInfo(String path, String sha1, int size, String url, boolean isNative) {
|
||||
public ArtifactInfo(VersionInfo.Library.Downloads.Artifact artifact, boolean isNative) {
|
||||
path = artifact.path;
|
||||
sha1 = artifact.sha1;
|
||||
size = artifact.size;
|
||||
url = artifact.url;
|
||||
this.isNative = isNative;
|
||||
this(artifact.path, artifact.sha1, artifact.size, artifact.url, isNative);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.inceptum;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
@ -14,42 +15,37 @@ public class InstanceMeta {
|
|||
public Long lastLaunched;
|
||||
public Arguments arguments;
|
||||
|
||||
@GSerializable
|
||||
public static class Arguments {
|
||||
public List<String> jvm;
|
||||
public List<String> client;
|
||||
public List<String> server;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Arguments arguments = (Arguments) o;
|
||||
return Objects.equals(jvm, arguments.jvm)
|
||||
&& Objects.equals(client, arguments.client)
|
||||
&& Objects.equals(server, arguments.server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(jvm, client, server);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
InstanceMeta that = (InstanceMeta) o;
|
||||
return Objects.equals(version, that.version)
|
||||
&& Objects.equals(java, that.java)
|
||||
&& Objects.equals(minMem, that.minMem)
|
||||
&& Objects.equals(maxMem, that.maxMem)
|
||||
&& Objects.equals(arguments, that.arguments);
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) return true;
|
||||
if (obj == null || obj.getClass() != this.getClass()) return false;
|
||||
var that = (InstanceMeta) obj;
|
||||
return Objects.equals(this.version, that.version) &&
|
||||
Objects.equals(this.java, that.java) &&
|
||||
Objects.equals(this.minMem, that.minMem) &&
|
||||
Objects.equals(this.maxMem, that.maxMem) &&
|
||||
Objects.equals(this.lastLaunched, that.lastLaunched) &&
|
||||
Objects.equals(this.arguments, that.arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(version, java, minMem, maxMem, arguments);
|
||||
return Objects.hash(version, java, minMem, maxMem, lastLaunched, arguments);
|
||||
}
|
||||
|
||||
|
||||
@GSerializable(configure = GsonPreset.Config.class)
|
||||
public record Arguments(List<String> jvm, List<String> client, List<String> server) {
|
||||
public Arguments withJvm(List<String> jvm) {
|
||||
return new Arguments(jvm, client, server);
|
||||
}
|
||||
|
||||
public Arguments withClient(List<String> client) {
|
||||
return new Arguments(jvm, client, server);
|
||||
}
|
||||
|
||||
public Arguments withServer(List<String> server) {
|
||||
return new Arguments(jvm, client, server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.inceptum;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
import io.gitlab.jfronny.inceptum.launcher.gson.ModMetaSourcesAdapter;
|
||||
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -8,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
@GSerializable(with = ModMetaSourcesAdapter.class)
|
||||
@GSerializable(with = ModMetaSourcesAdapter.class, configure = GsonPreset.Config.class)
|
||||
public class ModMeta$Sources implements Map<ModSource, Optional<ModSource>> {
|
||||
private Map<ModSource, Optional<ModSource>> delegate = new LinkedHashMap<>();
|
||||
|
||||
|
@ -34,7 +35,7 @@ public class ModMeta$Sources implements Map<ModSource, Optional<ModSource>> {
|
|||
|
||||
@Override
|
||||
public Optional<ModSource> get(Object o) {
|
||||
return delegate.get(o);
|
||||
return delegate[o];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.gitlab.jfronny.inceptum.launcher.model.inceptum;
|
|||
import io.gitlab.jfronny.commons.HashUtils;
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GPrefer;
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
import io.gitlab.jfronny.inceptum.common.Utils;
|
||||
import io.gitlab.jfronny.inceptum.launcher.api.CurseforgeApi;
|
||||
import io.gitlab.jfronny.inceptum.launcher.api.ModrinthApi;
|
||||
|
@ -17,17 +18,52 @@ import java.nio.file.Path;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@GSerializable
|
||||
public class ModMeta {
|
||||
public ModMeta$Sources sources; //key: source, value: update
|
||||
public String sha1;
|
||||
public Long murmur2;
|
||||
public List<String> dependents; // by file name
|
||||
public List<String> dependencies; // by file name
|
||||
public boolean explicit = true;
|
||||
|
||||
@GSerializable(configure = GsonPreset.Config.class)
|
||||
public record ModMeta(
|
||||
ModMeta$Sources sources, //key: source, value: update
|
||||
String sha1,
|
||||
Long murmur2,
|
||||
List<String> dependents, // by file name
|
||||
List<String> dependencies, // by file name
|
||||
boolean explicit
|
||||
) {
|
||||
@GPrefer
|
||||
public ModMeta() {
|
||||
public ModMeta {}
|
||||
|
||||
public static ModMeta of(Path mod) {
|
||||
String sha1 = null;
|
||||
Long murmur2 = null;
|
||||
if (!Files.isDirectory(mod)) {
|
||||
try {
|
||||
byte[] data = Files.readAllBytes(mod);
|
||||
sha1 = HashUtils.sha1(data);
|
||||
murmur2 = HashUtils.murmur2(data);
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not read file hash", e);
|
||||
}
|
||||
}
|
||||
return new ModMeta(
|
||||
new ModMeta$Sources(),
|
||||
sha1,
|
||||
murmur2,
|
||||
new ArrayList<>(),
|
||||
new ArrayList<>(),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
public static ModMeta of(String sha1, Long murmur2, @Nullable ModSource knownSource, String gameVersion) {
|
||||
ModMeta res = new ModMeta(
|
||||
new ModMeta$Sources(),
|
||||
sha1,
|
||||
murmur2,
|
||||
new ArrayList<>(),
|
||||
new ArrayList<>(),
|
||||
true
|
||||
);
|
||||
if (knownSource != null) res.addSource(knownSource, gameVersion);
|
||||
res.initialize(gameVersion);
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean initialize(String gameVersion) {
|
||||
|
@ -50,7 +86,8 @@ public class ModMeta {
|
|||
if (!curseforge) {
|
||||
try {
|
||||
FingerprintMatchesResponse.Result cf = CurseforgeApi.checkFingerprint(murmur2);
|
||||
if (!cf.exactMatches.isEmpty()) {
|
||||
if (!cf.exactMatches.isEmpty) {
|
||||
// TODO use array access once fixed
|
||||
FingerprintMatchesResponse.Result.Match f = cf.exactMatches.get(0);
|
||||
addSource(new CurseforgeModSource(f.id, f.file.id), gameVersion);
|
||||
changed = true;
|
||||
|
@ -62,40 +99,12 @@ public class ModMeta {
|
|||
return changed;
|
||||
}
|
||||
|
||||
public static ModMeta of(Path mod) {
|
||||
ModMeta res = new ModMeta();
|
||||
res.sources = new ModMeta$Sources();
|
||||
if (!Files.isDirectory(mod)) {
|
||||
try {
|
||||
byte[] data = Files.readAllBytes(mod);
|
||||
res.sha1 = HashUtils.sha1(data);
|
||||
res.murmur2 = HashUtils.murmur2(data);
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not read file hash", e);
|
||||
}
|
||||
}
|
||||
res.dependents = new ArrayList<>();
|
||||
res.dependencies = new ArrayList<>();
|
||||
return res;
|
||||
}
|
||||
|
||||
public static ModMeta of(String sha1, Long murmur2, @Nullable ModSource knownSource, String gameVersion) {
|
||||
ModMeta res = new ModMeta();
|
||||
res.sources = new ModMeta$Sources();
|
||||
res.sha1 = sha1;
|
||||
res.murmur2 = murmur2;
|
||||
res.dependents = new ArrayList<>();
|
||||
res.dependencies = new ArrayList<>();
|
||||
if (knownSource != null) res.addSource(knownSource, gameVersion);
|
||||
res.initialize(gameVersion);
|
||||
return res;
|
||||
}
|
||||
|
||||
public void addSource(ModSource source, String gameVersion) {
|
||||
try {
|
||||
// TODO use array access once fixed
|
||||
sources.put(source, source.getUpdate(gameVersion));
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not check " + source.getName() + " for updates", e);
|
||||
Utils.LOGGER.error("Could not check " + source.name + " for updates", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.microsoft;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@GSerializable
|
||||
public class Entitlements {
|
||||
public List<StoreItem> items;
|
||||
public String signature;
|
||||
|
||||
@GSerializable
|
||||
public static class StoreItem {
|
||||
public String name;
|
||||
public String signature;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Entitlements(List<StoreItem> items, String signature) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record StoreItem(String name, String signature) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.microsoft;
|
||||
|
||||
import io.gitlab.jfronny.gson.annotations.SerializedName;
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GPrefer;
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@GSerializable
|
||||
public class OauthTokenResponse {
|
||||
@SerializedName("token_type")
|
||||
public String tokenType;
|
||||
|
||||
@SerializedName("expires_in")
|
||||
public Integer expiresIn;
|
||||
|
||||
@SerializedName("expires_at")
|
||||
public Date expiresAt;
|
||||
|
||||
public String scope;
|
||||
|
||||
@SerializedName("access_token")
|
||||
public String accessToken;
|
||||
|
||||
@SerializedName("refresh_token")
|
||||
public String refreshToken;
|
||||
|
||||
@SerializedName("user_id")
|
||||
public String userId;
|
||||
|
||||
public String foci;
|
||||
|
||||
@GPrefer
|
||||
public OauthTokenResponse(String tokenType, Integer expiresIn, Date expiresAt, String scope, String accessToken, String refreshToken, String userId, String foci) {
|
||||
this.tokenType = tokenType;
|
||||
this.expiresIn = expiresIn;
|
||||
this.expiresAt = expiresAt;
|
||||
this.scope = scope;
|
||||
this.accessToken = accessToken;
|
||||
this.refreshToken = refreshToken;
|
||||
this.userId = userId;
|
||||
this.foci = foci;
|
||||
if (this.expiresAt == null) {
|
||||
this.expiresAt = new Date();
|
||||
this.expiresAt.setTime(this.expiresAt.getTime() + this.expiresIn * 1000);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,27 +1,17 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.microsoft;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@GSerializable
|
||||
public class Profile {
|
||||
public String id;
|
||||
public String name;
|
||||
public List<Skin> skins;
|
||||
public List<Cape> capes;
|
||||
|
||||
@GSerializable
|
||||
public static class Skin {
|
||||
public String id;
|
||||
public String state;
|
||||
public String url;
|
||||
public String variant;
|
||||
public String alias;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Profile(String id, String name, List<Skin> skins, List<Cape> capes) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Skin(String id, String state, String url, String variant, String alias) {
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class Cape {
|
||||
public String id;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Cape(String id) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.microsoft.request;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record LoginRequest(String xtoken, String platform) {
|
||||
}
|
|
@ -1,13 +1,14 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.api.account.request;
|
||||
package io.gitlab.jfronny.inceptum.launcher.model.microsoft.request;
|
||||
|
||||
import io.gitlab.jfronny.gson.annotations.SerializedName;
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
@GSerializable
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record XblTokenRequest(@SerializedName("Properties") Properties properties,
|
||||
@SerializedName("RelyingParty") String relyingParty,
|
||||
@SerializedName("TokenType") String tokenType) {
|
||||
@GSerializable
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Properties(@SerializedName("AuthMethod") String authMethod,
|
||||
@SerializedName("SiteName") String siteName,
|
||||
@SerializedName("RpsTicket") String rpsTicket) {
|
|
@ -1,15 +1,16 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.api.account.request;
|
||||
package io.gitlab.jfronny.inceptum.launcher.model.microsoft.request;
|
||||
|
||||
import io.gitlab.jfronny.gson.annotations.SerializedName;
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@GSerializable
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record XstsTokenRequest(@SerializedName("Properties") Properties properties,
|
||||
@SerializedName("RelyingParty") String relyingParty,
|
||||
@SerializedName("TokenType") String tokenType) {
|
||||
@GSerializable
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Properties(@SerializedName("SandboxId") String sandboxId, @SerializedName("UserTokens") List<String> userTokens) {
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.microsoft;
|
||||
package io.gitlab.jfronny.inceptum.launcher.model.microsoft.response;
|
||||
|
||||
import io.gitlab.jfronny.gson.annotations.SerializedName;
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
//TODO test SerializedName
|
||||
@GSerializable
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record LoginResponse(String username,
|
||||
@SerializedName("access_token") String accessToken,
|
||||
@SerializedName("token_type") String tokenType,
|
|
@ -0,0 +1,39 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.microsoft.response;
|
||||
|
||||
import io.gitlab.jfronny.gson.annotations.SerializedName;
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GPrefer;
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record OauthTokenResponse(
|
||||
@SerializedName("token_type") String tokenType,
|
||||
@SerializedName("expires_in") int expiresIn,
|
||||
@SerializedName("expires_at") Date expiresAt,
|
||||
String scope,
|
||||
@SerializedName("access_token") String accessToken,
|
||||
@SerializedName("refresh_token") String refreshToken,
|
||||
@SerializedName("user_id") String userId,
|
||||
String foci) {
|
||||
@GPrefer
|
||||
public OauthTokenResponse(String tokenType, int expiresIn, Date expiresAt, String scope, String accessToken, String refreshToken, String userId, String foci) {
|
||||
this.tokenType = tokenType;
|
||||
this.expiresIn = expiresIn;
|
||||
this.expiresAt = getExpiresAt(expiresAt, expiresIn);
|
||||
this.scope = scope;
|
||||
this.accessToken = accessToken;
|
||||
this.refreshToken = refreshToken;
|
||||
this.userId = userId;
|
||||
this.foci = foci;
|
||||
}
|
||||
|
||||
private static Date getExpiresAt(Date expiresAt, long expiresIn) {
|
||||
if (expiresAt == null) {
|
||||
expiresAt = new Date();
|
||||
expiresAt.time += expiresIn * 1000;
|
||||
}
|
||||
return expiresAt;
|
||||
}
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.microsoft;
|
||||
package io.gitlab.jfronny.inceptum.launcher.model.microsoft.response;
|
||||
|
||||
import io.gitlab.jfronny.gson.annotations.SerializedName;
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
//TODO test SerializedName
|
||||
@GSerializable
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record XboxLiveAuthResponse(@SerializedName("IssueInstant") Date issueInstant,
|
||||
@SerializedName("NotAfter") Date notAfter,
|
||||
@SerializedName("Token") String token,
|
||||
@SerializedName("DisplayClaims") DisplayClaims displayClaims) {
|
||||
@GSerializable
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record DisplayClaims(List<XUIClaim> xui) {
|
||||
@GSerializable
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record XUIClaim(String uhs) {
|
||||
}
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.modrinth;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
@GSerializable
|
||||
public class ModrinthHashes { //TODO ensure this can parse with additional hashes
|
||||
public String sha1;
|
||||
public String sha512;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record ModrinthHashes(String sha1, String sha512) {
|
||||
}
|
||||
|
|
|
@ -2,39 +2,33 @@ package io.gitlab.jfronny.inceptum.launcher.model.modrinth;
|
|||
|
||||
import io.gitlab.jfronny.gson.annotations.SerializedName;
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@GSerializable
|
||||
public class ModrinthModpackManifest {
|
||||
public Integer formatVersion; // 1
|
||||
public String game; // "minecraft"
|
||||
public String versionId;
|
||||
public String name;
|
||||
public String summary; // optional
|
||||
public List<File> files;
|
||||
public Dependencies dependencies;
|
||||
|
||||
@GSerializable
|
||||
public static class File {
|
||||
public String path;
|
||||
public ModrinthHashes hashes;
|
||||
public Env env; // optional
|
||||
public List<String> downloads;
|
||||
public Long fileSize;
|
||||
|
||||
@GSerializable
|
||||
public static class Env {
|
||||
public ModrinthDependencyType client;
|
||||
public ModrinthDependencyType server;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record ModrinthModpackManifest(
|
||||
int formatVersion, // 1
|
||||
String game, // "minecraft"
|
||||
String versionId,
|
||||
String name,
|
||||
String summary,
|
||||
List<File> files,
|
||||
Dependencies dependencies
|
||||
) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record File(String path, ModrinthHashes hashes, @Nullable Env env, List<String> downloads, long fileSize) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Env(ModrinthDependencyType client, ModrinthDependencyType server) {
|
||||
}
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class Dependencies { // All are nullable
|
||||
public String minecraft;
|
||||
public String forge;
|
||||
@SerializedName("fabric-loader") public String fabricLoader;
|
||||
@SerializedName("quilt-loader") public String quiltLoader;
|
||||
// All are nullable
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Dependencies(String minecraft,
|
||||
String forge,
|
||||
@SerializedName("fabric-loader") String fabricLoader,
|
||||
@SerializedName("quilt-loader") String quiltLoader) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,58 +1,48 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.modrinth;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@GSerializable
|
||||
public class ModrinthProject {
|
||||
public String id;
|
||||
public String slug;
|
||||
public ModrinthProjectType project_type;
|
||||
public String team;
|
||||
public String title;
|
||||
public String description;
|
||||
public String body;
|
||||
public String body_url;
|
||||
public Date publish;
|
||||
public Date updated;
|
||||
public String status;
|
||||
public License license;
|
||||
public ModrinthDependencyType client_side;
|
||||
public ModrinthDependencyType server_side;
|
||||
public Long downloads;
|
||||
public Long follows;
|
||||
public List<String> categories;
|
||||
public List<String> versions;
|
||||
public String icon_url;
|
||||
public String issues_url;
|
||||
public String source_url;
|
||||
public String wiki_url;
|
||||
public String discord_url;
|
||||
public List<DonationUrl> donation_urls;
|
||||
public List<GalleryItem> gallery;
|
||||
|
||||
@GSerializable
|
||||
public static class DonationUrl {
|
||||
public String id;
|
||||
public String platform;
|
||||
public String url;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record ModrinthProject(
|
||||
String id,
|
||||
String slug,
|
||||
ModrinthProjectType project_type,
|
||||
String team,
|
||||
String title,
|
||||
String description,
|
||||
String body,
|
||||
String body_url,
|
||||
Date publish,
|
||||
Date updated,
|
||||
String status,
|
||||
License license,
|
||||
ModrinthDependencyType client_side,
|
||||
ModrinthDependencyType server_side,
|
||||
long downloads,
|
||||
long follows,
|
||||
List<String> categories,
|
||||
List<String> versions,
|
||||
String icon_url,
|
||||
String issues_url,
|
||||
String source_url,
|
||||
String wiki_url,
|
||||
String discord_url,
|
||||
List<DonationUrl> donation_urls,
|
||||
List<GalleryItem> gallery
|
||||
) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record DonationUrl(String id, String platform, String url) {
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class License {
|
||||
public String id;
|
||||
public String name;
|
||||
public String url;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record License(String id, String name, String url) {
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class GalleryItem {
|
||||
public String url;
|
||||
public Boolean featured;
|
||||
public String title;
|
||||
public String description;
|
||||
public Date created;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record GalleryItem(String url, boolean featured, String title, String description, Date created) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,36 +1,33 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.modrinth;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@GSerializable
|
||||
public class ModrinthSearchResult {
|
||||
public List<ModResult> hits;
|
||||
public Integer offset;
|
||||
public Integer limit;
|
||||
public Integer total_hits;
|
||||
|
||||
@GSerializable
|
||||
public static class ModResult {
|
||||
public String project_id;
|
||||
public ModrinthProjectType project_type;
|
||||
public String slug;
|
||||
public String author;
|
||||
public String title;
|
||||
public String description;
|
||||
public List<String> categories;
|
||||
public List<String> versions;
|
||||
public Long downloads;
|
||||
public Long follows;
|
||||
public String icon_url;
|
||||
public Date date_created;
|
||||
public Date date_modified;
|
||||
public String latest_version;
|
||||
public String license;
|
||||
public String client_side;
|
||||
public String server_side;
|
||||
public List<String> gallery;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record ModrinthSearchResult(List<ModResult> hits, int offset, int limit, int total_hits) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record ModResult(
|
||||
String project_id,
|
||||
ModrinthProjectType project_type,
|
||||
String slug,
|
||||
String author,
|
||||
String title,
|
||||
String description,
|
||||
List<String> categories,
|
||||
List<String> versions,
|
||||
long downloads,
|
||||
long follows,
|
||||
String icon_url,
|
||||
Date date_created,
|
||||
Date date_modified,
|
||||
String latest_version,
|
||||
String license,
|
||||
String client_side,
|
||||
String server_side,
|
||||
List<String> gallery
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,46 +1,39 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.modrinth;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@GSerializable
|
||||
public class ModrinthVersion {
|
||||
public String id;
|
||||
public String project_id;
|
||||
public String author_id;
|
||||
public Boolean featured;
|
||||
public String name;
|
||||
public String version_number;
|
||||
public String changelog;
|
||||
public String changelog_url;
|
||||
public Date date_published;
|
||||
public Long downloads;
|
||||
public VersionType version_type;
|
||||
public List<File> files;
|
||||
public List<Dependency> dependencies;
|
||||
public List<String> game_versions;
|
||||
public List<String> loaders;
|
||||
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record ModrinthVersion(
|
||||
String id,
|
||||
String project_id,
|
||||
String author_id,
|
||||
boolean featured,
|
||||
String name,
|
||||
String version_number,
|
||||
String changelog,
|
||||
String changelog_url,
|
||||
Date date_published,
|
||||
long downloads,
|
||||
VersionType version_type,
|
||||
List<File> files,
|
||||
List<Dependency> dependencies,
|
||||
List<String> game_versions,
|
||||
List<String> loaders
|
||||
) {
|
||||
public enum VersionType {
|
||||
alpha, beta, release
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class File {
|
||||
public ModrinthHashes hashes;
|
||||
public String url;
|
||||
public String filename;
|
||||
public Boolean primary;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record File(ModrinthHashes hashes, String url, String filename, boolean primary) {
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class Dependency {
|
||||
public String version_id;
|
||||
public String project_id;
|
||||
public DependencyType dependency_type;
|
||||
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Dependency(String version_id, String project_id, DependencyType dependency_type) {
|
||||
public enum DependencyType {
|
||||
required,
|
||||
optional,
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.mojang;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@GSerializable
|
||||
public class AssetIndex {
|
||||
public Map<String, Asset> objects;
|
||||
|
||||
@GSerializable
|
||||
public static class Asset {
|
||||
public String hash;
|
||||
public int size;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record AssetIndex(Map<String, Asset> objects) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Asset(String hash, int size) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,16 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.mojang;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@GSerializable
|
||||
public class JvmFileInfo {
|
||||
public Map<String, File> files;
|
||||
|
||||
@GSerializable
|
||||
public static class File {
|
||||
public Downloads downloads;
|
||||
public boolean executable;
|
||||
public String type;
|
||||
|
||||
@GSerializable
|
||||
public static class Downloads {
|
||||
public MojangFileDownload lzma;
|
||||
public MojangFileDownload raw;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record JvmFileInfo(Map<String, File> files) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record File(Downloads downloads, boolean executable, String type) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Downloads(MojangFileDownload lzma, MojangFileDownload raw) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,34 +2,23 @@ package io.gitlab.jfronny.inceptum.launcher.model.mojang;
|
|||
|
||||
import io.gitlab.jfronny.gson.annotations.SerializedName;
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@GSerializable
|
||||
public class JvmInfo {
|
||||
public Map<String, List<Jvm>> linux;
|
||||
@SerializedName("mac-os")
|
||||
public Map<String, List<Jvm>> macOs;
|
||||
@SerializedName("windows-x64")
|
||||
public Map<String, List<Jvm>> windowsX64;
|
||||
|
||||
@GSerializable
|
||||
public static class Jvm {
|
||||
public Availability availability;
|
||||
public MojangFileDownload manifest;
|
||||
public Version version;
|
||||
|
||||
@GSerializable
|
||||
public static class Availability {
|
||||
public int group;
|
||||
public int progress;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record JvmInfo(Map<String, List<Jvm>> linux,
|
||||
@SerializedName("mac-os") Map<String, List<Jvm>> macOs,
|
||||
@SerializedName("windows-x64") Map<String, List<Jvm>> windowsX64) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Jvm(Availability availability, MojangFileDownload manifest, Version version) {
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Availability(int group, int progress) {
|
||||
}
|
||||
|
||||
@GSerializable
|
||||
public static class Version {
|
||||
public String name;
|
||||
public String released;
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public record Version(String name, String released) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package io.gitlab.jfronny.inceptum.launcher.model.mojang;
|
||||
|
||||
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
||||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
import io.gitlab.jfronny.inceptum.launcher.gson.MinecraftArgumentAdapter;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@GSerializable(with = MinecraftArgumentAdapter.class)
|
||||
@GSerializable(with = MinecraftArgumentAdapter.class, configure = GsonPreset.Api.class)
|
||||
public record MinecraftArgument(Set<String> arg) implements Cloneable {
|
||||
@Override
|
||||
protected MinecraftArgument clone() {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue