|  | package li.cil.oc.server.driver.item | 
|  |  | 
|  | import dan200.computer.api.IMedia | 
|  | import li.cil.oc | 
|  | import li.cil.oc.api.driver.Slot | 
|  | import li.cil.oc.api.fs.Label | 
|  | import li.cil.oc.common.item.{FloppyDisk, HardDiskDrive} | 
|  | import li.cil.oc.common.tileentity.TileEntity | 
|  | import li.cil.oc.util.mods.ComputerCraft | 
|  | import li.cil.oc.{Settings, Items} | 
|  | import net.minecraft.item.ItemStack | 
|  | import net.minecraft.nbt.NBTTagCompound | 
|  | import net.minecraft.tileentity.{TileEntity => MCTileEntity} | 
|  |  | 
|  | object FileSystem extends Item { | 
|  | override def worksWith(stack: ItemStack) = isOneOf(stack, Items.hdd1, Items.hdd2, Items.hdd3, Items.floppyDisk) || ComputerCraft.isDisk(stack) | 
|  |  | 
|  | override def createEnvironment(stack: ItemStack, container: MCTileEntity) = | 
|  | if (ComputerCraft.isDisk(stack)) { | 
|  | container match { | 
|  | case tileEntity: TileEntity => | 
|  | val address = addressFromTag(dataTag(stack)) | 
|  | val mount = ComputerCraft.createDiskMount(stack, tileEntity.world) | 
|  | Option(oc.api.FileSystem.asManagedEnvironment(mount, new ComputerCraftLabel(stack))) match { | 
|  | case Some(environment) => | 
|  | environment.node.asInstanceOf[oc.server.network.Node].address = address | 
|  | environment | 
|  | case _ => null | 
|  | } | 
|  | case _ => null | 
|  | } | 
|  | } else Items.multi.subItem(stack) match { | 
|  | case Some(hdd: HardDiskDrive) => createEnvironment(stack, hdd.kiloBytes * 1024) | 
|  | case Some(disk: FloppyDisk) => createEnvironment(stack, Settings.get.floppySize * 1024) | 
|  | case _ => null | 
|  | } | 
|  |  | 
|  | override def slot(stack: ItemStack) = | 
|  | if (ComputerCraft.isDisk(stack)) Slot.Disk | 
|  | else Items.multi.subItem(stack) match { | 
|  | case Some(hdd: HardDiskDrive) => Slot.HardDiskDrive | 
|  | case Some(disk: FloppyDisk) => Slot.Disk | 
|  | case _ => throw new IllegalArgumentException() | 
|  | } | 
|  |  | 
|  | override def tier(stack: ItemStack) = | 
|  | Items.multi.subItem(stack) match { | 
|  | case Some(hdd: HardDiskDrive) => hdd.tier | 
|  | case _ => 0 | 
|  | } | 
|  |  | 
|  | private def createEnvironment(stack: ItemStack, capacity: Int) = { | 
|  | // We have a bit of a chicken-egg problem here, because we want to use the | 
|  | // node's address as the folder name... so we generate the address here, | 
|  | // if necessary. No one will know, right? Right!? | 
|  | val address = addressFromTag(dataTag(stack)) | 
|  | Option(oc.api.FileSystem.asManagedEnvironment(oc.api.FileSystem. | 
|  | fromSaveDirectory(address, capacity, Settings.get.bufferChanges), new ItemLabel(stack))) match { | 
|  | case Some(environment) => | 
|  | environment.node.asInstanceOf[oc.server.network.Node].address = address | 
|  | environment | 
|  | case _ => null | 
|  | } | 
|  | } | 
|  |  | 
|  | private def addressFromTag(tag: NBTTagCompound) = | 
|  | if (tag.hasKey("node") && tag.getCompoundTag("node").hasKey("address")) { | 
|  | tag.getCompoundTag("node").getString("address") | 
|  | } | 
|  | else java.util.UUID.randomUUID().toString | 
|  |  | 
|  | private class ComputerCraftLabel(val stack: ItemStack) extends Label { | 
|  | val media = stack.getItem.asInstanceOf[IMedia] | 
|  |  | 
|  | def getLabel = media.getLabel(stack) | 
|  |  | 
|  | def setLabel(value: String) { | 
|  | media.setLabel(stack, value) | 
|  | } | 
|  | } | 
|  |  | 
|  | private class ItemLabel(val stack: ItemStack) extends Label { | 
|  | def getLabel = | 
|  | if (dataTag(stack).hasKey(Settings.namespace + "fs.label")) | 
|  | dataTag(stack).getString(Settings.namespace + "fs.label") | 
|  | else null | 
|  |  | 
|  | def setLabel(value: String) { | 
|  | dataTag(stack).setString(Settings.namespace + "fs.label", | 
|  | if (value.length > 16) value.substring(0, 16) else value) | 
|  | } | 
|  | } | 
|  |  | 
|  | } |