blob: 4a2e6ea4d81d8e0611f9ff6ae49a3258bc3885c1 [file] [log] [blame] [raw]
package li.cil.oc.server.component
import dan200.computer.api.{IMount, IWritableMount, IComputerAccess, IPeripheral}
import li.cil.oc.api
import li.cil.oc.api.network._
import li.cil.oc.server.network.{Node => MutableNode}
import net.minecraft.nbt.{NBTTagString, NBTTagCompound}
import scala.collection.convert.WrapAsScala._
import scala.collection.mutable
class Peripheral(peripheral: IPeripheral) extends ManagedComponent with IComputerAccess {
val node = api.Network.newNode(this, Visibility.Network).
withComponent("peripheral").
create()
private val mounts = mutable.Map.empty[String, ManagedEnvironment]
// Used to restore mounts to their previous addresses after save/load.
private val mountAddresses = mutable.Map.empty[String, String]
// ----------------------------------------------------------------------- //
@LuaCallback(value = "getType", asynchronous = true)
def getType(context: Context, args: Arguments): Array[Object] =
result(peripheral.getType)
@LuaCallback(value = "getMethodNames", asynchronous = true)
def getMethodNames(context: Context, args: Arguments): Array[Object] =
peripheral.getMethodNames.map(_.asInstanceOf[AnyRef])
@LuaCallback(value = "callMethod", asynchronous = true)
def callMethod(context: Context, args: Arguments): Array[Object] = {
val method = args.checkInteger(0)
peripheral.callMethod(this, null, method, args.drop(1).map {
case x: Array[Byte] => new String(x, "UTF-8")
case x => x
}.toArray)
}
// ----------------------------------------------------------------------- //
override def onConnect(node: Node) {
super.onConnect(node)
if (node == this.node) {
peripheral.attach(this)
}
}
override def onDisconnect(node: Node) {
super.onDisconnect(node)
if (node == this.node) {
peripheral.detach(this)
for ((_, env) <- mounts) {
env.node.remove()
}
}
}
// ----------------------------------------------------------------------- //
override def load(nbt: NBTTagCompound) {
super.load(nbt)
if (nbt.hasKey("oc.peripheral.addresses")) {
val addressesNbt = nbt.getCompoundTag("oc.peripheral.addresses")
for (tag <- addressesNbt.getTags) tag match {
case addressNbt: NBTTagString =>
mountAddresses += addressNbt.getName -> addressNbt.data
case _ =>
}
}
}
override def save(nbt: NBTTagCompound) {
super.save(nbt)
val addressesNbt = new NBTTagCompound()
for ((location, env) <- mounts) {
addressesNbt.setString(location, env.node.address)
}
nbt.setCompoundTag("oc.peripheral.addresses", addressesNbt)
}
// ----------------------------------------------------------------------- //
def getID = -1
def getAttachmentName = node.address
def queueEvent(event: String, arguments: Array[AnyRef]) {
node.sendToReachable("computer.signal", Seq(event) ++ arguments: _*)
}
def mount(desiredLocation: String, mount: IMount) =
mountFileSystem(desiredLocation, api.FileSystem.fromComputerCraft(mount))
def mountWritable(desiredLocation: String, mount: IWritableMount) =
mountFileSystem(desiredLocation, api.FileSystem.fromComputerCraft(mount))
private def mountFileSystem(desiredLocation: String, fs: api.fs.FileSystem) =
if (!mounts.contains(desiredLocation)) {
val env = api.FileSystem.asManagedEnvironment(fs, desiredLocation)
env.node.asInstanceOf[Component].setVisibility(Visibility.Network)
if (mountAddresses.contains(desiredLocation)) {
env.node.asInstanceOf[MutableNode].address = mountAddresses(desiredLocation)
mountAddresses -= desiredLocation
}
node.connect(env.node)
mounts += desiredLocation -> env
desiredLocation
}
else null
def unmount(location: String) {
mounts.remove(location) match {
case Some(env) =>
mountAddresses -= location
env.node.remove()
case _ =>
}
}
}