Skip to content

Commit

Permalink
First working prototype of mch-viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
Alvinn8 committed Feb 14, 2024
1 parent 4bd23aa commit 3bf764d
Show file tree
Hide file tree
Showing 9 changed files with 416 additions and 152 deletions.
61 changes: 21 additions & 40 deletions mch-fs/src/main/java/ca/bkaw/mch/fs/MchFileSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,31 +37,38 @@ public class MchFileSystem extends FileSystem {
private final MchFileSystemProvider provider;
private final MchRepository repository;
private TrackedWorld trackedWorld;
private World world;
private String dimensionKey;
private Dimension dimension;
private final Path root;
private Set<Path> restoredPaths;

public MchFileSystem(MchFileSystemProvider provider, Path root, MchRepository repository, TrackedWorld trackedWorld, World world) throws IOException {
public MchFileSystem(MchFileSystemProvider provider, Path root, MchRepository repository, TrackedWorld trackedWorld, String dimensionKey, Dimension dimension) {
if (root.getFileSystem() instanceof MchFileSystem) {
throw new IllegalArgumentException("path must correspond to a non-mch file system.");
throw new IllegalArgumentException("root path must correspond to a non-mch file system.");
}
if (!root.isAbsolute()) {
throw new IllegalArgumentException("root path must be absolute.");
}
this.provider = provider;
this.root = root;
this.repository = repository;
this.trackedWorld = trackedWorld;
this.world = world;
this.dimensionKey = dimensionKey;
this.dimension = dimension;
this.restoredPaths = new HashSet<>();
}

/**
* Set the {@link World} object that this file system reads from.
*
* @param trackedWorld The tracked world.
* @param world The world snapshot.
* @param dimensionKey The dimension key.
* @param dimension The dimension snapshot.
*/
public void setWorld(TrackedWorld trackedWorld, World world) {
public void setWorld(TrackedWorld trackedWorld, String dimensionKey, Dimension dimension) {
this.trackedWorld = trackedWorld;
this.world = world;
this.dimensionKey = dimensionKey;
this.dimension = dimension;
this.restoredPaths = new HashSet<>();
}

Expand All @@ -83,21 +90,8 @@ public void restore(@NotNull MchPath mchPath) throws IOException {
System.out.println("DEBUG Restoring " + mchPath);
Path relative = this.root.relativize(mchPath.path.toAbsolutePath());

// TODO custom dimensions
String dimensionKey = switch (relative.getName(0).getFileName().toString()) {
case Util.NETHER_FOLDER -> Dimension.NETHER;
case Util.THE_END_FOLDER -> Dimension.THE_END;
default -> Dimension.OVERWORLD;
};
int nameIndex = Dimension.OVERWORLD.equals(dimensionKey) ? 0 : 1;

Reference20<Dimension> dimensionRef = this.world.getDimension(dimensionKey);
if (dimensionRef == null) {
return;
}
Dimension dimension = dimensionRef.resolve(this.repository);

if ("region".equals(relative.getName(nameIndex).getFileName().toString())) {
if ("region".equals(relative.getName(0).getFileName().toString())) {
String fileName = relative.getFileName().toString();
if ("region".equals(fileName)) {
// lazy but works
Expand All @@ -117,11 +111,11 @@ public void restore(@NotNull MchPath mchPath) throws IOException {
}

Path regionStoragePath = RegionStorageVisitor.getPath(
this.repository, this.trackedWorld, dimensionKey, regionX, regionZ
this.repository, this.trackedWorld, this.dimensionKey, regionX, regionZ
);

Path mchRegionFilePath = MchRegionFile.getPath(
this.repository, this.trackedWorld, dimensionKey, regionX, regionZ
this.repository, this.trackedWorld, this.dimensionKey, regionX, regionZ
);

Path mcRegionFilePath = mchPath.path;
Expand All @@ -142,7 +136,7 @@ public void restore(@NotNull MchPath mchPath) throws IOException {

// Non-region file.
Tree tree = dimension.getMiscellaneousFiles().resolve(this.repository);
for (int i = nameIndex; i < relative.getNameCount() - 1; i++) {
for (int i = 0; i < relative.getNameCount() - 1; i++) {
String name = relative.getName(i).toString();
Reference20<Tree> subTreeRef = tree.getSubTrees().get(name);
if (subTreeRef == null) {
Expand Down Expand Up @@ -172,22 +166,9 @@ public DirectoryStream<Path> newDirectoryStream(@NotNull MchPath dir, DirectoryS
// Thread.dumpStack();
Path relative = this.root.relativize(dir.path.toAbsolutePath().normalize());

// TODO custom dimensions
String dimensionKey = switch (relative.getName(0).getFileName().toString()) {
case Util.NETHER_FOLDER -> Dimension.NETHER;
case Util.THE_END_FOLDER -> Dimension.THE_END;
default -> Dimension.OVERWORLD;
};
int nameIndex = Dimension.OVERWORLD.equals(dimensionKey) ? 0 : 1;

Reference20<Dimension> dimensionRef = this.world.getDimension(dimensionKey);
if (dimensionRef == null) {
throw new NoSuchFileException(dir.toString());
}
Dimension dimension = dimensionRef.resolve(this.repository);

if ("region".equals(relative.getName(nameIndex).getFileName().toString())) {
if (relative.getNameCount() != nameIndex + 1) {
if ("region".equals(relative.getName(0).getFileName().toString())) {
if (relative.getNameCount() != 1) {
// No files in subdirectories of region.
return new DirectoryStream<>() {
@Override
Expand Down Expand Up @@ -215,7 +196,7 @@ public void close() {}

// Non-region file.
Tree tree = dimension.getMiscellaneousFiles().resolve(this.repository);
for (int i = nameIndex; i < relative.getNameCount(); i++) {
for (int i = 0; i < relative.getNameCount(); i++) {
String name = relative.getName(i).toString();
if (name.isEmpty() || ".".equals(name)) {
continue;
Expand Down
62 changes: 24 additions & 38 deletions mch-fs/src/main/java/ca/bkaw/mch/fs/MchFileSystemProvider.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ca.bkaw.mch.fs;

import ca.bkaw.mch.object.world.World;
import ca.bkaw.mch.object.dimension.Dimension;
import ca.bkaw.mch.repository.MchRepository;
import ca.bkaw.mch.repository.TrackedWorld;
import org.jetbrains.annotations.NotNull;
Expand All @@ -16,7 +16,6 @@
import java.nio.file.DirectoryStream;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
Expand All @@ -26,59 +25,46 @@
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.spi.FileSystemProvider;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MchFileSystemProvider extends FileSystemProvider {
public static final MchFileSystemProvider INSTANCE = new MchFileSystemProvider();

public static final String SCHEME = "mch";
public static final String REPO_ENV_KEY = "mch_repository";
public static final String WORLD_ENV_KEY = "mch_world";
public static final String TRACKED_WORLD_ENV_KEY = "mch_tracked_world";

final Map<String, MchFileSystem> fileSystems = new HashMap<>();

@Override
public String getScheme() {
return SCHEME;
}

@Override
public FileSystem newFileSystem(URI uri, Map<String, ?> env) throws IOException {
synchronized (this.fileSystems) {
if (!(env.get(REPO_ENV_KEY) instanceof MchRepository repository)) {
throw new IllegalArgumentException("Please provide the mch repository as the \"" + REPO_ENV_KEY + "\" env key.");
}
if (!(env.get(WORLD_ENV_KEY) instanceof World world)) {
throw new IllegalArgumentException("Please provide the mch world object as the \"" + WORLD_ENV_KEY + "\" env key.");
}
if (!(env.get(TRACKED_WORLD_ENV_KEY) instanceof TrackedWorld trackedWorld)) {
throw new IllegalArgumentException("Please provide the tracked world as the \"" + TRACKED_WORLD_ENV_KEY + "\" env key.");
}
if (!SCHEME.equals(uri.getScheme())) {
throw new IllegalArgumentException("Expected \"" + SCHEME + "\" as the URI scheme.");
}
String path = uri.getPath();
Path root = Path.of(path);
if (!Files.isDirectory(root)) {
throw new IllegalArgumentException("Please make sure the provided path is a directory: " + root);
}

MchFileSystem fileSystem = this.fileSystems.get(path);
if (fileSystem != null) {
throw new FileSystemAlreadyExistsException(path);
}
fileSystem = new MchFileSystem(this, root, repository, trackedWorld, world);
this.fileSystems.put(path, fileSystem);
return fileSystem;
/**
* Create a new {@link MchFileSystem} that wraps paths on the real file system and
* provides files on-demand from the mch repository.
*
* @param root The root path to wrap, must be a directory that exists.
* @param repository The mch repository.
* @param trackedWorld The tracked world.
* @param dimensionKey The dimension key.
* @param dimension The dimension snapshot.
* @return The file system.
*/
@NotNull
public MchFileSystem newFileSystem(Path root, MchRepository repository, TrackedWorld trackedWorld, String dimensionKey, Dimension dimension) {
if (!Files.isDirectory(root)) {
throw new IllegalArgumentException("Please make sure the provided path is a directory: " + root);
}
return new MchFileSystem(this, root, repository, trackedWorld, dimensionKey, dimension);
}

@Override
public MchFileSystem newFileSystem(URI uri, Map<String, ?> env) {
throw new UnsupportedOperationException("Please use the other newFileSystem method.");
}

@Override
public FileSystem getFileSystem(URI uri) {
return this.fileSystems.get(uri.getPath());
throw new UnsupportedOperationException();
}

@Override
Expand Down Expand Up @@ -161,7 +147,7 @@ public boolean isHidden(Path path) throws IOException {
}

@Override
public FileStore getFileStore(Path path) throws IOException {
public FileStore getFileStore(Path path) {
throw new UnsupportedOperationException();
}

Expand Down
2 changes: 1 addition & 1 deletion mch-fs/src/main/java/ca/bkaw/mch/fs/MchPath.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public MchPath(@NotNull MchFileSystem fileSystem, @NotNull Path path) {
* @return The non-mch path.
*/
@Contract("!null -> !null; null -> null")
private @Nullable Path unwrap(@Nullable Path path) {
public static @Nullable Path unwrap(@Nullable Path path) {
if (path == null) {
return null;
}
Expand Down
61 changes: 0 additions & 61 deletions mch-fs/src/main/java/ca/bkaw/mch/fs/TestMain.java

This file was deleted.

42 changes: 37 additions & 5 deletions mch-viewer/fabric/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id("fabric-loom") version "1.5-SNAPSHOT"
id("java")
id("fabric-loom") version "1.5-SNAPSHOT"
id("com.github.johnrengelman.shadow") version "7.0.0"
}

base {
Expand All @@ -21,11 +22,11 @@ dependencies {
modImplementation("net.fabricmc.fabric-api:fabric-api:${property("fabric_version")}")

// Fantasy for runtime worlds
modImplementation("xyz.nucleoid:fantasy:${property("fantasy_version")}")
include(modImplementation("xyz.nucleoid:fantasy:${property("fantasy_version")}")!!)

// mch dependencies
implementation(project(":mch"))
implementation(project(":mch-fs"))
implementation(project(":mch"))!!
implementation(project(":mch-fs"))!!
compileOnly("org.jetbrains:annotations:24.0.1")
}

Expand All @@ -36,4 +37,35 @@ tasks {
expand(mutableMapOf("version" to project.version))
}
}
}

shadowJar {
archiveBaseName.set("mch-viewer-fabric-dev")
archiveClassifier.set("")

dependencies {
exclude("net.fabricmc:.*")
exclude("xyz.nucleoid:fantasy")
include(dependency("ca.bkaw.mch:.*"))
include(dependency("com.github.luben:zstd-jni:.*"))
include(dependency("commons-net:commons-net:.*"))
include(dependency("com.hierynomus:sshj:.*"))
exclude("/mappings/*")
}
}

val remappedShadowJar by registering(net.fabricmc.loom.task.RemapJarTask::class) {
dependsOn(shadowJar)
input = shadowJar.get().archiveFile
addNestedDependencies = true
archiveBaseName.set("mch-viewer-fabric")
}

assemble {
dependsOn(remappedShadowJar)
}

artifacts {
archives(remappedShadowJar)
shadow(shadowJar)
}
}
Loading

0 comments on commit 3bf764d

Please sign in to comment.