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