mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-18 03:36:47 -04:00
Context.address is now deprecated in favor of the new Context.node getter; emulating peripheral file system mounting; catching any errors in connect and disconnect callbacks
This commit is contained in:
parent
110d15ff50
commit
597770dd1b
@ -7,9 +7,17 @@ package li.cil.oc.api.network;
|
||||
public interface Context {
|
||||
/**
|
||||
* The network address of the computer.
|
||||
*
|
||||
* @deprecated Use <tt>node().address()</tt> instead.
|
||||
*/
|
||||
@Deprecated
|
||||
String address();
|
||||
|
||||
/**
|
||||
* The node through which the computer is attached to the component network.
|
||||
*/
|
||||
Node node();
|
||||
|
||||
/**
|
||||
* Tests whether a player is allowed to use the computer.
|
||||
* <p/>
|
||||
|
@ -2,9 +2,12 @@ package li.cil.oc.api.prefab;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import dan200.computer.api.*;
|
||||
import li.cil.oc.api.FileSystem;
|
||||
import li.cil.oc.api.Network;
|
||||
import li.cil.oc.api.network.Arguments;
|
||||
import li.cil.oc.api.network.Context;
|
||||
import li.cil.oc.api.network.Node;
|
||||
import li.cil.oc.api.network.Visibility;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@ -25,6 +28,7 @@ public class ManagedPeripheral extends ManagedEnvironment implements li.cil.oc.a
|
||||
public ManagedPeripheral(final IPeripheral peripheral) {
|
||||
this.peripheral = peripheral;
|
||||
_methods = Arrays.asList(peripheral.getMethodNames());
|
||||
node = Network.newNode(this, Visibility.Network).create();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -45,8 +49,8 @@ public class ManagedPeripheral extends ManagedEnvironment implements li.cil.oc.a
|
||||
}
|
||||
}
|
||||
final FakeComputerAccess access;
|
||||
if (accesses.containsKey(context.address())) {
|
||||
access = accesses.get(context.address());
|
||||
if (accesses.containsKey(context.node().address())) {
|
||||
access = accesses.get(context.node().address());
|
||||
} else {
|
||||
// The calling contexts is not visible to us, meaning we never got
|
||||
// an onConnect for it. Create a temporary access.
|
||||
@ -76,6 +80,7 @@ public class ManagedPeripheral extends ManagedEnvironment implements li.cil.oc.a
|
||||
} else if (node == this.node) {
|
||||
for (FakeComputerAccess access : accesses.values()) {
|
||||
peripheral.detach(access);
|
||||
access.close();
|
||||
}
|
||||
accesses.clear();
|
||||
}
|
||||
@ -87,30 +92,53 @@ public class ManagedPeripheral extends ManagedEnvironment implements li.cil.oc.a
|
||||
private static class FakeComputerAccess implements IComputerAccess {
|
||||
protected final ManagedPeripheral owner;
|
||||
protected final Context context;
|
||||
protected final Map<String, li.cil.oc.api.network.ManagedEnvironment> fileSystems = new HashMap<String, li.cil.oc.api.network.ManagedEnvironment>();
|
||||
|
||||
public FakeComputerAccess(final ManagedPeripheral owner, final Context context) {
|
||||
this.owner = owner;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
for (li.cil.oc.api.network.ManagedEnvironment fileSystem : fileSystems.values()) {
|
||||
fileSystem.node().remove();
|
||||
}
|
||||
fileSystems.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mount(final String desiredLocation, final IMount mount) {
|
||||
throw new UnsupportedOperationException();
|
||||
if (fileSystems.containsKey(desiredLocation)) {
|
||||
return null;
|
||||
}
|
||||
return mount(desiredLocation, FileSystem.asManagedEnvironment(FileSystem.fromComputerCraft(mount)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mountWritable(final String desiredLocation, final IWritableMount mount) {
|
||||
throw new UnsupportedOperationException();
|
||||
if (fileSystems.containsKey(desiredLocation)) {
|
||||
return null;
|
||||
}
|
||||
return mount(desiredLocation, FileSystem.asManagedEnvironment(FileSystem.fromComputerCraft(mount)));
|
||||
}
|
||||
|
||||
private String mount(final String path, final li.cil.oc.api.network.ManagedEnvironment fileSystem) {
|
||||
fileSystems.put(path, fileSystem);
|
||||
context.node().connect(fileSystem.node());
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unmount(final String location) {
|
||||
throw new UnsupportedOperationException();
|
||||
final li.cil.oc.api.network.ManagedEnvironment fileSystem = fileSystems.remove(location);
|
||||
if (fileSystem != null) {
|
||||
fileSystem.node().remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getID() {
|
||||
return context.address().hashCode();
|
||||
return context.node().address().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -65,7 +65,7 @@ class Terminal(val parent: Delegator) extends Delegate {
|
||||
rack.terminals(slot).key = Some(key)
|
||||
ServerPacketSender.sendServerState(rack, slot)
|
||||
stack.getTagCompound.setString(Settings.namespace + "key", key)
|
||||
stack.getTagCompound.setString(Settings.namespace + "server", server.machine.address)
|
||||
stack.getTagCompound.setString(Settings.namespace + "server", server.machine.node.address)
|
||||
player.inventory.onInventoryChanged()
|
||||
case _ => // Huh?
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ abstract class Computer(isRemote: Boolean) extends Environment with ComponentInv
|
||||
|
||||
override protected def onRedstoneInputChanged(side: ForgeDirection) {
|
||||
super.onRedstoneInputChanged(side)
|
||||
computer.signal("redstone_changed", computer.address, Int.box(toLocal(side).ordinal()))
|
||||
computer.signal("redstone_changed", computer.node.address, Int.box(toLocal(side).ordinal()))
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
@ -248,7 +248,7 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
|
||||
override def writeToNBTForClient(nbt: NBTTagCompound) {
|
||||
super.writeToNBTForClient(nbt)
|
||||
nbt.setByteArray("isServerRunning", _isRunning.map(value => (if (value) 1 else 0).toByte))
|
||||
nbt.setNewTagList("isPresent", servers.map(value => new NBTTagString(null, value.fold("")(_.machine.address))))
|
||||
nbt.setNewTagList("isPresent", servers.map(value => new NBTTagString(null, value.fold("")(_.machine.node.address))))
|
||||
nbt.setByteArray("sides", sides.map(_.ordinal.toByte))
|
||||
nbt.setNewTagList("terminals", terminals.map(t => {
|
||||
val terminalNbt = new NBTTagCompound()
|
||||
@ -324,7 +324,7 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
|
||||
override protected def onRedstoneInputChanged(side: ForgeDirection) {
|
||||
super.onRedstoneInputChanged(side)
|
||||
servers collect {
|
||||
case Some(server) => server.machine.signal("redstone_changed", server.machine.address, Int.box(toLocal(side).ordinal()))
|
||||
case Some(server) => server.machine.signal("redstone_changed", server.machine.node.address, Int.box(toLocal(side).ordinal()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ package li.cil.oc.common.tileentity
|
||||
|
||||
import cpw.mods.fml.common.Optional
|
||||
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
||||
import li.cil.oc.{Settings, api}
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.Network
|
||||
import li.cil.oc.api.network._
|
||||
import li.cil.oc.client.gui
|
||||
@ -67,7 +67,7 @@ class RobotProxy(val robot: Robot) extends Computer(robot.isClient) with ISidedI
|
||||
// Use the same address we use internally on the outside.
|
||||
if (isServer) {
|
||||
val nbt = new NBTTagCompound()
|
||||
nbt.setString("address", robot.address)
|
||||
nbt.setString("address", robot.node.address)
|
||||
node.load(nbt)
|
||||
}
|
||||
Network.joinOrCreateNetwork(this)
|
||||
|
@ -292,7 +292,7 @@ object PacketSender {
|
||||
t.servers.foreach {
|
||||
case Some(server) =>
|
||||
pb.writeBoolean(true)
|
||||
pb.writeUTF(server.machine.address)
|
||||
pb.writeUTF(server.machine.node.address)
|
||||
case _ =>
|
||||
pb.writeBoolean(false)
|
||||
}
|
||||
|
@ -20,7 +20,10 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label) extends ManagedC
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
@Callback(direct = true)
|
||||
def getLabel(context: Context, args: Arguments): Array[AnyRef] = result(label.getLabel)
|
||||
def getLabel(context: Context, args: Arguments): Array[AnyRef] = label match {
|
||||
case value: Label => result(label.getLabel)
|
||||
case _ => null
|
||||
}
|
||||
|
||||
@Callback
|
||||
def setLabel(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
@ -101,7 +104,7 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label) extends ManagedC
|
||||
val handle = args.checkInteger(0)
|
||||
Option(fileSystem.getHandle(handle)) match {
|
||||
case Some(file) =>
|
||||
owners.get(context.address) match {
|
||||
owners.get(context.node.address) match {
|
||||
case Some(set) if set.remove(handle) => file.close()
|
||||
case _ => throw new IOException("bad file descriptor")
|
||||
}
|
||||
@ -112,14 +115,14 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label) extends ManagedC
|
||||
|
||||
@Callback
|
||||
def open(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
if (owners.get(context.address).fold(false)(_.size >= Settings.get.maxHandles)) {
|
||||
if (owners.get(context.node.address).fold(false)(_.size >= Settings.get.maxHandles)) {
|
||||
throw new IOException("too many open handles")
|
||||
}
|
||||
val path = args.checkString(0)
|
||||
val mode = if (args.count > 1) args.checkString(1) else "r"
|
||||
val handle = fileSystem.open(clean(path), parseMode(mode))
|
||||
if (handle > 0) {
|
||||
owners.getOrElseUpdate(context.address, mutable.Set.empty[Int]) += handle
|
||||
owners.getOrElseUpdate(context.node.address, mutable.Set.empty[Int]) += handle
|
||||
}
|
||||
result(handle)
|
||||
}
|
||||
@ -128,7 +131,7 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label) extends ManagedC
|
||||
def read(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val handle = args.checkInteger(0)
|
||||
val n = math.min(Settings.get.maxReadBuffer, math.max(0, args.checkInteger(1)))
|
||||
checkOwner(context.address, handle)
|
||||
checkOwner(context.node.address, handle)
|
||||
Option(fileSystem.getHandle(handle)) match {
|
||||
case Some(file) =>
|
||||
// Limit size of read buffer to avoid crazy allocations.
|
||||
@ -160,7 +163,7 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label) extends ManagedC
|
||||
val handle = args.checkInteger(0)
|
||||
val whence = args.checkString(1)
|
||||
val offset = args.checkInteger(2)
|
||||
checkOwner(context.address, handle)
|
||||
checkOwner(context.node.address, handle)
|
||||
Option(fileSystem.getHandle(handle)) match {
|
||||
case Some(file) =>
|
||||
whence match {
|
||||
@ -181,7 +184,7 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label) extends ManagedC
|
||||
if (!node.tryChangeBuffer(-Settings.get.hddWriteCost * value.length)) {
|
||||
throw new IOException("not enough energy")
|
||||
}
|
||||
checkOwner(context.address, handle)
|
||||
checkOwner(context.node.address, handle)
|
||||
Option(fileSystem.getHandle(handle)) match {
|
||||
case Some(file) => file.write(value); result(true)
|
||||
case _ => throw new IOException("bad file descriptor")
|
||||
|
@ -49,7 +49,7 @@ class InternetCard(val owner: Context) extends ManagedComponent {
|
||||
|
||||
@Callback
|
||||
def request(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
if (context.address != owner.address) {
|
||||
if (context.node.address != owner.node.address) {
|
||||
throw new IllegalArgumentException("can only be used by the owning computer")
|
||||
}
|
||||
val address = args.checkString(0)
|
||||
@ -235,7 +235,7 @@ class InternetCard(val owner: Context) extends ManagedComponent {
|
||||
override def onMessage(message: Message) {
|
||||
super.onMessage(message)
|
||||
message.data match {
|
||||
case Array() if (message.name == "computer.stopped" || message.name == "computer.started") && message.source.address == owner.address =>
|
||||
case Array() if (message.name == "computer.stopped" || message.name == "computer.started") && message.source.address == owner.node.address =>
|
||||
connections.values.foreach(_.close())
|
||||
connections.clear()
|
||||
InternetCard.this.synchronized {
|
||||
|
@ -483,8 +483,10 @@ class Machine(val owner: Machine.Owner) extends ManagedComponent with Context wi
|
||||
val invalid = mutable.Set.empty[String]
|
||||
for ((address, name) <- components) {
|
||||
if (node.network.node(address) == null) {
|
||||
OpenComputers.log.warning("A component of type '" + name +
|
||||
"' disappeared! This usually means that it didn't save its node.")
|
||||
OpenComputers.log.fine("A component of type '%s' disappeared! This usually means that it didn't save its node.".format(name))
|
||||
if (name == "filesystem") {
|
||||
OpenComputers.log.fine("If this was a file system provided by a ComputerCraft peripheral, this is normal.");
|
||||
}
|
||||
signal("component_removed", address, name)
|
||||
invalid += address
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
package li.cil.oc.server.network
|
||||
|
||||
import li.cil.oc.api
|
||||
import java.util.logging.Level
|
||||
import li.cil.oc.api.network.{Environment, Visibility, Node => ImmutableNode}
|
||||
import li.cil.oc.{OpenComputers, api}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import scala.collection.convert.WrapAsJava._
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
@ -43,11 +44,19 @@ trait Node extends ImmutableNode {
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def onConnect(node: ImmutableNode) {
|
||||
host.onConnect(node)
|
||||
try {
|
||||
host.onConnect(node)
|
||||
} catch {
|
||||
case e: Throwable => OpenComputers.log.log(Level.WARNING, "A component of type '%s' threw an error while being connected to the component network.".format(host.getClass.getName), e)
|
||||
}
|
||||
}
|
||||
|
||||
def onDisconnect(node: ImmutableNode) {
|
||||
host.onDisconnect(node)
|
||||
try {
|
||||
host.onDisconnect(node)
|
||||
} catch {
|
||||
case e: Throwable => OpenComputers.log.log(Level.WARNING, "A component of type '%s' threw an error while being disconnected from the component network.".format(host.getClass.getName), e)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
Loading…
x
Reference in New Issue
Block a user