diff options
Diffstat (limited to 'core/src/main/java')
10 files changed, 188 insertions, 38 deletions
diff --git a/core/src/main/java/dev/figboot/launcher/core/LauncherConstants.java b/core/src/main/java/dev/figboot/launcher/core/LauncherConstants.java new file mode 100644 index 0000000..209f73c --- /dev/null +++ b/core/src/main/java/dev/figboot/launcher/core/LauncherConstants.java @@ -0,0 +1,5 @@ +package dev.figboot.launcher.core; + +public final class LauncherConstants { + public static final String PROGRAM_NAME = "l4s2"; +} diff --git a/core/src/main/java/dev/figboot/launcher/core/config/CacheLauncherDirectories.java b/core/src/main/java/dev/figboot/launcher/core/config/CacheLauncherDirectories.java new file mode 100644 index 0000000..ae26e2e --- /dev/null +++ b/core/src/main/java/dev/figboot/launcher/core/config/CacheLauncherDirectories.java @@ -0,0 +1,30 @@ +package dev.figboot.launcher.core.config; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.file.Path; +import java.util.EnumMap; +import java.util.Map; +import java.util.function.Function; + +class CacheLauncherDirectories implements LauncherDirectories { + private static final Logger LOGGER = LoggerFactory.getLogger(CacheLauncherDirectories.class); + + private final Map<LauncherDirectory, Path> dirs = new EnumMap<>(LauncherDirectory.class); + + <E extends Exception> CacheLauncherDirectories(LauncherDirectories delegate, Function<LauncherDirectory, E> onMissing) throws E { + for (LauncherDirectory dir : LauncherDirectory.values()) { + Path path = delegate.getDirectory(dir); + if (path == null) throw onMissing.apply(dir); + + LOGGER.info("Launcher directory {} located at: {}", dir, path); + dirs.put(dir, path); + } + } + + @Override + public Path getDirectory(LauncherDirectory directory) { + return dirs.get(directory); + } +} diff --git a/core/src/main/java/dev/figboot/launcher/core/config/DefaultLauncherDirectories.java b/core/src/main/java/dev/figboot/launcher/core/config/DefaultLauncherDirectories.java index 228bc1a..e9ca0ef 100644 --- a/core/src/main/java/dev/figboot/launcher/core/config/DefaultLauncherDirectories.java +++ b/core/src/main/java/dev/figboot/launcher/core/config/DefaultLauncherDirectories.java @@ -7,17 +7,19 @@ import java.nio.file.Path; @RequiredArgsConstructor(access = AccessLevel.PACKAGE) class DefaultLauncherDirectories implements LauncherDirectories { - private final LauncherDirectories parent; + private final Path home; @Override public Path getDirectory(LauncherDirectory directory) { switch (directory) { case HOME: - return parent.getDirectory(LauncherDirectory.HOME); + return home; case INSTANCES: - return parent.getDirectory(LauncherDirectory.HOME).resolve("instances"); + return home.resolve("instances"); case LIBRARIES: - return parent.getDirectory(LauncherDirectory.HOME).resolve("libraries"); + return home.resolve("libraries"); + case ASSETS: + return home.resolve("assets"); } return null; diff --git a/core/src/main/java/dev/figboot/launcher/core/config/LauncherConfiguration.java b/core/src/main/java/dev/figboot/launcher/core/config/LauncherConfiguration.java index 99bcca4..14abe2a 100644 --- a/core/src/main/java/dev/figboot/launcher/core/config/LauncherConfiguration.java +++ b/core/src/main/java/dev/figboot/launcher/core/config/LauncherConfiguration.java @@ -3,6 +3,5 @@ package dev.figboot.launcher.core.config; import java.nio.file.Path; public interface LauncherConfiguration { - Path getConfigPath(); - Path getInstancesPath(); + LauncherDirectories getDirectories(); } diff --git a/core/src/main/java/dev/figboot/launcher/core/config/LauncherDirectories.java b/core/src/main/java/dev/figboot/launcher/core/config/LauncherDirectories.java index d1ccd08..c1b6881 100644 --- a/core/src/main/java/dev/figboot/launcher/core/config/LauncherDirectories.java +++ b/core/src/main/java/dev/figboot/launcher/core/config/LauncherDirectories.java @@ -2,7 +2,7 @@ package dev.figboot.launcher.core.config; import java.nio.file.Path; -interface LauncherDirectories { +public interface LauncherDirectories { Path getDirectory(LauncherDirectory directory); default LauncherDirectories mapNull(LauncherDirectories ifNull) { diff --git a/core/src/main/java/dev/figboot/launcher/core/config/LauncherDirectory.java b/core/src/main/java/dev/figboot/launcher/core/config/LauncherDirectory.java index fa2cbd6..eb4503d 100644 --- a/core/src/main/java/dev/figboot/launcher/core/config/LauncherDirectory.java +++ b/core/src/main/java/dev/figboot/launcher/core/config/LauncherDirectory.java @@ -3,5 +3,6 @@ package dev.figboot.launcher.core.config; public enum LauncherDirectory { HOME, INSTANCES, - LIBRARIES + LIBRARIES, + ASSETS } diff --git a/core/src/main/java/dev/figboot/launcher/core/config/OSLauncherDirectories.java b/core/src/main/java/dev/figboot/launcher/core/config/OSLauncherDirectories.java index 988f2e6..ec1d6d0 100644 --- a/core/src/main/java/dev/figboot/launcher/core/config/OSLauncherDirectories.java +++ b/core/src/main/java/dev/figboot/launcher/core/config/OSLauncherDirectories.java @@ -1,23 +1,114 @@ package dev.figboot.launcher.core.config; +import dev.figboot.launcher.core.LauncherConstants; +import dev.figboot.launcher.core.system.SystemInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.nio.file.FileSystems; import java.nio.file.Path; -import java.util.EnumMap; -import java.util.function.Function; +import java.util.function.Supplier; class OSLauncherDirectories { private static final Logger LOGGER = LoggerFactory.getLogger(OSLauncherDirectories.class); - class Windows implements LauncherDirectories { + static LauncherDirectories forOS(SystemInfo.OperatingSystem os) { + switch (os) { + case WINDOWS: + return new Windows(); + case MACOS: + return new MacOS(); + case LINUX: + return new Linux(); + case UNKNOWN: + return d -> null; + } + + throw new IllegalArgumentException(); + } + + private static class Windows implements LauncherDirectories { @Override public Path getDirectory(LauncherDirectory directory) { - switch (directory) { - case HOME: { + if (directory != LauncherDirectory.HOME) return null; // defer + String appdata = System.getenv("APPDATA"); + if (appdata == null) { + LOGGER.warn("Undefined %APPDATA% environment variable! The launcher can't figure out where it should place its files."); + LOGGER.warn("Define %APPDATA% to a sensible directory to resolve this issue."); + return null; + } + + return FileSystems.getDefault().getPath(appdata, LauncherConstants.PROGRAM_NAME); + } + } + + private static Path cacheHome = null; + private static boolean homeChecked = false; + private static synchronized Path getHomeDirectory() { + if (!homeChecked) { + homeChecked = true; + String home = System.getProperty("user.home"); + if (home == null) { + LOGGER.warn("Could not find your home directory (\"user.home\" is unset...)! The launcher probably doesn't know where it should place its files."); + return null; + } + + cacheHome = FileSystems.getDefault().getPath(home); + } + + return cacheHome; + } + + private static class MacOS implements LauncherDirectories { + @Override + public Path getDirectory(LauncherDirectory directory) { + if (directory != LauncherDirectory.HOME) return null; // defer + + Path home = getHomeDirectory(); + if (home == null) return null; + + return home.resolve("Library").resolve("Application Support").resolve(LauncherConstants.PROGRAM_NAME); + } + } + + private static class Linux implements LauncherDirectories { + @Override + public Path getDirectory(LauncherDirectory directory) { + switch (directory) { + case HOME: + Path xdgConfig = getXDGDir("XDG_CONFIG_HOME", () -> FileSystems.getDefault().getPath(".config")); + if (xdgConfig == null) return null; + return xdgConfig.resolve(LauncherConstants.PROGRAM_NAME); + case INSTANCES: + Path xdgData = getXDGDir("XDG_DATA_HOME", () -> FileSystems.getDefault().getPath(".local", "share")); + if (xdgData == null) return null; + return xdgData.resolve(LauncherConstants.PROGRAM_NAME).resolve("instances"); + case LIBRARIES: { + Path xdgCache = getXDGDir("XDG_CACHE_HOME", () -> FileSystems.getDefault().getPath(".cache")); + if (xdgCache == null) return null; + return xdgCache.resolve(LauncherConstants.PROGRAM_NAME).resolve("libraries"); + } + case ASSETS: { + Path xdgCache = getXDGDir("XDG_CACHE_HOME", () -> FileSystems.getDefault().getPath(".cache")); + if (xdgCache == null) return null; + return xdgCache.resolve(LauncherConstants.PROGRAM_NAME).resolve("assets"); } } + + return null; + } + + private static Path getXDGDir(String xdgEnvVar, Supplier<Path> def) { + String env = System.getenv(xdgEnvVar); + + if (env == null) { + Path home = getHomeDirectory(); + if (home == null) return null; + return home.resolve(def.get()); + } + + return FileSystems.getDefault().getPath(env); } } } diff --git a/core/src/main/java/dev/figboot/launcher/core/config/PropertyLauncherDirectories.java b/core/src/main/java/dev/figboot/launcher/core/config/PropertyLauncherDirectories.java index 4d10919..a9a0358 100644 --- a/core/src/main/java/dev/figboot/launcher/core/config/PropertyLauncherDirectories.java +++ b/core/src/main/java/dev/figboot/launcher/core/config/PropertyLauncherDirectories.java @@ -1,14 +1,18 @@ package dev.figboot.launcher.core.config; +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; + import java.nio.file.FileSystems; import java.nio.file.Path; -enum PropertyLauncherDirectories implements LauncherDirectories { - INSTANCE; +@RequiredArgsConstructor(access = AccessLevel.PACKAGE) +class PropertyLauncherDirectories implements LauncherDirectories { + private final String root; @Override public Path getDirectory(LauncherDirectory dir) { - String prop = System.getProperty("dev.figboot.launcher.core.dir." + dir.name()); + String prop = System.getProperty(root + dir.name()); if (prop != null) { return FileSystems.getDefault().getPath(prop); diff --git a/core/src/main/java/dev/figboot/launcher/core/config/SimpleLauncherConfiguration.java b/core/src/main/java/dev/figboot/launcher/core/config/SimpleLauncherConfiguration.java index 6e4615f..0dda8ff 100644 --- a/core/src/main/java/dev/figboot/launcher/core/config/SimpleLauncherConfiguration.java +++ b/core/src/main/java/dev/figboot/launcher/core/config/SimpleLauncherConfiguration.java @@ -1,44 +1,42 @@ package dev.figboot.launcher.core.config; import dev.figboot.launcher.core.system.SystemInfo; +import dev.figboot.launcher.core.util.SystemException; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.nio.file.Path; import java.util.EnumMap; import java.util.Map; +import java.util.Objects; @RequiredArgsConstructor(access = AccessLevel.PROTECTED) public class SimpleLauncherConfiguration implements LauncherConfiguration { - private final Path configPath, instancePath; + private static final Logger LOGGER = LoggerFactory.getLogger(SimpleLauncherConfiguration.class); + private static final String DIR_PROP_ROOT = "dev.figboot.launcher.core.directories."; - public static SimpleLauncherConfiguration forOS(SystemInfo.OperatingSystem os) { - Map<LauncherDirectory, Path> launcherDirs = new EnumMap<>(LauncherDirectory.class); - launcherDirs.put + private final LauncherDirectories directories; - switch (os) { - case WINDOWS: - String appDataPath = System.getenv("APPDATA"); - String homePath = System.getProperty("user.home"); + public static SimpleLauncherConfiguration forOS(SystemInfo.OperatingSystem os) throws SystemException { + Objects.requireNonNull(os, "os must not be null"); - if (appDataPath != null) { - - } - break; + LauncherDirectories osDirs = OSLauncherDirectories.forOS(os); + Path home = osDirs.getDirectory(LauncherDirectory.HOME); + if (home == null) { + LOGGER.error("Unable to determine a sensible launcher home directory! Try defining \"{}.HOME\". Bailing out.", DIR_PROP_ROOT); + throw new SystemException("unable to determine sensible launcher home directory"); } - + return new SimpleLauncherConfiguration(new CacheLauncherDirectories(new PropertyLauncherDirectories(DIR_PROP_ROOT) + .mapNull(osDirs) + .mapNull(new DefaultLauncherDirectories(home)), + (dir) -> new SystemException(String.format("Couldn't determine directory %1$s! Try defining %2$s.%1$s.", dir.name(), DIR_PROP_ROOT)))); } @Override - public Path getConfigPath() { - return configPath; + public LauncherDirectories getDirectories() { + return directories; } - - @Override - public Path getInstancesPath() { - return instancePath; - } - - } diff --git a/core/src/main/java/dev/figboot/launcher/core/util/SystemException.java b/core/src/main/java/dev/figboot/launcher/core/util/SystemException.java new file mode 100644 index 0000000..5989e25 --- /dev/null +++ b/core/src/main/java/dev/figboot/launcher/core/util/SystemException.java @@ -0,0 +1,20 @@ +package dev.figboot.launcher.core.util; + +// launcher couldn't be initialized because the system isn't compatible +public class SystemException extends Exception { + public SystemException() { + super(); + } + + public SystemException(String message) { + super(message); + } + + public SystemException(Throwable cause) { + super(cause); + } + + public SystemException(String message, Throwable cause) { + super(message, cause); + } +} |
