2022-09-26 19:09:02 +02:00
|
|
|
package io.gitlab.jfronny.inceptum.launcher.util;
|
|
|
|
|
|
|
|
import io.gitlab.jfronny.commons.cache.FileBackedRef;
|
|
|
|
import io.gitlab.jfronny.commons.io.JFiles;
|
|
|
|
import io.gitlab.jfronny.inceptum.common.MetaHolder;
|
|
|
|
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
import java.nio.file.Files;
|
|
|
|
import java.nio.file.Path;
|
|
|
|
import java.util.*;
|
|
|
|
import java.util.function.Consumer;
|
|
|
|
|
|
|
|
public class InstanceList {
|
|
|
|
private static final Map<Path, IEntry> metas = new LinkedHashMap<>();
|
|
|
|
|
|
|
|
public static void forEach(Consumer<Entry> target) throws IOException {
|
|
|
|
Objects.requireNonNull(target);
|
|
|
|
if (!Files.exists(MetaHolder.INSTANCE_DIR)) Files.createDirectories(MetaHolder.INSTANCE_DIR);
|
|
|
|
JFiles.listTo(MetaHolder.INSTANCE_DIR, path -> {
|
|
|
|
if (!Files.isDirectory(path)) return;
|
|
|
|
target.accept(read(path));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-09-30 18:07:18 +02:00
|
|
|
public static boolean isEmpty() throws IOException {
|
|
|
|
if (!Files.exists(MetaHolder.INSTANCE_DIR)) return true;
|
|
|
|
return JFiles.list(MetaHolder.INSTANCE_DIR, Files::isDirectory).isEmpty();
|
2022-09-26 19:09:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static Entry read(Path instancePath) throws IOException {
|
|
|
|
Objects.requireNonNull(instancePath);
|
|
|
|
synchronized (metas) {
|
|
|
|
if (!metas.containsKey(instancePath)) {
|
|
|
|
metas.put(instancePath, new IEntry(
|
|
|
|
toId(instancePath.getFileName().toString()),
|
|
|
|
instancePath,
|
|
|
|
new FileBackedRef<>(instancePath.resolve("instance.json"), InstanceMeta.class)
|
|
|
|
));
|
|
|
|
}
|
|
|
|
return metas.get(instancePath).toPub();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts any string into a set of lowercase ascii chars
|
|
|
|
* @param input string to convert
|
|
|
|
* @return a string matching [a-p]*
|
|
|
|
*/
|
|
|
|
private static String toId(String input) {
|
|
|
|
StringBuilder result = new StringBuilder();
|
|
|
|
for (byte b : input.getBytes(StandardCharsets.UTF_8)) {
|
|
|
|
int by = Byte.toUnsignedInt(b);
|
|
|
|
int ch2 = by & 15; // right bits
|
|
|
|
int ch1 = (by - ch2) / 16; // left bits
|
|
|
|
result.append((char)('a' + ch1));
|
|
|
|
result.append((char)('a' + ch2));
|
|
|
|
}
|
|
|
|
return result.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
private record IEntry(String id, Path path, FileBackedRef<InstanceMeta> meta) {
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return path.getFileName().toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Entry toPub() throws IOException {
|
|
|
|
return new Entry(id, path, meta.get());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public record Entry(String id, Path path, InstanceMeta meta) implements Comparable<Entry> {
|
|
|
|
@Override
|
|
|
|
public int compareTo(@NotNull InstanceList.Entry entry) {
|
|
|
|
long time1 = meta.lastLaunched == null ? 0 : meta.lastLaunched;
|
|
|
|
long time2 = entry.meta.lastLaunched == null ? 0 : entry.meta.lastLaunched;
|
|
|
|
if (time1 == 0) {
|
|
|
|
if (time2 == 0) return path.getFileName().toString().compareTo(entry.path.getFileName().toString());
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (time2 == 0) return 1;
|
|
|
|
return Long.compare(time1, time2);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return path.getFileName().toString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|