Close Files.list streams, don't block for mods dir scan
This commit is contained in:
parent
0ac146e3ab
commit
e6e6c5822f
|
@ -3,4 +3,5 @@
|
|||
build/
|
||||
run/
|
||||
imgui.ini
|
||||
hs_err_pid*
|
||||
hs_err_pid*
|
||||
inceptum.log
|
|
@ -30,7 +30,7 @@ public class Steps {
|
|||
);
|
||||
|
||||
public static void reDownload() throws IOException {
|
||||
Files.list(Inceptum.INSTANCE_DIR).forEach(p -> {
|
||||
Utils.ls(Inceptum.INSTANCE_DIR, p -> {
|
||||
try {
|
||||
reDownload(p);
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -43,7 +43,7 @@ public class DownloadLibrariesStep implements Step {
|
|||
currentState.set("Extracting natives");
|
||||
Inceptum.LOGGER.info(currentState.get());
|
||||
try (FileSystem libFs = Utils.openZipFile(path, false)) {
|
||||
for (Path path1 : Files.list(libFs.getPath(".")).toList()) {
|
||||
for (Path path1 : Utils.ls(libFs.getPath("."))) {
|
||||
Utils.copyRecursive(path1, Inceptum.NATIVES_DIR.resolve(InstanceMeta.getMinecraftVersion(version.id)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,13 +18,16 @@ public class SetupDirsStep implements Step {
|
|||
Path iDir = Inceptum.INSTANCE_DIR.resolve(info.name());
|
||||
if (!Files.exists(iDir)) {
|
||||
Files.createDirectories(iDir.resolve("inceptum.setup.lock"));
|
||||
Files.createDirectories(iDir.resolve("config"));
|
||||
if (info.loader().type() != LoaderInfo.Type.None)
|
||||
Files.createDirectories(iDir.resolve("mods"));
|
||||
Files.createDirectories(iDir.resolve("resourcepacks"));
|
||||
Files.createDirectories(iDir.resolve("saves"));
|
||||
Files.createDirectories(iDir.resolve("screenshots"));
|
||||
}
|
||||
if (info.loader().type() != LoaderInfo.Type.None) {
|
||||
if (!Files.exists(iDir.resolve("mods")))
|
||||
Files.createDirectories(iDir.resolve("mods"));
|
||||
if (!Files.exists(iDir.resolve("config")))
|
||||
Files.createDirectories(iDir.resolve("config"));
|
||||
}
|
||||
Files.createDirectories(Inceptum.NATIVES_DIR.resolve(InstanceMeta.getMinecraftVersion(info.version().id)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ public final class CurseforgeModSource implements ModSource {
|
|||
|
||||
@Override
|
||||
public ModDownload download(Path modsDir) throws IOException {
|
||||
//TODO test
|
||||
//TODO this doesn't work
|
||||
Path path = modsDir.resolve(current.fileName);
|
||||
Utils.downloadFile(current.downloadUrl.replace("edge.forgecdn.net", "media.forgecdn.net"), path);
|
||||
byte[] data = Files.readAllBytes(path);
|
||||
|
|
|
@ -98,39 +98,37 @@ public class HttpUtils {
|
|||
return this;
|
||||
}
|
||||
|
||||
private <T> T _send(String accept, HttpResponse.BodyHandler<T> responseBodyHandler) {
|
||||
private <T> T _send(String accept, HttpResponse.BodyHandler<T> responseBodyHandler) throws IOException {
|
||||
builder.header("Accept", accept);
|
||||
if (method != null) builder.method(method.name(), HttpRequest.BodyPublishers.noBody());
|
||||
|
||||
HttpResponse<T> res;
|
||||
try {
|
||||
var res = CLIENT.send(builder.build(), responseBodyHandler);
|
||||
if (res.statusCode() == 200) return res.body();
|
||||
Inceptum.LOGGER.error("Unexpected return method: " + res.statusCode() + " (URL=" + url + ")");
|
||||
Inceptum.LOGGER.error(getString(res.body()));
|
||||
return null;
|
||||
} catch (IOException | InterruptedException e) {
|
||||
Inceptum.LOGGER.error("Could not send request", e);
|
||||
return null;
|
||||
res = CLIENT.send(builder.build(), responseBodyHandler);
|
||||
} catch (InterruptedException e) {
|
||||
throw new IOException("Could not send request", e);
|
||||
}
|
||||
if (res.statusCode() == 200) return res.body();
|
||||
throw new IOException("Unexpected return method: " + res.statusCode() + " (URL=" + url + ")\n" + res.body());
|
||||
}
|
||||
|
||||
public void send() {
|
||||
public void send() throws IOException {
|
||||
_send("*/*", HttpResponse.BodyHandlers.discarding());
|
||||
}
|
||||
|
||||
public InputStream sendInputStream() {
|
||||
public InputStream sendInputStream() throws IOException {
|
||||
return _send("*/*", HttpResponse.BodyHandlers.ofInputStream());
|
||||
}
|
||||
|
||||
public String sendString() {
|
||||
public String sendString() throws IOException {
|
||||
return _send("*/*", HttpResponse.BodyHandlers.ofString());
|
||||
}
|
||||
|
||||
public Stream<String> sendLines() {
|
||||
public Stream<String> sendLines() throws IOException {
|
||||
return _send("*/*", HttpResponse.BodyHandlers.ofLines());
|
||||
}
|
||||
|
||||
public <T> T sendJson(Type type) {
|
||||
public <T> T sendJson(Type type) throws IOException {
|
||||
InputStream in = _send("application/json", HttpResponse.BodyHandlers.ofInputStream());
|
||||
return in == null ? null : Inceptum.GSON.fromJson(new InputStreamReader(in), type);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
package io.gitlab.jfronny.inceptum.util;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.model.fabric.FabricModJson;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.ModDescription;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
public class ModsDirScanner implements Closeable {
|
||||
private final Map<Path, IWModDescription> descriptions = new HashMap<>();
|
||||
private final Thread th;
|
||||
private final Path modsDir;
|
||||
private final InstanceMeta instance;
|
||||
private boolean disposed = false;
|
||||
|
||||
public ModsDirScanner(Path modsDir, InstanceMeta instance) {
|
||||
this.modsDir = modsDir;
|
||||
this.instance = instance;
|
||||
th = new Thread(this::scanTaskInternal);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
th.start();
|
||||
}
|
||||
|
||||
public Set<IWModDescription> getMods() throws IOException {
|
||||
Set<IWModDescription> mods = new LinkedHashSet<>();
|
||||
if (Files.isDirectory(modsDir)) {
|
||||
for (Path path : Utils.ls(modsDir)) {
|
||||
if (!path.toString().endsWith(".imod"))
|
||||
mods.add(get(path));
|
||||
}
|
||||
}
|
||||
return mods;
|
||||
}
|
||||
|
||||
public IWModDescription get(Path path) {
|
||||
if (descriptions.containsKey(path))
|
||||
return descriptions.get(path);
|
||||
else {
|
||||
// not yet scanned
|
||||
return new IWModDescription(path);
|
||||
}
|
||||
}
|
||||
|
||||
private void scanTaskInternal() {
|
||||
while (!disposed) {
|
||||
try {
|
||||
if (!Files.isDirectory(modsDir)) {
|
||||
Thread.sleep(5000);
|
||||
continue;
|
||||
}
|
||||
for (Path mods : Utils.ls(modsDir)) {
|
||||
if (Files.isDirectory(mods)) {
|
||||
descriptions.put(mods, new IWModDescription(mods));
|
||||
} else {
|
||||
if (mods.toString().endsWith(".jar")) {
|
||||
Optional<Path> imod = Optional.of(mods.getParent().resolve(mods.getFileName() + ".imod"));
|
||||
// fabric.mod.json
|
||||
Optional<FabricModJson> fmj;
|
||||
try (FileSystem fs = Utils.openZipFile(mods, false)) {
|
||||
fmj = Files.exists(fs.getPath("fabric.mod.json"))
|
||||
? Optional.of(Utils.loadObject(fs.getPath("fabric.mod.json"), FabricModJson.class))
|
||||
: Optional.empty();
|
||||
}
|
||||
// mod description
|
||||
Optional<ModDescription> md = Optional.empty();
|
||||
//TODO attempt to compare versions across sources
|
||||
Optional<ModSource> update = Optional.empty();
|
||||
if (Files.exists(imod.get())) {
|
||||
try (FileSystem fs = Utils.openZipFile(mods, false)) {
|
||||
md = Optional.of(Utils.loadObject(imod.get(), ModDescription.class));
|
||||
for (ModSource source : md.get().sources) {
|
||||
Optional<ModSource> ms = source.getUpdate(instance.getMinecraftVersion());
|
||||
if (ms.isEmpty()) continue;
|
||||
if (update.isEmpty()) update = ms;
|
||||
}
|
||||
}
|
||||
}
|
||||
else imod = Optional.empty();
|
||||
descriptions.put(mods, new IWModDescription(mods, md, fmj, imod, update));
|
||||
}
|
||||
else if (!mods.toString().endsWith(".imod")) {
|
||||
descriptions.put(mods, new IWModDescription(mods));
|
||||
}
|
||||
}
|
||||
}
|
||||
Thread.sleep(100);
|
||||
} catch (IOException | URISyntaxException | InterruptedException e) {
|
||||
Inceptum.LOGGER.error("Could not list mods", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
public static record IWModDescription(Path path, Optional<ModDescription> mod, Optional<FabricModJson> fmj, Optional<Path> imod, Optional<ModSource> update) {
|
||||
public String getName() {
|
||||
if (fmj.isEmpty()) return path.getFileName().toString();
|
||||
String base;
|
||||
if (fmj.get().name != null) base = fmj.get().name;
|
||||
else if (fmj.get().id != null) base = fmj.get().id;
|
||||
else {
|
||||
base = path.getFileName().toString();
|
||||
if (Files.isDirectory(path))
|
||||
base += '/';
|
||||
}
|
||||
if (fmj.get().version != null) base += ' ' + fmj.get().version;
|
||||
return base;
|
||||
}
|
||||
|
||||
public String[] getDescription() {
|
||||
try {
|
||||
if (fmj.isPresent() && fmj.get().description != null) {
|
||||
return fmj.get().description.split("\n");
|
||||
}
|
||||
else if (Files.isDirectory(path)) {
|
||||
return Utils.lsVi(path);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Inceptum.LOGGER.error("Could not get description", e);
|
||||
}
|
||||
return new String[] {"No description is available", "This mod may have been added manually"};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a description with only the path and no additional information
|
||||
* @param path The path of the mod entry
|
||||
*/
|
||||
public IWModDescription(Path path) {
|
||||
this(path, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ package io.gitlab.jfronny.inceptum.util;
|
|||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.model.OSType;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Desktop;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URI;
|
||||
|
@ -14,9 +14,13 @@ import java.nio.file.FileSystem;
|
|||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Utils {
|
||||
public static final Pattern VALID_FILENAME = Pattern.compile("[a-zA-Z0-9_\\-.][a-zA-Z0-9 _\\-.]*[a-zA-Z0-9_\\-.]");
|
||||
|
@ -107,7 +111,7 @@ public class Utils {
|
|||
public static void clearDirectory(Path path) throws IOException {
|
||||
if (!Files.exists(path)) return;
|
||||
try {
|
||||
Files.list(path).forEach(p -> {
|
||||
Utils.ls(path, p -> {
|
||||
if (Files.isDirectory(p)) {
|
||||
try {
|
||||
deleteRecursive(p);
|
||||
|
@ -129,23 +133,26 @@ public class Utils {
|
|||
}
|
||||
|
||||
public static void deleteRecursive(Path path) throws IOException {
|
||||
Files.walkFileTree(path, new SimpleFileVisitor<>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
FileVisitResult fv = super.visitFile(file, attrs);
|
||||
if (fv != FileVisitResult.CONTINUE) return fv;
|
||||
Files.delete(file);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
if (Files.isDirectory(path)) {
|
||||
Files.walkFileTree(path, new SimpleFileVisitor<>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
FileVisitResult fv = super.visitFile(file, attrs);
|
||||
if (fv != FileVisitResult.CONTINUE) return fv;
|
||||
Files.delete(file);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
||||
FileVisitResult fv = super.postVisitDirectory(dir, exc);
|
||||
if (fv != FileVisitResult.CONTINUE) return fv;
|
||||
Files.delete(dir);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
||||
FileVisitResult fv = super.postVisitDirectory(dir, exc);
|
||||
if (fv != FileVisitResult.CONTINUE) return fv;
|
||||
Files.delete(dir);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
}
|
||||
else Files.delete(path);
|
||||
}
|
||||
|
||||
public static void copyRecursive(Path source, Path destination) throws IOException {
|
||||
|
@ -155,7 +162,7 @@ public class Utils {
|
|||
public static void copyRecursive(Path source, Path destination, CopyOption... copyOptions) throws IOException {
|
||||
if (!Files.exists(destination)) Files.createDirectories(destination);
|
||||
if(Files.isDirectory(source)) {
|
||||
Files.list(source).forEach(sourcePath -> {
|
||||
Utils.ls(source, sourcePath -> {
|
||||
try {
|
||||
copyRecursive(sourcePath, destination.resolve(sourcePath.getFileName().toString()), copyOptions);
|
||||
} catch (IOException e) {
|
||||
|
@ -176,7 +183,7 @@ public class Utils {
|
|||
public static void openWebBrowser(URI uri) {
|
||||
try {
|
||||
if (OSCheck.OS == OSType.LINUX && JvmUtils.executableInPath("xdg-open")) {
|
||||
Runtime.getRuntime().exec("xdg-open " + uri);
|
||||
Runtime.getRuntime().exec(new String[]{"xdg-open", uri.toString()});
|
||||
} else if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
|
||||
Desktop.getDesktop().browse(uri);
|
||||
}
|
||||
|
@ -185,6 +192,42 @@ public class Utils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void openFile(File file) {
|
||||
try {
|
||||
if (OSCheck.OS == OSType.LINUX && JvmUtils.executableInPath("xdg-open")) {
|
||||
Runtime.getRuntime().exec(new String[]{"xdg-open", file.getAbsoluteFile().toString()});
|
||||
} else if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
|
||||
Desktop.getDesktop().open(file);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Inceptum.LOGGER.error("Error opening web browser!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Path> ls(Path dir) throws IOException {
|
||||
try (Stream<Path> sp = Files.list(dir)) {
|
||||
return sp.toList();
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] lsVi(Path dir) throws IOException {
|
||||
try (Stream<Path> sp = Files.list(dir)) {
|
||||
return sp.map(p -> Files.isDirectory(p) ? p.getFileName().toString() + "/" : p.getFileName().toString()).toArray(String[]::new);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Path> ls(Path dir, Predicate<Path> predicate) throws IOException {
|
||||
try (Stream<Path> sp = Files.list(dir); Stream<Path> fi = sp.filter(predicate)) {
|
||||
return fi.toList();
|
||||
}
|
||||
}
|
||||
|
||||
public static void ls(Path dir, Consumer<Path> consumer) throws IOException {
|
||||
try (Stream<Path> sp = Files.list(dir)) {
|
||||
sp.forEach(consumer);
|
||||
}
|
||||
}
|
||||
|
||||
public static FileSystem openZipFile(Path zip, boolean create) throws IOException, URISyntaxException {
|
||||
URI fileUri = zip.toUri();
|
||||
return FileSystems.newFileSystem(new URI("jar:" + fileUri.getScheme(), fileUri.getPath(), null), create ? Map.of("create", "true") : Map.of());
|
||||
|
|
|
@ -39,7 +39,7 @@ public class CurseforgeApi {
|
|||
return Utils.downloadObject(API_URL + "addon/" + modId + "/file/" + fileId, CurseforgeFile.class);
|
||||
}
|
||||
|
||||
public static CurseforgeFingerprint checkFingerprint(String hash) {
|
||||
public static CurseforgeFingerprint checkFingerprint(String hash) throws IOException {
|
||||
return HttpUtils.post(API_URL + "fingerprint").bodyJson("[" + hash + "]").sendJson(CurseforgeFingerprint.class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ import io.gitlab.jfronny.inceptum.model.microsoft.LoginResponse;
|
|||
import io.gitlab.jfronny.inceptum.model.microsoft.OauthTokenResponse;
|
||||
import io.gitlab.jfronny.inceptum.model.microsoft.Profile;
|
||||
import io.gitlab.jfronny.inceptum.model.microsoft.XboxLiveAuthResponse;
|
||||
import io.gitlab.jfronny.inceptum.windows.AlertWindow;
|
||||
import io.gitlab.jfronny.inceptum.windows.MicrosoftLoginWindow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
|
@ -88,31 +88,24 @@ public class MicrosoftAccount {
|
|||
return accessToken;
|
||||
}
|
||||
|
||||
public String getCurrentUsername() {
|
||||
public String getCurrentUsername() throws IOException {
|
||||
Profile profile = MicrosoftAuthAPI.getMcProfile(accessToken);
|
||||
|
||||
if (profile == null) {
|
||||
Inceptum.LOGGER.error("Error getting Minecraft profile");
|
||||
return null;
|
||||
}
|
||||
|
||||
return Optional.of(profile.name).orElse(null);
|
||||
if (profile.name == null) throw new IOException("Got null name");
|
||||
return profile.name;
|
||||
}
|
||||
|
||||
public void updateSkinPreCheck() {
|
||||
this.refreshAccessToken();
|
||||
}
|
||||
|
||||
public String getSkinUrl() {
|
||||
public String getSkinUrl() throws IOException {
|
||||
Profile profile = MicrosoftAuthAPI.getMcProfile(accessToken);
|
||||
|
||||
if (profile == null) {
|
||||
Inceptum.LOGGER.error("Error getting Minecraft profile");
|
||||
return null;
|
||||
}
|
||||
|
||||
return Optional.of(profile.skins).orElse(new ArrayList<>()).stream()
|
||||
.filter(s -> s.state.equalsIgnoreCase("ACTIVE")).findFirst().map(s -> s.url).orElse(null);
|
||||
return Optional.of(profile.skins).orElse(new ArrayList<>())
|
||||
.stream()
|
||||
.filter(s -> s.state.equalsIgnoreCase("ACTIVE"))
|
||||
.findFirst()
|
||||
.map(s -> s.url)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public boolean refreshAccessToken() {
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.gitlab.jfronny.inceptum.util.api.account;
|
|||
import io.gitlab.jfronny.inceptum.model.microsoft.*;
|
||||
import io.gitlab.jfronny.inceptum.util.HttpUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -28,7 +29,7 @@ public class MicrosoftAuthAPI {
|
|||
public static final String MICROSOFT_MINECRAFT_STORE_URL = "https://api.minecraftservices.com/entitlements/mcstore";
|
||||
public static final String MICROSOFT_MINECRAFT_PROFILE_URL = "https://api.minecraftservices.com/minecraft/profile";
|
||||
|
||||
public static OauthTokenResponse tradeCodeForAccessToken(String code) {
|
||||
public static OauthTokenResponse tradeCodeForAccessToken(String code) throws IOException {
|
||||
return HttpUtils.post(MICROSOFT_AUTH_TOKEN_URL)
|
||||
.bodyForm(Map.of("client_id", MICROSOFT_LOGIN_CLIENT_ID,
|
||||
"code", code,
|
||||
|
@ -38,7 +39,7 @@ public class MicrosoftAuthAPI {
|
|||
.sendJson(OauthTokenResponse.class);
|
||||
}
|
||||
|
||||
public static OauthTokenResponse refreshAccessToken(String refreshToken) {
|
||||
public static OauthTokenResponse refreshAccessToken(String refreshToken) throws IOException {
|
||||
return HttpUtils.post(MICROSOFT_AUTH_TOKEN_URL)
|
||||
.bodyForm(Map.of("client_id", MICROSOFT_LOGIN_CLIENT_ID,
|
||||
"refresh_token", refreshToken,
|
||||
|
@ -47,7 +48,7 @@ public class MicrosoftAuthAPI {
|
|||
.sendJson(OauthTokenResponse.class);
|
||||
}
|
||||
|
||||
public static XboxLiveAuthResponse getXBLToken(String accessToken) {
|
||||
public static XboxLiveAuthResponse getXBLToken(String accessToken) throws IOException {
|
||||
Map<Object, Object> properties = new HashMap<>();
|
||||
properties.put("AuthMethod", "RPS");
|
||||
properties.put("SiteName", "user.auth.xboxlive.com");
|
||||
|
@ -64,7 +65,7 @@ public class MicrosoftAuthAPI {
|
|||
.sendJson(XboxLiveAuthResponse.class);
|
||||
}
|
||||
|
||||
public static XboxLiveAuthResponse getXstsToken(String xblToken) {
|
||||
public static XboxLiveAuthResponse getXstsToken(String xblToken) throws IOException {
|
||||
Map<Object, Object> properties = new HashMap<>();
|
||||
properties.put("SandboxId", "RETAIL");
|
||||
|
||||
|
@ -83,7 +84,7 @@ public class MicrosoftAuthAPI {
|
|||
.sendJson(XboxLiveAuthResponse.class);
|
||||
}
|
||||
|
||||
public static LoginResponse loginToMinecraft(String xstsToken) {
|
||||
public static LoginResponse loginToMinecraft(String xstsToken) throws IOException {
|
||||
Map<Object, Object> data = new HashMap<Object, Object>();
|
||||
data.put("identityToken", xstsToken);
|
||||
|
||||
|
@ -92,11 +93,11 @@ public class MicrosoftAuthAPI {
|
|||
.sendJson(LoginResponse.class);
|
||||
}
|
||||
|
||||
public static Store getMcEntitlements(String accessToken) {
|
||||
public static Store getMcEntitlements(String accessToken) throws IOException {
|
||||
return HttpUtils.get(MICROSOFT_MINECRAFT_STORE_URL).bearer(accessToken).sendJson(Store.class);
|
||||
}
|
||||
|
||||
public static Profile getMcProfile(String accessToken) {
|
||||
public static Profile getMcProfile(String accessToken) throws IOException {
|
||||
return HttpUtils.get(MICROSOFT_MINECRAFT_PROFILE_URL).bearer(accessToken).sendJson(Profile.class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
|
|||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModrinthModSource;
|
||||
import io.gitlab.jfronny.inceptum.model.modrinth.ModrinthSearchResult;
|
||||
import io.gitlab.jfronny.inceptum.model.modrinth.ModrinthVersion;
|
||||
import io.gitlab.jfronny.inceptum.util.ModsDirScanner;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.util.api.CurseforgeApi;
|
||||
import io.gitlab.jfronny.inceptum.util.api.ModrinthApi;
|
||||
|
@ -24,21 +25,20 @@ import java.net.URISyntaxException;
|
|||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AddModWindow extends Window {
|
||||
private final ImString query = new ImString("", 128);
|
||||
private final Path modsDir;
|
||||
private final InstanceMeta instance;
|
||||
private final Map<Path, InstanceEditWindow.IWModDescription> descriptions;
|
||||
private final ModsDirScanner mds;
|
||||
private int page = 0;
|
||||
private ModrinthSearchResult mr = null;
|
||||
private List<CurseforgeMod> cf = null;
|
||||
public AddModWindow(Path modsDir, InstanceMeta instance, Map<Path, InstanceEditWindow.IWModDescription> descriptions) {
|
||||
public AddModWindow(Path modsDir, InstanceMeta instance, ModsDirScanner mds) {
|
||||
super(modsDir.getParent().getFileName().toString() + " - Add Mods");
|
||||
this.modsDir = modsDir;
|
||||
this.instance = instance;
|
||||
this.descriptions = descriptions;
|
||||
this.mds = mds;
|
||||
}
|
||||
|
||||
private void refreshMR() throws IOException {
|
||||
|
@ -103,7 +103,8 @@ public class AddModWindow extends Window {
|
|||
Inceptum.showError("No valid version could be identified for this mod", "No version found");
|
||||
}
|
||||
else {
|
||||
download(new ModrinthModSource(latest.id), modsDir, descriptions).write();
|
||||
//TODO don't block
|
||||
download(new ModrinthModSource(latest.id), modsDir, mds).write();
|
||||
}
|
||||
}
|
||||
ImGui.sameLine();
|
||||
|
@ -136,7 +137,8 @@ public class AddModWindow extends Window {
|
|||
Inceptum.showError("No valid version could be identified for this mod", "No version found");
|
||||
}
|
||||
else {
|
||||
download(new CurseforgeModSource(mod.id, latest.projectFileId), modsDir, descriptions).write();
|
||||
//TODO don't block
|
||||
download(new CurseforgeModSource(mod.id, latest.projectFileId), modsDir, mds).write();
|
||||
}
|
||||
}
|
||||
ImGui.sameLine();
|
||||
|
@ -156,11 +158,12 @@ public class AddModWindow extends Window {
|
|||
}
|
||||
}
|
||||
|
||||
public static DownloadMeta download(ModSource ms, Path modsDir, Map<Path, InstanceEditWindow.IWModDescription> descriptions) throws IOException {
|
||||
for (InstanceEditWindow.IWModDescription value : descriptions.values()) {
|
||||
for (ModSource source : value.mod().sources) {
|
||||
public static DownloadMeta download(ModSource ms, Path modsDir, ModsDirScanner mds) throws IOException {
|
||||
for (ModsDirScanner.IWModDescription value : mds.getMods()) {
|
||||
if (value.mod().isEmpty()) continue;
|
||||
for (ModSource source : value.mod().get().sources) {
|
||||
if (ms.equals(source)) {
|
||||
return new DownloadMeta(new ModDownload(value.mod().sha1, value.mod().murmur2, value.path()), value.mod(), source);
|
||||
return new DownloadMeta(new ModDownload(value.mod().get().sha1, value.mod().get().murmur2, value.path()), value.mod().get(), source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +196,7 @@ public class AddModWindow extends Window {
|
|||
manifest.dependents = new ArrayList<>();
|
||||
manifest.dependencies = new ArrayList<>();
|
||||
for (ModSource dependency : ms.getDependencies()) {
|
||||
DownloadMeta depMan = download(dependency, modsDir, descriptions);
|
||||
DownloadMeta depMan = download(dependency, modsDir, mds);
|
||||
depMan.description.dependents.add(md.file().getFileName().toString());
|
||||
manifest.dependencies.add(depMan.download.file().getFileName().toString());
|
||||
depMan.write();
|
||||
|
|
|
@ -6,22 +6,15 @@ import imgui.type.ImString;
|
|||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.InceptumGui;
|
||||
import io.gitlab.jfronny.inceptum.install.Steps;
|
||||
import io.gitlab.jfronny.inceptum.model.fabric.FabricModJson;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.ModDescription;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.JvmUtils;
|
||||
import io.gitlab.jfronny.inceptum.util.ModsDirScanner;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.windows.control.InstanceManageControls;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class InstanceEditWindow extends Window {
|
||||
private final Path path;
|
||||
|
@ -29,34 +22,27 @@ public class InstanceEditWindow extends Window {
|
|||
private final InstanceManageControls imc;
|
||||
private final ImBoolean customJava;
|
||||
private final ImString customJavaPath = new ImString(128);
|
||||
private final Map<Path, IWModDescription> descriptions = new HashMap<>();
|
||||
private final ModsDirScanner mds;
|
||||
private Path selected = null;
|
||||
private boolean reDownload = false;
|
||||
|
||||
public static record IWModDescription(ModDescription mod, FabricModJson fmj, Path path, Path imod, Optional<ModSource> update) {
|
||||
public String getName() {
|
||||
if (fmj == null) return path.getFileName().toString();
|
||||
String base;
|
||||
if (fmj.name != null) base = fmj.name;
|
||||
else if (fmj.id != null) base = fmj.id;
|
||||
else base = path.getFileName().toString();
|
||||
if (fmj.version != null) base += ' ' + fmj.version;
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
public InstanceEditWindow(Path path, InstanceMeta instance) {
|
||||
super(path.getFileName().toString() + " - Edit");
|
||||
this.path = path;
|
||||
this.instance = instance;
|
||||
mds = new ModsDirScanner(path.resolve("mods"), instance);
|
||||
mds.start();
|
||||
customJava = new ImBoolean(instance.java != null);
|
||||
imc = new InstanceManageControls(instance.getLoaderVersion());
|
||||
imc = new InstanceManageControls(instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
if (ImGui.beginTabBar("InstanceEdit" + path)) {
|
||||
if (ImGui.beginTabItem("General")) {
|
||||
if (ImGui.button("Open Directory")) {
|
||||
Utils.openFile(path.toFile());
|
||||
}
|
||||
imc.nameBox("Rename", name -> {
|
||||
try {
|
||||
Path newPath = Inceptum.INSTANCE_DIR.resolve(name);
|
||||
|
@ -98,50 +84,35 @@ public class InstanceEditWindow extends Window {
|
|||
ImGui.endTabItem();
|
||||
}
|
||||
//TODO update all
|
||||
if (instance.isFabric() && Files.exists(path.resolve("mods")) && ImGui.beginTabItem("Mods")) {
|
||||
if (instance.isFabric() && ImGui.beginTabItem("Mods")) {
|
||||
if (!Files.exists(path.resolve("mods"))) {
|
||||
try {
|
||||
Files.createDirectories(path.resolve("mods"));
|
||||
} catch (IOException e) {
|
||||
Inceptum.LOGGER.error("Could not create mods directory which was missing from this modded instance", e);
|
||||
}
|
||||
}
|
||||
ImGui.beginChild("mods select", 200, 0);
|
||||
if (ImGui.button("Add")) {
|
||||
InceptumGui.WINDOWS.add(new AddModWindow(path.resolve("mods"), instance, descriptions));
|
||||
InceptumGui.WINDOWS.add(new AddModWindow(path.resolve("mods"), instance, mds));
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (Files.exists(path.resolve("mods")) && ImGui.button("Show")) {
|
||||
Utils.openFile(path.resolve("mods").toFile());
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (Files.exists(path.resolve("config")) && ImGui.button("Configs")) {
|
||||
Utils.openFile(path.resolve("config").toFile());
|
||||
}
|
||||
ImGui.separator();
|
||||
try {
|
||||
for (Path mods : Files.list(path.resolve("mods")).toList()) {
|
||||
if (Files.isDirectory(mods)) {
|
||||
ImGui.text(mods.getFileName().toString());
|
||||
}
|
||||
else {
|
||||
if (mods.toString().endsWith(".jar")) {
|
||||
Path imod = mods.getParent().resolve(mods.getFileName() + ".imod");
|
||||
//TODO prevent blocking UI thread
|
||||
if (Files.exists(imod) && !descriptions.containsKey(mods)) {
|
||||
try (FileSystem fs = Utils.openZipFile(mods, false)) {
|
||||
ModDescription md = Utils.loadObject(imod, ModDescription.class);
|
||||
Optional<ModSource> update = Optional.empty();
|
||||
for (ModSource source : md.sources) {
|
||||
Optional<ModSource> ms = source.getUpdate(instance.getMinecraftVersion());
|
||||
if (ms.isEmpty()) continue;
|
||||
if (update.isEmpty()) update = ms;
|
||||
}
|
||||
if (Files.exists(fs.getPath("fabric.mod.json"))) {
|
||||
descriptions.put(mods, new IWModDescription(md,
|
||||
Utils.loadObject(fs.getPath("fabric.mod.json"), FabricModJson.class),
|
||||
mods,
|
||||
imod,
|
||||
update));
|
||||
}
|
||||
else {
|
||||
descriptions.put(mods, new IWModDescription(md, null, mods, null, update));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!mods.toString().endsWith(".imod") && ImGui.button(descriptions.containsKey(mods) ? descriptions.get(mods).getName() : mods.getFileName().toString())) {
|
||||
selected = mods;
|
||||
}
|
||||
for (ModsDirScanner.IWModDescription mod : mds.getMods()) {
|
||||
if (ImGui.button(mod.getName())) {
|
||||
selected = mod.path();
|
||||
}
|
||||
}
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
Inceptum.showError("Could not list mods", e);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ImGui.endChild();
|
||||
ImGui.sameLine();
|
||||
|
@ -149,38 +120,34 @@ public class InstanceEditWindow extends Window {
|
|||
if (selected == null) {
|
||||
ImGui.text("Select a mod to view settings");
|
||||
} else {
|
||||
if (descriptions.containsKey(selected)) {
|
||||
IWModDescription md = descriptions.get(selected);
|
||||
ImGui.text(md.getName());
|
||||
if (md.fmj != null && md.fmj.description != null) {
|
||||
ImGui.text(md.fmj.description);
|
||||
}
|
||||
if (md.update.isPresent() && ImGui.button("Update to " + md.update.get().getVersion())) {
|
||||
try {
|
||||
AddModWindow.download(md.update.get(), path.resolve("mods"), descriptions).write();
|
||||
Files.delete(md.path);
|
||||
if (md.imod != null && Files.exists(md.imod)) Files.delete(md.imod);
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Update failed", e);
|
||||
}
|
||||
}
|
||||
if (ImGui.button("Delete")) {
|
||||
if (!md.mod.dependents.isEmpty()) {
|
||||
Inceptum.showError("This mod still has the following dependent mods installed: " + String.join(", ", md.mod.dependents), "Dependents present");
|
||||
}
|
||||
else {
|
||||
try {
|
||||
delete(md);
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Couldn't delete the file", e);
|
||||
}
|
||||
selected = null;
|
||||
}
|
||||
ModsDirScanner.IWModDescription md = mds.get(selected);
|
||||
ImGui.text(md.getName());
|
||||
ImGui.separator();
|
||||
for (String s : md.getDescription()) {
|
||||
ImGui.text(s);
|
||||
}
|
||||
if (md.update().isPresent() && ImGui.button("Update to " + md.update().get().getVersion())) {
|
||||
try {
|
||||
AddModWindow.DownloadMeta dm = AddModWindow.download(md.update().get(), path.resolve("mods"), mds);
|
||||
dm.write();
|
||||
Files.delete(md.path());
|
||||
if (md.imod().isPresent() && Files.exists(md.imod().get())) Files.delete(md.imod().get());
|
||||
selected = dm.download().file();
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Update failed", e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ImGui.text("This mod was added manually");
|
||||
ImGui.text("Its hash was also not found on modrinth or curseforge.");
|
||||
if (ImGui.button("Delete")) {
|
||||
if (md.mod().isPresent() && !md.mod().get().dependents.isEmpty())
|
||||
Inceptum.showError("This mod still has the following dependent mods installed: " + String.join(", ", md.mod().get().dependents), "Dependents present");
|
||||
else {
|
||||
try {
|
||||
delete(md);
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Couldn't delete the file", e);
|
||||
}
|
||||
selected = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui.endGroup();
|
||||
|
@ -190,15 +157,20 @@ public class InstanceEditWindow extends Window {
|
|||
}
|
||||
}
|
||||
|
||||
private void delete(IWModDescription md) throws IOException {
|
||||
Files.delete(md.path);
|
||||
if (md.imod != null && Files.exists(md.imod)) Files.delete(md.imod);
|
||||
for (String dependency : md.mod.dependencies) {
|
||||
Path dep = path.resolve("mods").resolve(dependency);
|
||||
IWModDescription dmd = descriptions.get(dep);
|
||||
dmd.mod.dependencies.remove(md.path.getFileName().toString());
|
||||
if (dmd.mod.dependencies.isEmpty()) delete(dmd);
|
||||
else Utils.writeObject(dmd.imod, dmd.mod);
|
||||
private void delete(ModsDirScanner.IWModDescription md) throws IOException {
|
||||
Utils.deleteRecursive(md.path());
|
||||
if (md.imod().isPresent() && Files.exists(md.imod().get())) Files.delete(md.imod().get());
|
||||
if (md.mod().isPresent()) {
|
||||
for (String dependency : md.mod().get().dependencies) {
|
||||
Path dep = path.resolve("mods").resolve(dependency);
|
||||
ModsDirScanner.IWModDescription dmd = mds.get(dep);
|
||||
if (dmd.mod().isPresent()) {
|
||||
dmd.mod().get().dependencies.remove(md.path().getFileName().toString());
|
||||
if (dmd.mod().get().dependencies.isEmpty()) delete(dmd);
|
||||
else if (dmd.imod().isPresent())
|
||||
Utils.writeObject(dmd.imod().get(), dmd.mod().get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,8 +185,10 @@ public class InstanceEditWindow extends Window {
|
|||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
mds.close();
|
||||
if (reDownload) {
|
||||
try {
|
||||
//TODO show progress
|
||||
Steps.reDownload(path);
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Could not re-download data", e);
|
||||
|
|
|
@ -6,17 +6,9 @@ import imgui.type.ImBoolean;
|
|||
import imgui.type.ImInt;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.InceptumGui;
|
||||
import io.gitlab.jfronny.inceptum.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.install.Steps;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.LoaderInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionsListInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.MapAppender;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.util.api.FabricMetaApi;
|
||||
import io.gitlab.jfronny.inceptum.util.api.McApi;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.AccountManager;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.AuthInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.MicrosoftAccount;
|
||||
|
@ -26,8 +18,7 @@ import java.io.IOException;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class MainWindow extends Window {
|
||||
private final ImBoolean darkTheme = new ImBoolean(Inceptum.CONFIG.darkTheme);
|
||||
|
@ -99,7 +90,7 @@ public class MainWindow extends Window {
|
|||
List<Path> paths;
|
||||
try {
|
||||
if (!Files.exists(Inceptum.INSTANCE_DIR)) Files.createDirectories(Inceptum.INSTANCE_DIR);
|
||||
paths = Files.list(Inceptum.INSTANCE_DIR).filter(Files::isDirectory).toList();
|
||||
paths = Utils.ls(Inceptum.INSTANCE_DIR, (Predicate<Path>) Files::isDirectory);
|
||||
} catch (IOException e) {
|
||||
Inceptum.LOGGER.error("Could not list instances");
|
||||
return;
|
||||
|
|
|
@ -6,6 +6,7 @@ import imgui.type.ImInt;
|
|||
import imgui.type.ImString;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.model.fabric.FabricVersionLoaderInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.LoaderInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionsList;
|
||||
|
@ -34,15 +35,21 @@ public class InstanceManageControls {
|
|||
private VersionsListInfo selected;
|
||||
private FabricVersionLoaderInfo selectedFabric;
|
||||
|
||||
public InstanceManageControls(String loaderVersion) {
|
||||
public InstanceManageControls(InstanceMeta meta) {
|
||||
selected = getVersions(false).get(0);
|
||||
if (Inceptum.CONFIG.snapshots)
|
||||
version.set(manifest.versions.indexOf(selected));
|
||||
for (VersionsListInfo ver : getVersions(true)) {
|
||||
if (ver.id.equals(meta.getMinecraftVersion()))
|
||||
selected = ver;
|
||||
}
|
||||
version.set(getVersions(snapshots.get()).indexOf(selected));
|
||||
name.set(getDefaultName(selected, fabric.get()));
|
||||
fabric.set(meta == null || meta.isFabric());
|
||||
List<FabricVersionLoaderInfo> versions = getFabricLoaderInfo();
|
||||
for (int i = 0, fabricLoaderInfoSize = versions.size(); i < fabricLoaderInfoSize; i++) {
|
||||
FabricVersionLoaderInfo version = versions.get(i);
|
||||
if (((loaderVersion == null || loaderVersion.equals("")) && version.loader.stable) || (version.loader.version.equals(loaderVersion))) {
|
||||
if (meta != null && meta.isFabric()
|
||||
? version.loader.version.equals(meta.getLoaderVersion())
|
||||
: version.loader.stable) {
|
||||
selectedFabric = version;
|
||||
fabricVersion.set(i);
|
||||
break;
|
||||
|
|
|
@ -2,16 +2,24 @@
|
|||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} %boldCyan(%-34.-34thread) %red(%10.10X{jda.shard}) %boldGreen(%-15.-15logger{0}) %highlight(%-6level) %msg%n</pattern>
|
||||
<pattern>%d{HH:mm:ss.SSS} %boldCyan(%thread) %boldGreen(%logger{0}) %highlight(%level) %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="MapAppender" class="io.gitlab.jfronny.inceptum.util.MapAppender">
|
||||
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
|
||||
<file>inceptum.log</file>
|
||||
<append>false</append>
|
||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||
<pattern>%d{HH:mm:ss.SSS} %thread %logger{0} %level %msg%n</pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="MEMORY" class="io.gitlab.jfronny.inceptum.util.MapAppender">
|
||||
</appender>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="MapAppender" />
|
||||
<appender-ref ref="FILE" />
|
||||
<appender-ref ref="MEMORY" />
|
||||
</root>
|
||||
</configuration>
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.nio.file.Path;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Wrapper {
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
@ -45,11 +46,13 @@ public class Wrapper {
|
|||
}
|
||||
Path pathChosen = null;
|
||||
ComparableVersion chosenVer = new ComparableVersion("0");
|
||||
for (Path path1 : Files.list(p).toList()) {
|
||||
ComparableVersion cv = new ComparableVersion(path1.getFileName().toString());
|
||||
if (cv.compareTo(chosenVer) > 0) {
|
||||
chosenVer = cv;
|
||||
pathChosen = path1;
|
||||
try (Stream<Path> versionDirs = Files.list(p)) {
|
||||
for (Path path1 : versionDirs.toList()) {
|
||||
ComparableVersion cv = new ComparableVersion(path1.getFileName().toString());
|
||||
if (cv.compareTo(chosenVer) > 0) {
|
||||
chosenVer = cv;
|
||||
pathChosen = path1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pathChosen == null) {
|
||||
|
|
Loading…
Reference in New Issue