diff --git a/li/cil/oc/api/FileSystem.scala b/li/cil/oc/api/FileSystem.scala index 77c83ba68..733bc6b02 100644 --- a/li/cil/oc/api/FileSystem.scala +++ b/li/cil/oc/api/FileSystem.scala @@ -1,5 +1,6 @@ package li.cil.oc.api +import dan200.computer.api.{IWritableMount, IMount} import li.cil.oc.api.detail.FileSystemAPI import li.cil.oc.api.fs.{Mode, Handle} import li.cil.oc.api.network.Node @@ -301,8 +302,8 @@ object FileSystem extends FileSystemAPI { * @param buffered whether data should only be written to disk when saving. * @return a file system wrapping the specified folder. */ - def fromSaveDir(root: String, capacity: Long, buffered: Boolean = true) = - instance.fold(None: Option[FileSystem])(_.fromSaveDir(root, capacity, buffered)) + def fromSaveDirectory(root: String, capacity: Long, buffered: Boolean = true) = + instance.fold(None: Option[FileSystem])(_.fromSaveDirectory(root, capacity, buffered)) /** * Creates a new *writable* file system that resides in memory. @@ -315,8 +316,26 @@ object FileSystem extends FileSystemAPI { * @param capacity the capacity of the file system. * @return a file system residing in memory. */ - def fromRam(capacity: Long): Option[FileSystem] = - instance.fold(None: Option[FileSystem])(_.fromRam(capacity)) + def fromMemory(capacity: Long): Option[FileSystem] = + instance.fold(None: Option[FileSystem])(_.fromMemory(capacity)) + + /** + * Creates a new file system based on a read-only ComputerCraft mount. + * + * @param mount the mount to wrap with a file system. + * @return a file system wrapping the specified mount. + */ + def fromComputerCraft(mount: IMount): Option[FileSystem] = + instance.fold(None: Option[FileSystem])(_.fromComputerCraft(mount)) + + /** + * Creates a new file system based on a read-write ComputerCraft mount. + * + * @param mount the mount to wrap with a file system. + * @return a file system wrapping the specified mount. + */ + def fromComputerCraft(mount: IWritableMount): Option[FileSystem] = + instance.fold(None: Option[FileSystem])(_.fromComputerCraft(mount)) /** * Creates a network node that makes the specified file system available via diff --git a/li/cil/oc/api/detail/FileSystemAPI.scala b/li/cil/oc/api/detail/FileSystemAPI.scala index f50429c7f..4daacdcf0 100644 --- a/li/cil/oc/api/detail/FileSystemAPI.scala +++ b/li/cil/oc/api/detail/FileSystemAPI.scala @@ -2,14 +2,19 @@ package li.cil.oc.api.detail import li.cil.oc.api.FileSystem import li.cil.oc.api.network.Node +import dan200.computer.api.{IMount, IWritableMount} /** Avoids reflection structural types would induce. */ trait FileSystemAPI { def fromClass(clazz: Class[_], domain: String, root: String): Option[FileSystem] - def fromSaveDir(root: String, capacity: Long, buffered: Boolean): Option[FileSystem] + def fromSaveDirectory(root: String, capacity: Long, buffered: Boolean): Option[FileSystem] - def fromRam(capacity: Long): Option[FileSystem] + def fromMemory(capacity: Long): Option[FileSystem] + + def fromComputerCraft(mount: IMount): Option[FileSystem] + + def fromComputerCraft(mount: IWritableMount): Option[FileSystem] def asNode(fs: FileSystem): Option[Node] } \ No newline at end of file diff --git a/li/cil/oc/server/component/Computer.scala b/li/cil/oc/server/component/Computer.scala index b92d801e4..7eed644b9 100644 --- a/li/cil/oc/server/component/Computer.scala +++ b/li/cil/oc/server/component/Computer.scala @@ -69,7 +69,7 @@ class Computer(val owner: Computer.Environment) extends Persistable with Runnabl flatMap(api.FileSystem.asNode) private val tmp = api.FileSystem. - fromRam(512 * 1024). + fromMemory(512 * 1024). flatMap(api.FileSystem.asNode) // ----------------------------------------------------------------------- // diff --git a/li/cil/oc/server/driver/FileSystem.scala b/li/cil/oc/server/driver/FileSystem.scala index 99c8ab311..651ada21c 100644 --- a/li/cil/oc/server/driver/FileSystem.scala +++ b/li/cil/oc/server/driver/FileSystem.scala @@ -22,7 +22,7 @@ object FileSystem extends Item { val address = if (tag.hasKey("address")) tag.getString("address") else java.util.UUID.randomUUID().toString - oc.api.FileSystem.fromSaveDir(address, subItem.megaBytes * 1024 * 1024, Config.filesBuffered). + oc.api.FileSystem.fromSaveDirectory(address, subItem.megaBytes * 1024 * 1024, Config.filesBuffered). flatMap(oc.api.FileSystem.asNode) match { case None => None case Some(node) => diff --git a/li/cil/oc/server/fs/ComputerCraftFileSystem.scala b/li/cil/oc/server/fs/ComputerCraftFileSystem.scala new file mode 100644 index 000000000..d2158edf8 --- /dev/null +++ b/li/cil/oc/server/fs/ComputerCraftFileSystem.scala @@ -0,0 +1,23 @@ +package li.cil.oc.server.fs + +import dan200.computer.api.IMount + +class ComputerCraftFileSystem(val mount: IMount) extends InputStreamFileSystem { + override def exists(path: String) = mount.exists(path) + + override def isDirectory(path: String) = mount.isDirectory(path) + + override def list(path: String) = { + val result = new java.util.ArrayList[String] + mount.list(path, result) + Some(result.toArray.asInstanceOf[Array[String]]) + } + + override def size(path: String) = mount.getSize(path) + + protected def openInputStream(path: String) = try { + Some(mount.openForRead(path)) + } catch { + case _: Throwable => None + } +} diff --git a/li/cil/oc/server/fs/ComputerCraftWritableFileSystem.scala b/li/cil/oc/server/fs/ComputerCraftWritableFileSystem.scala new file mode 100644 index 000000000..f96ea5401 --- /dev/null +++ b/li/cil/oc/server/fs/ComputerCraftWritableFileSystem.scala @@ -0,0 +1,32 @@ +package li.cil.oc.server.fs + +import dan200.computer.api.IWritableMount +import li.cil.oc.api.fs.Mode + +class ComputerCraftWritableFileSystem(override val mount: IWritableMount) + extends ComputerCraftFileSystem(mount) + with OutputStreamFileSystem { + + override protected def makeDirectory(path: String) = try { + mount.makeDirectory(path) + true + } catch { + case _: Throwable => false + } + + override protected def delete(path: String) = try { + mount.delete(path) + true + } catch { + case _: Throwable => false + } + + override protected def openOutputStream(path: String, mode: Mode.Value) = try { + Some(mode match { + case Mode.Append => mount.openForAppend(path) + case Mode.Write => mount.openForWrite(path) + }) + } catch { + case _: Throwable => None + } +} diff --git a/li/cil/oc/server/fs/FileSystem.scala b/li/cil/oc/server/fs/FileSystem.scala index 378786140..ff337403c 100644 --- a/li/cil/oc/server/fs/FileSystem.scala +++ b/li/cil/oc/server/fs/FileSystem.scala @@ -1,5 +1,6 @@ package li.cil.oc.server.fs +import dan200.computer.api.{IWritableMount, IMount} import java.io import java.util.zip.ZipFile import li.cil.oc.server.component @@ -38,7 +39,7 @@ object FileSystem extends api.detail.FileSystemAPI { } } - override def fromSaveDir(root: String, capacity: Long, buffered: Boolean) = { + override def fromSaveDirectory(root: String, capacity: Long, buffered: Boolean) = { val path = new io.File(DimensionManager.getCurrentSaveRootDirectory, Config.savePath + root) path.mkdirs() if (path.exists() && path.isDirectory) { @@ -50,7 +51,11 @@ object FileSystem extends api.detail.FileSystemAPI { else None } - override def fromRam(capacity: Long): Option[api.FileSystem] = Some(new RamFileSystem(capacity)) + override def fromMemory(capacity: Long): Option[api.FileSystem] = Some(new RamFileSystem(capacity)) + + def fromComputerCraft(mount: IMount) = Some(new ComputerCraftFileSystem(mount)) + + def fromComputerCraft(mount: IWritableMount) = Some(new ComputerCraftWritableFileSystem(mount)) override def asNode(fileSystem: api.FileSystem) = Some(new component.FileSystem(fileSystem)) diff --git a/li/cil/oc/server/fs/VirtualFileSystem.scala b/li/cil/oc/server/fs/VirtualFileSystem.scala index 8487d3d69..80722cfef 100644 --- a/li/cil/oc/server/fs/VirtualFileSystem.scala +++ b/li/cil/oc/server/fs/VirtualFileSystem.scala @@ -5,7 +5,7 @@ import li.cil.oc.api.fs.Mode import net.minecraft.nbt.{NBTTagList, NBTTagCompound} import scala.collection.mutable -class VirtualFileSystem extends OutputStreamFileSystem { +trait VirtualFileSystem extends OutputStreamFileSystem { private val root = new VirtualDirectory // ----------------------------------------------------------------------- //