Fixed crash in access point.

This commit is contained in:
Florian Nücke 2014-10-14 14:07:26 +02:00
parent c170b2f09f
commit 509cb26e6f
5 changed files with 52 additions and 76 deletions

View File

@ -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)
}
}

View File

@ -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
// ----------------------------------------------------------------------- //

View File

@ -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}"

View File

@ -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) {

View File

@ -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
}
}