diff --git a/Launcher/src/main/java/pro/gravit/launcher/runtime/backend/LauncherBackendImpl.java b/Launcher/src/main/java/pro/gravit/launcher/runtime/backend/LauncherBackendImpl.java index 4b9779ae..691a295b 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/runtime/backend/LauncherBackendImpl.java +++ b/Launcher/src/main/java/pro/gravit/launcher/runtime/backend/LauncherBackendImpl.java @@ -68,6 +68,7 @@ public class LauncherBackendImpl implements LauncherBackendAPI, TextureUploadExt private volatile List availableJavas; private volatile CompletableFuture> availableJavasFuture; private volatile CompletableFuture processHardwareFuture; + private volatile Path vfsRootPath; private final Map> pingFutures = new ConcurrentHashMap<>(); @Override @@ -315,6 +316,14 @@ public boolean isTestMode() { } } + @Override + public ResourceLayer makeResourceLayer(List overlayList) { + if(vfsRootPath == null) { + vfsRootPath = initVfsDirectory(); + } + return new ResourceLayerImpl(vfsRootPath, overlayList); + } + @SuppressWarnings("unchecked") @Override public T getExtension(Class clazz) { diff --git a/Launcher/src/main/java/pro/gravit/launcher/runtime/backend/ResourceLayerImpl.java b/Launcher/src/main/java/pro/gravit/launcher/runtime/backend/ResourceLayerImpl.java new file mode 100644 index 00000000..6aa50a16 --- /dev/null +++ b/Launcher/src/main/java/pro/gravit/launcher/runtime/backend/ResourceLayerImpl.java @@ -0,0 +1,39 @@ +package pro.gravit.launcher.runtime.backend; + +import pro.gravit.launcher.base.vfs.Vfs; +import pro.gravit.launcher.base.vfs.VfsDirectory; +import pro.gravit.launcher.base.vfs.directory.OverlayVfsDirectory; +import pro.gravit.launcher.core.backend.LauncherBackendAPI; +import pro.gravit.utils.helper.SecurityHelper; + +import java.io.IOException; +import java.net.URL; +import java.nio.file.Path; +import java.util.List; +import java.util.Objects; +import java.util.stream.Stream; + +public class ResourceLayerImpl implements LauncherBackendAPI.ResourceLayer { + private final Path vfsPath; + + public ResourceLayerImpl(Path basePath, List overlayList) { + if(overlayList == null || overlayList.isEmpty()) { + vfsPath = basePath; + return; + } + List overlays = Stream.concat(overlayList.stream(), Stream.of(Path.of(""))) + .map(basePath::resolve) + .map(x -> (VfsDirectory) Vfs.get().resolve(x)) + .filter(Objects::nonNull) + .toList(); + OverlayVfsDirectory directory = new OverlayVfsDirectory(overlays); + String randomName = SecurityHelper.randomStringToken(); + vfsPath = Path.of(randomName); + Vfs.get().put(vfsPath, directory); + } + + @Override + public URL getURL(Path path) throws IOException { + return Vfs.get().getURL(vfsPath.resolve(path)); + } +} diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/base/vfs/directory/FileVfsDirectory.java b/LauncherAPI/src/main/java/pro/gravit/launcher/base/vfs/directory/FileVfsDirectory.java index 666c4b9b..4faaa4b1 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/base/vfs/directory/FileVfsDirectory.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/base/vfs/directory/FileVfsDirectory.java @@ -33,10 +33,10 @@ public VfsEntry find(String name) { @Override public VfsEntry resolve(Path path) { if(path == null) { - return null; + return this; } - Path target = path.resolve(path); + Path target = this.path.resolve(path); if(Files.exists(target)) { if(Files.isDirectory(target)) { return new FileVfsDirectory(target); diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/base/vfs/directory/SimpleVfsDirectory.java b/LauncherAPI/src/main/java/pro/gravit/launcher/base/vfs/directory/SimpleVfsDirectory.java index c2754720..67908446 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/base/vfs/directory/SimpleVfsDirectory.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/base/vfs/directory/SimpleVfsDirectory.java @@ -19,7 +19,7 @@ public VfsEntry find(String name) { @Override public VfsEntry resolve(Path path) { if(path == null) { - return null; + return this; } VfsDirectory current = this; @@ -30,6 +30,9 @@ public VfsEntry resolve(Path path) { if(entity instanceof SimpleVfsDirectory) { current = newDir; } else { + if (i+1 >= path.getNameCount()) { + return newDir; + } Path newPath = path.subpath(i+1, path.getNameCount()); return newDir.resolve(newPath); } diff --git a/LauncherCore/src/main/java/pro/gravit/launcher/core/backend/LauncherBackendAPI.java b/LauncherCore/src/main/java/pro/gravit/launcher/core/backend/LauncherBackendAPI.java index 8172a0a0..63903910 100644 --- a/LauncherCore/src/main/java/pro/gravit/launcher/core/backend/LauncherBackendAPI.java +++ b/LauncherCore/src/main/java/pro/gravit/launcher/core/backend/LauncherBackendAPI.java @@ -9,6 +9,8 @@ import pro.gravit.launcher.core.api.model.UserPermissions; import pro.gravit.launcher.core.backend.extensions.Extension; +import java.io.IOException; +import java.net.URL; import java.nio.file.Path; import java.util.List; import java.util.Set; @@ -38,6 +40,7 @@ public interface LauncherBackendAPI { String getUsername(); SelfUser getSelfUser(); boolean isTestMode(); + ResourceLayer makeResourceLayer(List overlayList); // Extensions T getExtension(Class clazz); void shutdown(); @@ -173,4 +176,8 @@ interface ServerPingInfo { int getOnline(); List getPlayerNames(); } + + interface ResourceLayer { + URL getURL(Path path) throws IOException; + } }