diff --git a/src/main/java/li/cil/oc/api/network/Network.java b/src/main/java/li/cil/oc/api/network/Network.java index 3d76f0014..e1d6fa893 100644 --- a/src/main/java/li/cil/oc/api/network/Network.java +++ b/src/main/java/li/cil/oc/api/network/Network.java @@ -103,7 +103,7 @@ public interface Network { Iterable nodes(); /** - * The list of addressed nodes in the network visible to the specified node. + * The list of addressed nodes in the network reachable by the specified node. *

* This does not include nodes with a visibility of None * or a visibility of Neighbors when there is no direct connection diff --git a/src/main/resources/assets/opencomputers/loot/openos/bin/pastebin.lua b/src/main/resources/assets/opencomputers/loot/openos/bin/pastebin.lua index 685428499..b5ff93473 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/bin/pastebin.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/bin/pastebin.lua @@ -21,7 +21,7 @@ local function get(pasteId, filename) end io.write("Downloading from pastebin.com... ") - local url = "http://pastebin.com/raw.php?i=" .. pasteId + local url = "http://pastebin.com/raw/" .. pasteId local result, response = pcall(internet.request, url) if result then io.write("success.\n") diff --git a/src/main/resources/assets/opencomputers/loot/openos/boot/00_base.lua b/src/main/resources/assets/opencomputers/loot/openos/boot/00_base.lua index 87311875c..581584347 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/boot/00_base.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/boot/00_base.lua @@ -15,7 +15,8 @@ function loadfile(filename, mode, env) end table.insert(buffer, data) end - buffer = table.concat(buffer):gsub("^#![^\n]+", "") -- remove shebang if any + buffer[1] = (buffer[1] or ""):gsub("^#![^\n]+", "") -- remove shebang if any + buffer = table.concat(buffer) return load(buffer, "=" .. filename, mode, env) end 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 0b252bb30..c924a0dab 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/internet.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/internet.lua @@ -11,10 +11,10 @@ function internet.request(url, data, headers) checkArg(2, data, "string", "table", "nil") checkArg(3, headers, "table", "nil") - local inet = component.internet - if not inet then + if not component.isAvailable("internet") then error("no primary internet card found", 2) end + local inet = component.internet local post if type(data) == "string" then @@ -31,23 +31,35 @@ function internet.request(url, data, headers) error(reason, 2) end - return function() - while true do - local data, reason = request.read() - if not data then - request.close() - if reason then - error(reason, 2) - else - return nil -- eof + return setmetatable( + { + ["()"] = "function():string -- Tries to read data from the socket stream and return the read byte array.", + close = setmetatable({}, + { + __call = request.close, + __tostring = function() return "function() -- closes the connection" end + }) + }, + { + __call = function() + while true do + local data, reason = request.read() + if not data then + request.close() + if reason then + error(reason, 2) + else + return nil -- eof + end + elseif #data > 0 then + return data end - elseif #data > 0 then - return data + -- else: no data, block + os.sleep(0) end - -- else: no data, block - os.sleep(0) - end - end + end, + __index = request, + }) end ------------------------------------------------------------------------------- diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/term.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/term.lua index 297fbd890..b936ac261 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/term.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/term.lua @@ -390,7 +390,13 @@ function term.drawText(value, wrap, window) local function scroll(_sy,_y) return _sy + term.internal.scroll(window,_y-h), math.min(_y,h) end + local uptime = computer.uptime + local last_sleep = uptime() while index <= vlen do + if uptime() - last_sleep > 4 then + os.sleep(0) + last_sleep = uptime() + end local si,ei = value:find("[\t\r\n\a]", index) si = si or vlen+1 if index==si then @@ -401,7 +407,7 @@ function term.drawText(value, wrap, window) x,y=1,y+1 sy,y = scroll(sy,y) elseif delim=="\a" and not beeped then - require("computer").beep() + computer.beep() beeped = true end cr_last = delim == "\r" diff --git a/src/main/scala/li/cil/oc/Settings.scala b/src/main/scala/li/cil/oc/Settings.scala index 58127f33f..fd54153f2 100644 --- a/src/main/scala/li/cil/oc/Settings.scala +++ b/src/main/scala/li/cil/oc/Settings.scala @@ -652,7 +652,7 @@ object Settings { } def checkAccess(ctxOpt: Option[DebugCard.AccessContext]): Option[String] = ctxOpt match { - case Some(ctx) => values.get(ctx.player) match { + case Some(ctx) => values.get(ctx.player.toLowerCase) match { case Some(x) => if (x == ctx.nonce) None else Some("debug card is invalidated, please re-bind it to yourself") diff --git a/src/main/scala/li/cil/oc/common/item/DebugCard.scala b/src/main/scala/li/cil/oc/common/item/DebugCard.scala index 37ee76e48..70c592ffa 100644 --- a/src/main/scala/li/cil/oc/common/item/DebugCard.scala +++ b/src/main/scala/li/cil/oc/common/item/DebugCard.scala @@ -19,7 +19,7 @@ class DebugCard(val parent: Delegator) extends traits.Delegate { } override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ItemStack = { - if (player.isSneaking) { + if (!world.isRemote && player.isSneaking) { val data = new DebugCardData(stack) val name = player.getName 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 0fe212ccf..90824d085 100644 --- a/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala +++ b/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala @@ -3,13 +3,13 @@ package li.cil.oc.server.component import java.util import li.cil.oc.Constants -import li.cil.oc.api.driver.DeviceInfo.DeviceAttribute -import li.cil.oc.api.driver.DeviceInfo.DeviceClass import li.cil.oc.Localization import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.Network 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.machine.Arguments import li.cil.oc.api.machine.Callback import li.cil.oc.api.machine.Context @@ -72,32 +72,15 @@ class GraphicsCard(val tier: Int) extends prefab.ManagedEnvironment with DeviceI ) def capacityInfo = (maxResolution._1 * maxResolution._2).toString + def widthInfo = Array("1", "4", "8").apply(maxDepth.ordinal()) + def clockInfo = ((2000 / setBackgroundCosts(tier)).toInt / 100).toString + "/" + ((2000 / setForegroundCosts(tier)).toInt / 100).toString + "/" + ((2000 / setPaletteColorCosts(tier)).toInt / 100).toString + "/" + ((2000 / setCosts(tier)).toInt / 100).toString + "/" + ((2000 / copyCosts(tier)).toInt / 100).toString + "/" + ((2000 / fillCosts(tier)).toInt / 100).toString override def getDeviceInfo: util.Map[String, String] = deviceInfo // ----------------------------------------------------------------------- // - override val canUpdate = true - - override def update() { - super.update() - if (node.network != null && screenInstance.isEmpty && screenAddress.isDefined) { - Option(node.network.node(screenAddress.get)) match { - case Some(node: Node) if node.host.isInstanceOf[api.internal.TextBuffer] => - screenInstance = Some(node.host.asInstanceOf[api.internal.TextBuffer]) - case _ => - // This could theoretically happen after loading an old address, but - // if the screen either disappeared between saving and now or changed - // type. The first scenario is more likely, and could happen if the - // chunk the screen is in isn't loaded when the chunk the GPU is in - // gets loaded. - screenAddress = None - } - } - } - @Callback(doc = """function(address:string[, reset:boolean=true]):boolean -- Binds the GPU to the screen with the specified address and resets screen settings if `reset` is true.""") def bind(context: Context, args: Arguments): Array[AnyRef] = { val address = args.checkString(0) @@ -395,6 +378,17 @@ class GraphicsCard(val tier: Int) extends prefab.ManagedEnvironment with DeviceI } } + override def onConnect(node: Node): Unit = { + super.onConnect(node) + if (screenInstance.isEmpty && screenAddress.fold(false)(_ == node.address)) { + node.host match { + case buffer: api.internal.TextBuffer => + screenInstance = Some(buffer) + case _ => // Not the screen node we're looking for. + } + } + } + override def onDisconnect(node: Node) { super.onDisconnect(node) if (node == this.node || screenAddress.contains(node.address)) { diff --git a/src/main/scala/li/cil/oc/server/network/Network.scala b/src/main/scala/li/cil/oc/server/network/Network.scala index 82453c368..fae5c759e 100644 --- a/src/main/scala/li/cil/oc/server/network/Network.scala +++ b/src/main/scala/li/cil/oc/server/network/Network.scala @@ -160,12 +160,20 @@ private class Network private(private val data: mutable.Map[String, Network.Vert def nodes: Iterable[ImmutableNode] = data.values.map(_.data) - def nodes(reference: ImmutableNode): Iterable[ImmutableNode] = { + def reachableNodes(reference: ImmutableNode): Iterable[ImmutableNode] = { val referenceNeighbors = neighbors(reference).toSet nodes.filter(node => node != reference && (node.reachability == Visibility.Network || (node.reachability == Visibility.Neighbors && referenceNeighbors.contains(node)))) } + def reachingNodes(reference: ImmutableNode): Iterable[ImmutableNode] = { + if (reference.reachability == Visibility.Network) nodes.filter(node => node != reference) + else if (reference.reachability == Visibility.Neighbors) { + val referenceNeighbors = neighbors(reference).toSet + nodes.filter(node => node != reference && referenceNeighbors.contains(node)) + } else Iterable.empty + } + def neighbors(node: ImmutableNode): Iterable[ImmutableNode] = { data.get(node.address) match { case Some(n) if n.data == node => n.edges.map(_.other(n).data) @@ -194,13 +202,13 @@ private class Network private(private val data: mutable.Map[String, Network.Vert def sendToReachable(source: ImmutableNode, name: String, args: AnyRef*) = { if (source.network != wrapper) throw new IllegalArgumentException("Source node must be in this network.") - send(source, nodes(source), name, args: _*) + send(source, reachableNodes(source), name, args: _*) } def sendToVisible(source: ImmutableNode, name: String, args: AnyRef*) = { if (source.network != wrapper) throw new IllegalArgumentException("Source node must be in this network.") - send(source, nodes(source) collect { + send(source, reachableNodes(source) collect { case component: api.network.Component if component.canBeSeenFrom(source) => component }, name, args: _*) } @@ -236,11 +244,11 @@ private class Network private(private val data: mutable.Map[String, Network.Vert connects += ((addedNode, Iterable(addedNode))) case Visibility.Neighbors => connects += ((addedNode, Iterable(addedNode) ++ neighbors(addedNode))) - nodes(addedNode).foreach(node => connects += ((node, Iterable(addedNode)))) + reachingNodes(addedNode).foreach(node => connects += ((node, Iterable(addedNode)))) case Visibility.Network => // Explicitly send to the added node itself first. connects += ((addedNode, Iterable(addedNode) ++ nodes.filter(_ != addedNode))) - nodes(addedNode).foreach(node => connects += ((node, Iterable(addedNode)))) + reachingNodes(addedNode).foreach(node => connects += ((node, Iterable(addedNode)))) } } else { @@ -746,7 +754,7 @@ object Network extends api.detail.NetworkAPI { def nodes = network.nodes.asJava - def nodes(reference: ImmutableNode) = network.nodes(reference).asJava + def nodes(reference: ImmutableNode) = network.reachableNodes(reference).asJava def neighbors(node: ImmutableNode) = network.neighbors(node).asJava