diff --git a/README.md b/README.md index b34deaecf..49567662b 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ In the case you wish to use Eclipse rather than IntelliJ IDEA, the process is mo [api]: https://github.com/MightyPirates/OpenComputers/tree/master-MC1.7.10/src/main/java/li/cil/oc/api [code conventions]: https://ocdoc.cil.li/lua_conventions -[dev-jar]: https://oc.cil.li/index.php?/page/latest.php?repo=OpenComputers-dev-MC1.7.10&type=dev +[dev-jar]: https://ci.cil.li/view/OpenComputers/job/OpenComputers-MC1.7.10/ [forums]: https://oc.cil.li/ [irc]: http://webchat.esper.net/?channels=#oc [issues]: https://github.com/MightyPirates/OpenComputers/issues?state=open @@ -110,4 +110,4 @@ In the case you wish to use Eclipse rather than IntelliJ IDEA, the process is mo [wiki]: https://ocdoc.cil.li/ [integration]: https://github.com/MightyPirates/OpenComputers/tree/master-MC1.7.10/src/main/scala/li/cil/oc/integration [ingame manual]: https://github.com/MightyPirates/OpenComputers/tree/master-MC1.7.10/src/main/resources/assets/opencomputers/doc -[idea_1.7.10]: https://ocdoc.cil.li/tutorial:debug_1.7.10 \ No newline at end of file +[idea_1.7.10]: https://ocdoc.cil.li/tutorial:debug_1.7.10 diff --git a/build.gradle b/build.gradle index 67a584f30..257789d86 100644 --- a/build.gradle +++ b/build.gradle @@ -75,7 +75,7 @@ if (JavaVersion.current().isJava8Compatible()) { repositories { maven { name = "mightypirates" - url = "http://maven.cil.li/" + url = "https://maven.cil.li/" } } diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 247c47f49..ed82cf87a 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -268,6 +268,15 @@ opencomputers { # IN PARTICULAR, DO NOT REPORT ISSUES AFTER MESSING WITH THIS! maxTotalRam: 67108864 } + + # The maximum depth a machine will queue signals before dropping them + # A machine state should be pulling signals via computer.pullSignal + # As the machine receives signals they are queued for pulling, and + # this maximum defines the max queue size. All signals recieved when + # the queue is full are discarded. Note that clipboard text creates + # a signal for each line of text. Thus client are limited to pasting + # text of this many lines. The default (and minimum) is 256 + maxSignalQueueSize: 256 } # Robot related settings, what they may do and general balancing. diff --git a/src/main/resources/assets/opencomputers/loot/network/data/lib/network.lua b/src/main/resources/assets/opencomputers/loot/network/data/lib/network.lua index 1e94e5b78..65de0b0fb 100644 --- a/src/main/resources/assets/opencomputers/loot/network/data/lib/network.lua +++ b/src/main/resources/assets/opencomputers/loot/network/data/lib/network.lua @@ -159,7 +159,7 @@ function internal.tcp.handle(origin, data) end elseif data:sub(2,2) == "A" then local remote = data:byte(3)*256 + data:byte(4) - local ch = data:byte(3)*256 + data:byte(4) + local ch = data:byte(5)*256 + data:byte(6) if internal.tcp.channels[ch] and internal.tcp.channels[ch].waiting then internal.tcp.channels[ch].waiting = nil internal.tcp.channels[ch].open = true diff --git a/src/main/resources/assets/opencomputers/loot/openos/etc/profile.lua b/src/main/resources/assets/opencomputers/loot/openos/etc/profile.lua index 32a945d3b..52e054734 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/etc/profile.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/etc/profile.lua @@ -26,7 +26,7 @@ shell.setAlias("..", "cd ..") shell.setAlias("df", "df -h") shell.setAlias("grep", "grep --color") shell.setAlias("more", "less --noback") -shell.setAlias("reset", "clear; resolution `cat /dev/components/by-type/gpu/0/maxResolution`") +shell.setAlias("reset", "resolution `cat /dev/components/by-type/gpu/0/maxResolution`") os.setenv("EDITOR", "/bin/edit") os.setenv("HISTSIZE", "10") diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/internet.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/internet.lua index c924a0dab..87fe3ea5c 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/internet.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/internet.lua @@ -6,10 +6,11 @@ local internet = {} ------------------------------------------------------------------------------- -function internet.request(url, data, headers) +function internet.request(url, data, headers, method) checkArg(1, url, "string") checkArg(2, data, "string", "table", "nil") checkArg(3, headers, "table", "nil") + checkArg(4, method, "string", "nil") if not component.isAvailable("internet") then error("no primary internet card found", 2) @@ -26,7 +27,7 @@ function internet.request(url, data, headers) end end - local request, reason = inet.request(url, post, headers) + local request, reason = inet.request(url, post, headers, method) if not request then error(reason, 2) end diff --git a/src/main/resources/assets/opencomputers/robot.names b/src/main/resources/assets/opencomputers/robot.names index 7cead7cfa..8ba9c910f 100644 --- a/src/main/resources/assets/opencomputers/robot.names +++ b/src/main/resources/assets/opencomputers/robot.names @@ -80,6 +80,7 @@ Kodos # Contributor Laire # Perry Rhodan Loader 1340 # Borderlands 2 LordFokas # Contributor +Maria # Metropolis Marvin # Hitchhiker's Guide to the Galaxy Mawhrin-skel # The Player of Games (Iain M Banks) Michiyo # Contributor diff --git a/src/main/scala/li/cil/oc/Settings.scala b/src/main/scala/li/cil/oc/Settings.scala index acf150673..bf72e01b8 100644 --- a/src/main/scala/li/cil/oc/Settings.scala +++ b/src/main/scala/li/cil/oc/Settings.scala @@ -338,7 +338,6 @@ class Settings(val config: Config) { val maxScreenWidth = config.getInt("misc.maxScreenWidth") max 1 val maxScreenHeight = config.getInt("misc.maxScreenHeight") max 1 val inputUsername = config.getBoolean("misc.inputUsername") - val maxClipboard = config.getInt("misc.maxClipboard") max 0 val maxNetworkPacketSize = config.getInt("misc.maxNetworkPacketSize") max 0 // Need at least 4 for nanomachine protocol. Because I can! val maxNetworkPacketParts = config.getInt("misc.maxNetworkPacketParts") max 4 @@ -465,6 +464,9 @@ class Settings(val config: Config) { val registerLuaJArchitecture = config.getBoolean("debug.registerLuaJArchitecture") val disableLocaleChanging = config.getBoolean("debug.disableLocaleChanging") + + // >= 1.7.4 + val maxSignalQueueSize: Int = (if (config.hasPath("computer.maxSignalQueueSize")) config.getInt("computer.maxSignalQueueSize") else 256) min 256 } object Settings { diff --git a/src/main/scala/li/cil/oc/common/init/Items.scala b/src/main/scala/li/cil/oc/common/init/Items.scala index abd0aa29c..4960b8bf6 100644 --- a/src/main/scala/li/cil/oc/common/init/Items.scala +++ b/src/main/scala/li/cil/oc/common/init/Items.scala @@ -284,6 +284,7 @@ object Items extends ItemAPI { Option(safeGetStack(Constants.ItemName.PistonUpgrade)), Option(safeGetStack(Constants.BlockName.Geolyzer)), Option(safeGetStack(Constants.ItemName.NavigationUpgrade)), + Option(safeGetStack(Constants.ItemName.Analyzer)), Option(safeGetStack(Constants.ItemName.GraphicsCardTier2)), Option(safeGetStack(Constants.ItemName.RedstoneCardTier2)), diff --git a/src/main/scala/li/cil/oc/common/tileentity/Rack.scala b/src/main/scala/li/cil/oc/common/tileentity/Rack.scala index f12cc0f05..48bd57d21 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Rack.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Rack.scala @@ -132,12 +132,7 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance } } - // ----------------------------------------------------------------------- // - // Hub - - override protected def relayPacket(sourceSide: Option[ForgeDirection], packet: Packet): Unit = { - if (isRelayEnabled) super.relayPacket(sourceSide, packet) - + protected def sendPacketToMountables(sourceSide: Option[ForgeDirection], packet: Packet): Unit = { // When a message arrives on a bus, also send it to all secondary nodes // connected to it. Only deliver it to that very node, if it's not the // sender, to avoid loops. @@ -159,6 +154,22 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance } } + // ----------------------------------------------------------------------- // + // Hub + + override def tryEnqueuePacket(sourceSide: Option[ForgeDirection], packet: Packet): Boolean = { + sendPacketToMountables(sourceSide, packet) + if (isRelayEnabled) + super.tryEnqueuePacket(sourceSide, packet) + else + true + } + + override protected def relayPacket(sourceSide: Option[ForgeDirection], packet: Packet): Unit = { + if (isRelayEnabled) + super.relayPacket(sourceSide, packet) + } + override protected def onPlugConnect(plug: Plug, node: Node): Unit = { super.onPlugConnect(plug, node) connectComponents() 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 b2b1377f4..4c9d303fa 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 @@ -69,8 +69,9 @@ trait Hub extends traits.Environment with SidedEnvironment { else { relayCooldown = -1 if (queue.nonEmpty) queue.synchronized { - packetsPerCycleAvg += queue.size - for (i <- 0 until math.min(queue.size, relayAmount)) { + val packetsToRely = math.min(queue.size, relayAmount) + packetsPerCycleAvg += packetsToRely + for (i <- 0 until packetsToRely) { val (sourceSide, packet) = queue.dequeue() relayPacket(sourceSide, packet) } @@ -96,8 +97,13 @@ trait Hub extends traits.Environment with SidedEnvironment { } protected def relayPacket(sourceSide: Option[ForgeDirection], packet: Packet) { - for (side <- ForgeDirection.VALID_DIRECTIONS if Option(side) != sourceSide && sidedNode(side) != null) { - sidedNode(side).sendToReachable("network.message", packet) + for (side <- ForgeDirection.VALID_DIRECTIONS) { + if (sourceSide.isEmpty || sourceSide.get != side) { + val node = sidedNode(side) + if (node != null) { + node.sendToReachable("network.message", packet) + } + } } } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeBarcodeReader.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeBarcodeReader.scala new file mode 100644 index 000000000..3419caf70 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeBarcodeReader.scala @@ -0,0 +1,27 @@ +package li.cil.oc.integration.opencomputers + +import li.cil.oc.Constants +import li.cil.oc.api.driver.EnvironmentProvider +import li.cil.oc.api +import li.cil.oc.api.driver.item.{HostAware, Slot} +import li.cil.oc.api.network.{EnvironmentHost, ManagedEnvironment} +import li.cil.oc.server.component +import li.cil.oc.server.component.UpgradeBarcodeReader +import net.minecraft.item.ItemStack + +object DriverUpgradeBarcodeReader extends Item with HostAware { + override def worksWith(stack: ItemStack) = isOneOf(stack, + api.Items.get(Constants.ItemName.Analyzer)) + + override def createEnvironment(stack: ItemStack, host: EnvironmentHost): ManagedEnvironment = + new UpgradeBarcodeReader(host) + + override def slot(stack: ItemStack) = Slot.Upgrade + + object Provider extends EnvironmentProvider { + override def getEnvironment(stack: ItemStack): Class[_] = + if (worksWith(stack)) + classOf[component.UpgradeBarcodeReader] + else null + } +} diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala index cfce85a78..a0a27e823 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala @@ -151,6 +151,7 @@ object ModOpenComputers extends ModProxy { api.Driver.add(DriverTerminalServer) api.Driver.add(DriverUpgradeAngel) + api.Driver.add(DriverUpgradeBarcodeReader) api.Driver.add(DriverUpgradeBattery) api.Driver.add(DriverUpgradeChunkloader) api.Driver.add(DriverUpgradeCrafting) @@ -212,6 +213,7 @@ object ModOpenComputers extends ModProxy { Constants.BlockName.ScreenTier1, Constants.BlockName.Transposer, Constants.BlockName.CarpetedCapacitor, + Constants.ItemName.Analyzer, Constants.ItemName.AngelUpgrade, Constants.ItemName.BatteryUpgradeTier1, Constants.ItemName.BatteryUpgradeTier2, @@ -235,6 +237,7 @@ object ModOpenComputers extends ModProxy { Constants.BlockName.ScreenTier1, Constants.BlockName.Transposer, Constants.BlockName.CarpetedCapacitor, + Constants.ItemName.Analyzer, Constants.ItemName.APUTier1, Constants.ItemName.APUTier2, Constants.ItemName.GraphicsCardTier1, @@ -250,6 +253,7 @@ object ModOpenComputers extends ModProxy { Constants.BlockName.Keyboard, Constants.BlockName.ScreenTier1, Constants.BlockName.CarpetedCapacitor, + Constants.ItemName.Analyzer, Constants.ItemName.APUTier1, Constants.ItemName.APUTier2, Constants.ItemName.GraphicsCardTier1, @@ -275,6 +279,7 @@ object ModOpenComputers extends ModProxy { blacklistHost(classOf[internal.Robot], Constants.BlockName.Transposer, Constants.BlockName.CarpetedCapacitor, + Constants.ItemName.Analyzer, Constants.ItemName.LeashUpgrade) blacklistHost(classOf[internal.Tablet], Constants.BlockName.ScreenTier1, diff --git a/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala b/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala index 90824d085..b25316e19 100644 --- a/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala +++ b/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala @@ -100,7 +100,7 @@ class GraphicsCard(val tier: Int) extends prefab.ManagedEnvironment with DeviceI s.setForegroundColor(0xFFFFFF) s.setBackgroundColor(0x000000) } - else context.pause(0.2) // To discourage outputting "in realtime" to multiple screens using one GPU. + else context.pause(0) // To discourage outputting "in realtime" to multiple screens using one GPU. result(true) }) case _ => result(Unit, "not a screen") diff --git a/src/main/scala/li/cil/oc/server/component/InternetCard.scala b/src/main/scala/li/cil/oc/server/component/InternetCard.scala index b9d08a7c6..ba33e2842 100644 --- a/src/main/scala/li/cil/oc/server/component/InternetCard.scala +++ b/src/main/scala/li/cil/oc/server/component/InternetCard.scala @@ -59,7 +59,7 @@ class InternetCard extends prefab.ManagedEnvironment with DeviceInfo { @Callback(direct = true, doc = """function():boolean -- Returns whether HTTP requests can be made (config setting).""") def isHttpEnabled(context: Context, args: Arguments): Array[AnyRef] = result(Settings.get.httpEnabled) - @Callback(doc = """function(url:string[, postData:string[, headers:table]]):userdata -- Starts an HTTP request. If this returns true, further results will be pushed using `http_response` signals.""") + @Callback(doc = """function(url:string[, postData:string[, headers:table[, method:string]]]):userdata -- Starts an HTTP request. If this returns true, further results will be pushed using `http_response` signals.""") def request(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { checkOwner(context) val address = args.checkString(0) @@ -77,7 +77,8 @@ class InternetCard extends prefab.ManagedEnvironment with DeviceInfo { if (!Settings.get.httpHeadersEnabled && headers.nonEmpty) { return result(Unit, "http request headers are unavailable") } - val request = new InternetCard.HTTPRequest(this, checkAddress(address), post, headers) + val method = if (args.isString(3)) Option(args.checkString(3)) else None + val request = new InternetCard.HTTPRequest(this, checkAddress(address), post, headers, method) connections += request result(request) } @@ -363,10 +364,10 @@ object InternetCard { } class HTTPRequest extends AbstractValue with Closable { - def this(owner: InternetCard, url: URL, post: Option[String], headers: Map[String, String]) { + def this(owner: InternetCard, url: URL, post: Option[String], headers: Map[String, String], method: Option[String]) { this() this.owner = Some(owner) - this.stream = threadPool.submit(new RequestSender(url, post, headers)) + this.stream = threadPool.submit(new RequestSender(url, post, headers, method)) } private var owner: Option[InternetCard] = None @@ -465,27 +466,23 @@ object InternetCard { } // This one doesn't (see comment in TCP socket), but I like to keep it consistent. - private class RequestSender(val url: URL, val post: Option[String], val headers: Map[String, String]) extends Callable[InputStream] { + private class RequestSender(val url: URL, val post: Option[String], val headers: Map[String, String], val method: Option[String]) extends Callable[InputStream] { override def call() = try { checkLists(InetAddress.getByName(url.getHost), url.getHost) val proxy = Option(MinecraftServer.getServer.getServerProxy).getOrElse(java.net.Proxy.NO_PROXY) url.openConnection(proxy) match { case http: HttpURLConnection => try { http.setDoInput(true) + http.setDoOutput(post.isDefined) + http.setRequestMethod(if (method.isDefined) method.get else if (post.isDefined) "POST" else "GET") headers.foreach(Function.tupled(http.setRequestProperty)) if (post.isDefined) { - http.setRequestMethod("POST") - http.setDoOutput(true) http.setReadTimeout(Settings.get.httpTimeout) val out = new BufferedWriter(new OutputStreamWriter(http.getOutputStream)) out.write(post.get) out.close() } - else { - http.setRequestMethod("GET") - http.setDoOutput(false) - } val input = http.getInputStream HTTPRequest.this.synchronized { diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeBarcodeReader.scala b/src/main/scala/li/cil/oc/server/component/UpgradeBarcodeReader.scala new file mode 100644 index 000000000..07070ea32 --- /dev/null +++ b/src/main/scala/li/cil/oc/server/component/UpgradeBarcodeReader.scala @@ -0,0 +1,77 @@ +package li.cil.oc.server.component + +import java.util + +import li.cil.oc.{Constants, OpenComputers, api} +import li.cil.oc.api.driver.DeviceInfo +import li.cil.oc.api.driver.DeviceInfo.DeviceAttribute +import li.cil.oc.api.driver.DeviceInfo.DeviceClass +import li.cil.oc.api.internal +import li.cil.oc.api.network._ +import li.cil.oc.api.prefab +import li.cil.oc.util.BlockPosition +import li.cil.oc.util.ExtendedWorld._ +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.NBTTagList +import net.minecraft.util.EnumFacing +import net.minecraft.world.WorldServer +import net.minecraftforge.common.util.ForgeDirection + +import scala.collection.convert.WrapAsJava._ + +class UpgradeBarcodeReader(val host: EnvironmentHost) extends prefab.ManagedEnvironment with DeviceInfo { + override val node = api.Network.newNode(this, Visibility.Network). + withComponent("barcode_reader"). + withConnector(). + create() + + private final lazy val deviceInfo = Map( + DeviceAttribute.Class -> DeviceClass.Generic, + DeviceAttribute.Description -> "Barcode reader upgrade", + DeviceAttribute.Vendor -> Constants.DeviceInfo.DefaultVendor, + DeviceAttribute.Product -> "Readerizer Deluxe" + ) + + override def getDeviceInfo: util.Map[String, String] = deviceInfo + + override def onMessage(message: Message): Unit = { + super.onMessage(message) + if (message.name == "tablet.use") message.source.host match { + case machine: api.machine.Machine => (machine.host, message.data) match { + case (tablet: internal.Tablet, Array(nbt: NBTTagCompound, stack: ItemStack, player: EntityPlayer, blockPos: BlockPosition, side: ForgeDirection, hitX: java.lang.Float, hitY: java.lang.Float, hitZ: java.lang.Float)) => + host.world.getTileEntity(blockPos) match { + case analyzable: Analyzable => + processNodes(analyzable.onAnalyze(player, side.ordinal(), hitX.toFloat, hitY.toFloat, hitZ.toFloat), nbt) + case host: SidedEnvironment => + processNodes(Array(host.sidedNode(side)), nbt) + case host: Environment => + processNodes(Array(host.node), nbt) + } + } + } + } + + private def processNodes(nodes: Array[Node], nbt: NBTTagCompound): Unit = if (nodes != null) { + val readerNBT = new NBTTagList() + + for (node <- nodes if node != null) { + val nodeNBT = new NBTTagCompound() + node match { + case component: Component => + nodeNBT.setString("type", component.name) + case _ => + } + + val address = node.address() + if (address != null && !address.isEmpty) { + nodeNBT.setString("address", node.address()) + } + + readerNBT.appendTag(nodeNBT) + } + + nbt.setTag("analyzed", readerNBT) + } +} diff --git a/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala b/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala index 120d9ebda..587dd1f7e 100644 --- a/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala +++ b/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala @@ -133,12 +133,12 @@ abstract class WirelessNetworkCard(host: EnvironmentHost) extends NetworkCard(ho object WirelessNetworkCard { class Tier1(host: EnvironmentHost) extends WirelessNetworkCard(host) { - override protected def wirelessCostPerRange = Settings.get.wirelessCostPerRange(Tier.One) + override protected def wirelessCostPerRange: Double = Settings.get.wirelessCostPerRange(Tier.One) - override protected def maxWirelessRange = Settings.get.maxWirelessRange(Tier.One) + override protected def maxWirelessRange: Double = Settings.get.maxWirelessRange(Tier.One) // wired network card is before wireless cards in max port list - override protected def maxOpenPorts = Settings.get.maxOpenPorts(Tier.One + 1) + override protected def maxOpenPorts: Int = Settings.get.maxOpenPorts(Tier.One + 1) override protected def shouldSendWiredTraffic = false @@ -157,17 +157,18 @@ object WirelessNetworkCard { override def getDeviceInfo: util.Map[String, String] = deviceInfo - override protected def isPacketAccepted(packet: Packet, distance: Double) = distance != 0 && super.isPacketAccepted(packet, distance) - + override protected def isPacketAccepted(packet: Packet, distance: Double): Boolean = { + (shouldSendWiredTraffic || distance == 0) && super.isPacketAccepted(packet, distance) + } } class Tier2(host: EnvironmentHost) extends Tier1(host) { - override protected def wirelessCostPerRange = Settings.get.wirelessCostPerRange(Tier.Two) + override protected def wirelessCostPerRange: Double = Settings.get.wirelessCostPerRange(Tier.Two) - override protected def maxWirelessRange = Settings.get.maxWirelessRange(Tier.Two) + override protected def maxWirelessRange: Double = Settings.get.maxWirelessRange(Tier.Two) // wired network card is before wireless cards in max port list - override protected def maxOpenPorts = Settings.get.maxOpenPorts(Tier.Two + 1) + override protected def maxOpenPorts: Int = Settings.get.maxOpenPorts(Tier.Two + 1) override protected def shouldSendWiredTraffic = true diff --git a/src/main/scala/li/cil/oc/server/machine/Machine.scala b/src/main/scala/li/cil/oc/server/machine/Machine.scala index 3b536e317..62ea1e770 100644 --- a/src/main/scala/li/cil/oc/server/machine/Machine.scala +++ b/src/main/scala/li/cil/oc/server/machine/Machine.scala @@ -102,6 +102,8 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach private var cost = Settings.get.computerCost * Settings.get.tickFrequency + private val maxSignalQueueSize = Settings.get.maxSignalQueueSize + // ----------------------------------------------------------------------- // override def onHostChanged(): Unit = { @@ -307,30 +309,48 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach } } + def convertArg(param: Any): AnyRef = { + param match { + case arg: java.lang.Boolean => arg + case arg: java.lang.Character => Double.box(arg.toDouble) + case arg: java.lang.Long => arg + case arg: java.lang.Number => Double.box(arg.doubleValue) + case arg: java.lang.String => arg + case arg: Array[Byte] => arg + case arg: NBTTagCompound => arg + case arg => + OpenComputers.log.warn("Trying to push signal with an unsupported argument of type " + arg.getClass.getName) + null + } + } + override def signal(name: String, args: AnyRef*): Boolean = { state.synchronized(state.top match { case Machine.State.Stopped | Machine.State.Stopping => return false case _ => signals.synchronized { - if (signals.size >= 256) return false + if (signals.size >= maxSignalQueueSize) return false else if (args == null) { signals.enqueue(new Machine.Signal(name, Array.empty)) } else { signals.enqueue(new Machine.Signal(name, args.map { case null | Unit | None => null - case arg: java.lang.Boolean => arg - case arg: java.lang.Character => Double.box(arg.toDouble) - case arg: java.lang.Long => arg - case arg: java.lang.Number => Double.box(arg.doubleValue) - case arg: java.lang.String => arg - case arg: Array[Byte] => arg case arg: Map[_, _] if arg.isEmpty || arg.head._1.isInstanceOf[String] && arg.head._2.isInstanceOf[String] => arg case arg: mutable.Map[_, _] if arg.isEmpty || arg.head._1.isInstanceOf[String] && arg.head._2.isInstanceOf[String] => arg.toMap - case arg: java.util.Map[_, _] if arg.isEmpty || arg.head._1.isInstanceOf[String] && arg.head._2.isInstanceOf[String] => arg.toMap - case arg: NBTTagCompound => arg - case arg => - OpenComputers.log.warn("Trying to push signal with an unsupported argument of type " + arg.getClass.getName) - null + case arg: java.util.Map[_, _] => { + val convertedMap = new mutable.HashMap[AnyRef, AnyRef] + for ((key, value) <- arg) { + val convertedKey = convertArg(key) + if (convertedKey != null) { + val convertedValue = convertArg(value) + if (convertedValue != null) { + convertedMap += convertedKey -> convertedValue + } + } + } + convertedMap + } + case arg => convertArg(arg) }.toArray[AnyRef])) } }