Inceptum/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/instance/Instance.java

141 lines
4.6 KiB
Java

package io.gitlab.jfronny.inceptum.launcher.system.instance;
import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta.GC_InstanceMeta;
import io.gitlab.jfronny.commons.ref.R;
import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner;
import io.gitlab.jfronny.inceptum.launcher.util.GameVersionParser;
import io.gitlab.jfronny.inceptum.launcher.util.ProcessUtils;
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.Set;
public record Instance(String id, Path path, InstanceMeta meta, ModsDirScanner mds) implements Comparable<Instance> {
private static final String INCEPTUM_LOCK = "inceptum.lock";
private static final String INCEPTUM_SETUP_LOCK = "inceptum.setup.lock";
public Instance(Path path, InstanceMeta meta) throws IOException {
this(generateId(path.fileName.toString()), path, meta, ModsDirScanner.get(path.resolve("mods"), meta));
}
public Instance(String id, Path path, InstanceMeta meta, ModsDirScanner mds) {
this.id = id;
this.path = path.toAbsolutePath().normalize();
this.meta = meta;
this.mds = mds;
}
/**
* Converts any string into a set of lowercase ascii chars
*
* @param input string to convert
* @return a string matching [a-p]*
*/
private static String generateId(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();
}
@Override
public int compareTo(@NotNull Instance 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.fileName.toString().compareTo(entry.path.fileName.toString());
return -1;
}
if (time2 == 0) return 1;
return Long.compare(time1, time2);
}
@Override
public String toString() {
return path.fileName.toString();
}
public Path getModsDir() {
return path.resolve("mods");
}
public Path getConfigDir() {
return path.resolve("config");
}
public Set<Mod> getMods() throws IOException {
mds.runOnce(R::nop);
return mds.getMods();
}
public String getName() {
return path.fileName.toString();
}
public boolean isFabric() {
return GameVersionParser.isFabric(meta.version);
}
public String getGameVersion() {
return GameVersionParser.getGameVersion(meta.version);
}
public String getLoaderVersion() {
return GameVersionParser.getLoaderVersion(meta.version);
}
public boolean isSetupLocked() {
return Files.exists(path.resolve(INCEPTUM_SETUP_LOCK));
}
public void setSetupLock(boolean state) throws IOException {
setSetupLock(path, state);
}
public static void setSetupLock(Path instanceDir, boolean state) throws IOException {
if (Files.exists(instanceDir.resolve(INCEPTUM_SETUP_LOCK))) {
if (!state) Files.delete(instanceDir.resolve(INCEPTUM_SETUP_LOCK));
} else {
if (state) Files.createDirectories(instanceDir.resolve(INCEPTUM_SETUP_LOCK));
}
}
public boolean isRunningLocked() {
if (!Files.exists(path.resolve(INCEPTUM_LOCK))) return false;
try {
if (ProcessUtils.isProcessAlive(Files.readString(path.resolve(INCEPTUM_LOCK))))
return true;
Files.delete(path.resolve(INCEPTUM_LOCK));
} catch (IOException e) {
Utils.LOGGER.error("Could not read running lock of " + name, e);
}
return false;
}
public void setRunningLock(long pid) throws IOException {
Files.writeString(path.resolve(INCEPTUM_LOCK), Long.toString(pid));
}
public boolean isLocked() {
return isSetupLocked() || isRunningLocked();
}
public void writeMeta() {
try {
GC_InstanceMeta.write(meta, path.resolve(InstanceList.INSTANCE_CONFIG_NAME));
} catch (IOException e) {
Utils.LOGGER.error("Could not write instance config", e);
}
}
}