diff --git a/src/main/scala/li/cil/oc/common/tileentity/AccessPoint.scala b/src/main/scala/li/cil/oc/common/tileentity/AccessPoint.scala index da385eebc..39f1dac5b 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/AccessPoint.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/AccessPoint.scala @@ -71,8 +71,12 @@ class AccessPoint extends Switch with WirelessEndpoint with traits.PowerAcceptor super.relayPacket(sourceSide, packet) if (strength > 0) { val cost = Settings.get.wirelessCostPerRange - val connector = plugs(sourceSide.ordinal).node.asInstanceOf[Connector] - if (connector.tryChangeBuffer(-strength * cost)) { + val tryChangeBuffer = + if (sourceSide == ForgeDirection.UNKNOWN) + (amount: Double) => plugs.exists(_.node.asInstanceOf[Connector].tryChangeBuffer(amount)) + else + (amount: Double) => plugs(sourceSide.ordinal).node.asInstanceOf[Connector].tryChangeBuffer(amount) + if (tryChangeBuffer(-strength * cost)) { api.Network.sendWirelessPacket(this, strength, packet) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Screen.scala b/src/main/scala/li/cil/oc/common/tileentity/Screen.scala index d3640b405..bc266e302 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Screen.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Screen.scala @@ -59,8 +59,8 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with @SideOnly(Side.CLIENT) override def canConnect(side: ForgeDirection) = toLocal(side) != ForgeDirection.SOUTH - // Allow connections from front for keyboards, just don't render cables as connected... - override def sidedNode(side: ForgeDirection) = node + // Allow connections from front for keyboards, and keyboards only... + override def sidedNode(side: ForgeDirection) = if (toLocal(side) != ForgeDirection.SOUTH || world.getTileEntity(x + side.offsetX, y + side.offsetY, z + side.offsetZ).isInstanceOf[Keyboard]) node else null // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/common/tileentity/Switch.scala b/src/main/scala/li/cil/oc/common/tileentity/Switch.scala index 590f24b2c..a4e9bf989 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Switch.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Switch.scala @@ -1,12 +1,7 @@ package li.cil.oc.common.tileentity import com.google.common.base.Charsets -import cpw.mods.fml.common.Optional -import dan200.computercraft.api.lua.ILuaContext import dan200.computercraft.api.peripheral.IComputerAccess -import dan200.computercraft.api.peripheral.IPeripheral -import li.cil.oc.Settings -import li.cil.oc.api import li.cil.oc.api.Driver import li.cil.oc.api.network.Message import li.cil.oc.api.network.Packet @@ -22,8 +17,7 @@ import net.minecraftforge.common.util.ForgeDirection import scala.collection.mutable -@Optional.Interface(iface = "dan200.computercraft.api.peripheral.IPeripheral", modid = Mods.IDs.ComputerCraft) -class Switch extends traits.Hub with traits.NotAnalyzable with IPeripheral with traits.ComponentInventory { +class Switch extends traits.Hub with traits.NotAnalyzable with traits.ComponentInventory { var lastMessage = 0L val computers = mutable.Buffer.empty[AnyRef] @@ -34,66 +28,6 @@ class Switch extends traits.Hub with traits.NotAnalyzable with IPeripheral with // ----------------------------------------------------------------------- // - @Optional.Method(modid = Mods.IDs.ComputerCraft) - override def getType = "oc_adapter" - - @Optional.Method(modid = Mods.IDs.ComputerCraft) - override def attach(computer: IComputerAccess) { - computers += computer - openPorts += computer -> mutable.Set.empty - } - - @Optional.Method(modid = Mods.IDs.ComputerCraft) - override def detach(computer: IComputerAccess) { - computers -= computer - openPorts -= computer - } - - @Optional.Method(modid = Mods.IDs.ComputerCraft) - override def getMethodNames = Array("open", "isOpen", "close", "closeAll", "maxPacketSize", "transmit", "isWireless") - - @Optional.Method(modid = Mods.IDs.ComputerCraft) - override def callMethod(computer: IComputerAccess, context: ILuaContext, method: Int, arguments: Array[AnyRef]) = getMethodNames()(method) match { - case "open" => - val port = checkPort(arguments, 0) - if (openPorts(computer).size >= 128) - throw new IllegalArgumentException("too many open channels") - result(openPorts(computer).add(port)) - case "isOpen" => - val port = checkPort(arguments, 0) - result(openPorts(computer).contains(port)) - case "close" => - val port = checkPort(arguments, 0) - result(openPorts(computer).remove(port)) - case "closeAll" => - openPorts(computer).clear() - null - case "maxPacketSize" => - result(Settings.get.maxNetworkPacketSize) - case "transmit" => - val sendPort = checkPort(arguments, 0) - val answerPort = checkPort(arguments, 1) - val data = Seq(Int.box(answerPort)) ++ arguments.drop(2) - val packet = api.Network.newPacket(s"cc${computer.getID}_${computer.getAttachmentName}", null, sendPort, data.toArray) - result(tryEnqueuePacket(ForgeDirection.UNKNOWN, packet)) - case "isWireless" => result(this.isInstanceOf[AccessPoint]) - case _ => null - } - - @Optional.Method(modid = Mods.IDs.ComputerCraft) - override def equals(other: IPeripheral) = other == this - - // ----------------------------------------------------------------------- // - - protected def checkPort(args: Array[AnyRef], index: Int) = { - if (args.length < index - 1 || !args(index).isInstanceOf[Double]) - throw new IllegalArgumentException("bad argument #%d (number expected)".format(index + 1)) - val port = args(index).asInstanceOf[Double].toInt - if (port < 1 || port > 0xFFFF) - throw new IllegalArgumentException("bad argument #%d (number in [1, 65535] expected)".format(index + 1)) - port - } - protected def queueMessage(source: String, destination: String, port: Int, answerPort: Int, args: Array[AnyRef]) { for (computer <- computers.map(_.asInstanceOf[IComputerAccess])) { val address = s"cc${computer.getID}_${computer.getAttachmentName}" diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/Hub.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/Hub.scala index 37ad6fbb0..651f9fd9d 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/Hub.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/Hub.scala @@ -80,7 +80,7 @@ trait Hub extends traits.Environment with SidedEnvironment { } } - protected def tryEnqueuePacket(sourceSide: ForgeDirection, packet: Packet) = queue.synchronized { + def tryEnqueuePacket(sourceSide: ForgeDirection, packet: Packet) = queue.synchronized { if (packet.ttl > 0 && queue.size < maxQueueSize) { queue += sourceSide -> packet.hop() if (relayCooldown < 0) { diff --git a/src/main/scala/li/cil/oc/integration/computercraft/SwitchPeripheral.scala b/src/main/scala/li/cil/oc/integration/computercraft/SwitchPeripheral.scala index 71a6337cd..eacda6c65 100644 --- a/src/main/scala/li/cil/oc/integration/computercraft/SwitchPeripheral.scala +++ b/src/main/scala/li/cil/oc/integration/computercraft/SwitchPeripheral.scala @@ -3,12 +3,17 @@ package li.cil.oc.integration.computercraft import dan200.computercraft.api.lua.ILuaContext import dan200.computercraft.api.peripheral.IComputerAccess import dan200.computercraft.api.peripheral.IPeripheral +import li.cil.oc.Settings +import li.cil.oc.api +import li.cil.oc.common.tileentity.AccessPoint import li.cil.oc.common.tileentity.Switch +import li.cil.oc.util.ResultWrapper._ +import net.minecraftforge.common.util.ForgeDirection import scala.collection.mutable class SwitchPeripheral(val switch: Switch) extends IPeripheral { - override def getType = switch.getType + override def getType = "modem" override def attach(computer: IComputerAccess) { switch.computers += computer @@ -20,13 +25,46 @@ class SwitchPeripheral(val switch: Switch) extends IPeripheral { switch.openPorts -= computer } - override def getMethodNames = switch.getMethodNames + override def getMethodNames = Array("open", "isOpen", "close", "closeAll", "maxPacketSize", "transmit", "isWireless") - override def callMethod(computer: IComputerAccess, context: ILuaContext, method: Int, arguments: Array[AnyRef]) = - switch.callMethod(computer, context, method, arguments) + override def callMethod(computer: IComputerAccess, context: ILuaContext, method: Int, arguments: Array[AnyRef]) = getMethodNames()(method) match { + case "open" => + val port = checkPort(arguments, 0) + if (switch.openPorts(computer).size >= 128) + throw new IllegalArgumentException("too many open channels") + result(switch.openPorts(computer).add(port)) + case "isOpen" => + val port = checkPort(arguments, 0) + result(switch.openPorts(computer).contains(port)) + case "close" => + val port = checkPort(arguments, 0) + result(switch.openPorts(computer).remove(port)) + case "closeAll" => + switch.openPorts(computer).clear() + null + case "maxPacketSize" => + result(Settings.get.maxNetworkPacketSize) + case "transmit" => + val sendPort = checkPort(arguments, 0) + val answerPort = checkPort(arguments, 1) + val data = Seq(Int.box(answerPort)) ++ arguments.drop(2) + val packet = api.Network.newPacket(s"cc${computer.getID}_${computer.getAttachmentName}", null, sendPort, data.toArray) + result(switch.tryEnqueuePacket(ForgeDirection.UNKNOWN, packet)) + case "isWireless" => result(switch.isInstanceOf[AccessPoint]) + case _ => null + } override def equals(other: IPeripheral) = other match { case peripheral: SwitchPeripheral => peripheral.switch == switch case _ => false } + + private def checkPort(args: Array[AnyRef], index: Int) = { + if (args.length < index - 1 || !args(index).isInstanceOf[Double]) + throw new IllegalArgumentException("bad argument #%d (number expected)".format(index + 1)) + val port = args(index).asInstanceOf[Double].toInt + if (port < 1 || port > 0xFFFF) + throw new IllegalArgumentException("bad argument #%d (number in [1, 65535] expected)".format(index + 1)) + port + } }