mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-16 02:39:48 -04:00
Extended implementation of switch CC peripheral to properly "fake" connected modems (all the remote stuffs).
This means CC can now call methods on OC peripherals \o/
This commit is contained in:
parent
d3918d39dc
commit
19e39a2f13
@ -5,13 +5,90 @@ import dan200.computercraft.api.peripheral.IComputerAccess
|
|||||||
import dan200.computercraft.api.peripheral.IPeripheral
|
import dan200.computercraft.api.peripheral.IPeripheral
|
||||||
import li.cil.oc.Settings
|
import li.cil.oc.Settings
|
||||||
import li.cil.oc.api
|
import li.cil.oc.api
|
||||||
|
import li.cil.oc.api.machine.Context
|
||||||
|
import li.cil.oc.api.network.Component
|
||||||
import li.cil.oc.common.tileentity.AccessPoint
|
import li.cil.oc.common.tileentity.AccessPoint
|
||||||
import li.cil.oc.common.tileentity.Switch
|
import li.cil.oc.common.tileentity.Switch
|
||||||
import li.cil.oc.util.ResultWrapper._
|
import li.cil.oc.util.ResultWrapper._
|
||||||
|
import net.minecraftforge.common.util.ForgeDirection
|
||||||
|
|
||||||
|
import scala.collection.convert.WrapAsJava._
|
||||||
|
import scala.collection.convert.WrapAsScala._
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
|
|
||||||
class SwitchPeripheral(val switch: Switch) extends IPeripheral {
|
class SwitchPeripheral(val switch: Switch) extends IPeripheral {
|
||||||
|
private val methods = Map[String, (IComputerAccess, ILuaContext, Array[AnyRef]) => Array[AnyRef]](
|
||||||
|
// Generic modem methods.
|
||||||
|
"open" -> ((computer, context, arguments) => {
|
||||||
|
val port = checkPort(arguments, 0)
|
||||||
|
if (switch.openPorts(computer).size >= 128)
|
||||||
|
throw new IllegalArgumentException("too many open channels")
|
||||||
|
result(switch.openPorts(computer).add(port))
|
||||||
|
}),
|
||||||
|
"isOpen" -> ((computer, context, arguments) => {
|
||||||
|
val port = checkPort(arguments, 0)
|
||||||
|
result(switch.openPorts(computer).contains(port))
|
||||||
|
}),
|
||||||
|
"close" -> ((computer, context, arguments) => {
|
||||||
|
val port = checkPort(arguments, 0)
|
||||||
|
result(switch.openPorts(computer).remove(port))
|
||||||
|
}),
|
||||||
|
"closeAll" -> ((computer, context, arguments) => {
|
||||||
|
switch.openPorts(computer).clear()
|
||||||
|
null
|
||||||
|
}),
|
||||||
|
"transmit" -> ((computer, context, arguments) => {
|
||||||
|
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(None, packet))
|
||||||
|
}),
|
||||||
|
"isWireless" -> ((computer, context, arguments) => {
|
||||||
|
result(switch.isInstanceOf[AccessPoint])
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Undocumented modem messages.
|
||||||
|
"callRemote" -> ((computer, context, arguments) => {
|
||||||
|
val address = checkString(arguments, 0)
|
||||||
|
visibleComponents.find(_.address == address) match {
|
||||||
|
case Some(component) =>
|
||||||
|
val method = checkString(arguments, 1)
|
||||||
|
val fakeContext = new CCContext(computer, context)
|
||||||
|
component.invoke(method, fakeContext, arguments.drop(2): _*)
|
||||||
|
case _ => null
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
"getMethodsRemote" -> ((computer, context, arguments) => {
|
||||||
|
val address = checkString(arguments, 0)
|
||||||
|
visibleComponents.find(_.address == address) match {
|
||||||
|
case Some(component) => result(mapAsJavaMap(component.methods.zipWithIndex.map(t => (t._2 + 1, t._1)).toMap))
|
||||||
|
case _ => null
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
"getNamesRemote" -> ((computer, context, arguments) => {
|
||||||
|
result(mapAsJavaMap(visibleComponents.map(_.address).zipWithIndex.map(t => (t._2 + 1, t._1)).toMap))
|
||||||
|
}),
|
||||||
|
"getTypeRemote" -> ((computer, context, arguments) => {
|
||||||
|
val address = checkString(arguments, 0)
|
||||||
|
visibleComponents.find(_.address == address) match {
|
||||||
|
case Some(component) => result(component.name)
|
||||||
|
case _ => null
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
"isPresentRemote" -> ((computer, context, arguments) => {
|
||||||
|
val address = checkString(arguments, 0)
|
||||||
|
result(visibleComponents.exists(_.address == address))
|
||||||
|
}),
|
||||||
|
|
||||||
|
// OC specific.
|
||||||
|
"maxPacketSize" -> ((computer, context, arguments) => {
|
||||||
|
result(Settings.get.maxNetworkPacketSize)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
private val methodNames = methods.keys.toArray.sorted
|
||||||
|
|
||||||
override def getType = "modem"
|
override def getType = "modem"
|
||||||
|
|
||||||
override def attach(computer: IComputerAccess) {
|
override def attach(computer: IComputerAccess) {
|
||||||
@ -24,34 +101,9 @@ class SwitchPeripheral(val switch: Switch) extends IPeripheral {
|
|||||||
switch.openPorts -= computer
|
switch.openPorts -= computer
|
||||||
}
|
}
|
||||||
|
|
||||||
override def getMethodNames = Array("open", "isOpen", "close", "closeAll", "maxPacketSize", "transmit", "isWireless")
|
override def getMethodNames = methodNames
|
||||||
|
|
||||||
override def callMethod(computer: IComputerAccess, context: ILuaContext, method: Int, arguments: Array[AnyRef]) = getMethodNames()(method) match {
|
override def callMethod(computer: IComputerAccess, context: ILuaContext, method: Int, arguments: Array[AnyRef]) = methods(methodNames(method))(computer, context, arguments)
|
||||||
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(None, packet))
|
|
||||||
case "isWireless" => result(switch.isInstanceOf[AccessPoint])
|
|
||||||
case _ => null
|
|
||||||
}
|
|
||||||
|
|
||||||
override def equals(other: IPeripheral) = other match {
|
override def equals(other: IPeripheral) = other match {
|
||||||
case peripheral: SwitchPeripheral => peripheral.switch == switch
|
case peripheral: SwitchPeripheral => peripheral.switch == switch
|
||||||
@ -66,4 +118,41 @@ class SwitchPeripheral(val switch: Switch) extends IPeripheral {
|
|||||||
throw new IllegalArgumentException(s"bad argument #${index + 1} (number in [1, 65535] expected)")
|
throw new IllegalArgumentException(s"bad argument #${index + 1} (number in [1, 65535] expected)")
|
||||||
port
|
port
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def checkString(args: Array[AnyRef], index: Int) = {
|
||||||
|
if (args.length < index - 1 || !args(index).isInstanceOf[String])
|
||||||
|
throw new IllegalArgumentException(s"bad argument #${index + 1} (string expected)")
|
||||||
|
args(index).asInstanceOf[String]
|
||||||
|
}
|
||||||
|
|
||||||
|
private def visibleComponents = {
|
||||||
|
ForgeDirection.VALID_DIRECTIONS.flatMap(side => {
|
||||||
|
val node = switch.sidedNode(side)
|
||||||
|
node.reachableNodes.collect {
|
||||||
|
case component: Component if component.canBeSeenFrom(node) => component
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
class CCContext(val computer: IComputerAccess, val context: ILuaContext) extends Context {
|
||||||
|
override def node() = switch.node
|
||||||
|
|
||||||
|
override def isPaused = false
|
||||||
|
|
||||||
|
override def stop() = false
|
||||||
|
|
||||||
|
override def canInteract(player: String) = true
|
||||||
|
|
||||||
|
override def signal(name: String, args: AnyRef*) = {
|
||||||
|
computer.queueEvent(name, args.toArray)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
override def pause(seconds: Double) = false
|
||||||
|
|
||||||
|
override def isRunning = true
|
||||||
|
|
||||||
|
override def start() = false
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user