**This is an old revision of the document!**

信号

信号是一些外部源发送给计算机的信息,可被用于各种用途。它们需要至少有个名字,然后还可以有任意数量的(简单)参数。注意,电脑也可以向自己的信号队列中添加信号。

信号可以通过调用 computer.pullSignal() 或它的简单封装 event.pull() 来消耗。

下面列出了所有由组件和内置库触发的信号。它们由以下格式列出:name(arg: type, ...),你可以像 local name, arg, ... = event.pull() 这样拉取它们。例如,要拉取一条调制解调器的消息:

snippet.lua
local event = require("event")
local _, localNetworkCard, remoteAddress, port, distance, payload = event.pull("modem_message")
print("在网卡 ‘" .. localNetworkCard .. "’ 的 ‘" .. port .. "’ 端口上收到来自 ‘" .. remoteAddress .. "’ 地址的数据:" .. tostring(payload))
if distance > 0 then
  print("消息来自 " .. distance .. " 格远。")
end

电脑

  • component_added(address: string, componentType: string)
    当一个新的组件连接到系统时,电脑机器人会将这个信号加入信号队列。address 是新加入的组件的地址,componentType 是组件的类型(如 redstonegpu)。
    注意:请尽可能不要直接使用这个信号,而是用 component_available 代替,后者会在首选组件被添加或改变时,被component(组件) 库加入信号队列。
  • component_removed(address: string, componentType: string)
    当一个组件被从系统中移除时,电脑机器人会将这个信号加入信号队列。address 是被移除的组件的地址,componentType 是组件的类型(如 redstonegpu)。
    注意:请尽可能不要直接使用这个信号,而是用 component_unavailable 代替,后者会在首选组件被移除时,被component(组件) 库加入信号队列。
  • component_available(componentType: string)
    首选组件被添加或改变时,component(组件) 库会将这个信号加入信号队列。一般来说,最好使用它而不是 component_added,以免与组件库冲突。
  • component_unavailable(componentType: string)
    首选组件被移除时,component(组件) 库会将这个信号加入信号队列。一般来说,最好使用它而不是 component_removed,以免与组件库冲突。
  • term_available()
    当电脑的 GPU 屏幕变得都可用时,term(终端) 库会将这个信号加入信号队列。这对于确定现在是否可以将文本输出到连接的屏幕上有很大帮助。
  • term_unavailable()
    当电脑的 GPU 屏幕的其中任意一个变得不可用时,term(终端) 库会将这个信号加入信号队列。这对于确定现在是否可以将文本输出到连接的屏幕上有很大帮助。

屏幕

  • screen_resized(screenAddress: string, newWidth: number, newHeight: number)
    当分辨率发生变化时,对应的屏幕会将这个信号加入信号队列,例如分辨率被通过 GPU 手动修改时。screenAddress 是产生信号的屏幕的地址。
  • touch(screenAddress: string, x: number, y: number, button: number, playerName: string)
    这个信号会在二级或三级屏幕被点击时触发。这包括左键点击 GUI(连接键盘时)或在世界中直接右键点击或激活它们(没有键盘连接或潜行交互时)。screenAddress 是产生信号的屏幕的地址。xy 的坐标数值是以“字母”为单位的(这意味着它直接映射到 term.setCursorgpu.set)。playerName 是触发这个事件的玩家的名字。 关于玩家名的说明:我可能会在将来添加一个配置项来禁用这个参数,因为有些人认为这太……不真实了。它对多用户程序很方便,因此我暂时保留了它。 重要:这个信号是经过核查,也就是说,只有当玩家是该电脑的登记用户(或该电脑没有登记任何用户)时,信号才会入队。
  • drag(screenAddress: string, x: number, y: number, button: number, playerName: string)
    这个信号几乎等同于 touch 信号,唯一隐含的区别是: 当这个信号被触发时,它是“属于”先前已被触发的 touch 信号的。此信号只能通过在GUI中进行拖动来触发。
  • drop(screenAddress: string, x: number, y: number, button: number, playerName: string)
    这个信号在玩家触发 touch 后松开鼠标时被触发。尽管它叫这个名字,但它不一定在 drag 信号之后。
  • scroll(screenAddress: string, x: number, y: number, direction: number, playerName: string)
    当玩家在二级或三级屏幕的 GUI 中使用鼠标滚轮时,该屏幕会将这个信号加入信号队列。xy 坐标数值为滚动时鼠标光标的位置。跟 touch 信号一样,坐标以“字母”为单位。direction 表示滚动的方向,正数代表“向上”,负数代表“向下”。注意,这可能会根据游戏客户端的操作系统或驱动配置而有所不同。playerName 是触发该事件的玩家的名字。 这里有与 touch 中相同的关于玩家名的考虑。
  • walk(screenAddress: string, x: number, y: number[, playerName: string])
    当玩家或其他实体在二级或三级屏幕上行走时,该屏幕会将这个信号加入信号队列。screenAddress 是产生信号的屏幕的地址。xy 坐标是当屏幕为多方块屏幕时子方块的坐标。使用 gpu.getSize() 可以计算出实际上代表了显示器的哪个区域。 与点击不同的是,根据当前的分辨率,这个信号可能会被屏幕上没有任何显示的区域触发,所以要记住这一点。 这里有与 touch 中相同的关于玩家名的考虑。

键盘

  • key_down(keyboardAddress: string, char: number, code: number, playerName: string)
    当用户在屏幕上输入东西时,其附着的键盘会将这个信号添加到信号队列。准确来说,应该是当用户按下一个键时。如果用户一直按着这个键,这个事件可能会被重复触发。 重要:这个信号是经过核查,也就是说,只有当玩家是该电脑的登记用户(或该电脑没有登记任何用户)时,信号才会入队。
  • key_up(keyboardAddress: string, char: number, code: number, playerName: string)
    当用户在屏幕上输入东西时,其连接的键盘会将这个信号添加到信号队列。准确来说,应该是当用户松开一个键时。 注意,玩家可以不释放按键就将自己“移开”屏幕,这在大多数情况下应该会得到处理(我认为),但有时仍会失效。这意味着该功能或多或少还处于……观察阶段,如果被证明不可行的话,该功能会在以后的某个时间点被删除。 重要:这个信号是经过核查,也就是说,只有当玩家是该电脑的登记用户(或该电脑没有登记任何用户)时,信号才会入队。
  • clipboard(keyboardAddress: string, value: string, playerName: string)
    当用户从剪切板上粘贴文本(Shift+Ins 或鼠标中键)时,键盘会将这个信号添加到信号队列。注意,可粘贴的文本最大长度是有限制的(可以在配置文件中修改)。 重要:这个信号是经过核查,也就是说,只有当玩家是该电脑的登记用户(或该电脑没有登记任何用户)时,信号才会入队。

红石卡与红石 I/O 端口

  • redstone_changed(address: string, side: number, oldValue: number, newValue: number[, color: number])
    当传入的红石信号改变时,红石组件会将这个信号添加到事件队列。address红石 I/O 端口或被安装在检测到红石信号的机器上的红石卡的地址。sidesides内的一个常数,表示红石信号在哪一侧发生变化。这个方向是相对于组件的容器的,因此对于计算机和机器人来说,具体的值取决于它们的朝向。对于红石 I/O 端口来说,方向是绝对的。color 参数只有在配合集束线缆使用时才会引入,其值表示发生改变的信号的颜色。

运动传感器

  • motion(address:string, relativeX:number, relativeY:number, relativeZ:number[, entityName:string])
    当其检测范围内的生物实体移动速度超过配置的灵敏度时,这个信号会被运动传感器添加到事件队列。relativeXrelativeYrelativeZ 是被检测到的物体相对于运动传感器的位置。

网卡

  • modem_message(receiverAddress: string, senderAddress: string, port: number, distance: number, ...)
    当在开放的端口上收到消息时,网卡 (包括无线网卡)会将这个信号添加到事件队列。receiverAddress 是收到消息的网卡的地址,senderAddress 是发送消息的网卡的地址。注意,如果消息经过了一个或多个中继器,那么发送者的地址可能与实际发送消息的网卡的地址不同。port 是收到消息的端口。distance 只有收到无线网络信息时才有效,此时它的值是接收者到发送者之间的距离。对于普通的网卡来说,这个值将永远是零。其他所有参数都是用户定义的,并对应用户在调用 modem.send()modem.broadcast() 时指定的内容,用作信息载荷。

机器人

  • inventory_changed(slot: number)
    当机器人的物品栏发生变化时,机器人会将这个信号添加到事件队列。注意这只包括储存在槽中的物品种类的变化。增加或减少一个物品堆中的物品数量并不会触发这个信号。然而玩家手动将机器人库存中的一件物品换成另一件物品(例如玩家鼠标持有木棍,然后点击机器人库存中的火把,玩家鼠标上的物品会变成火把,机器人对应槽中的物品会变成木棍)时实际上会触发两个信号:一个是移除火把的信号,一个是与此同时放入木棍的信号。使用 robot.transferTo() 交换两个槽中的物品甚至会触发四个信号——原因同上,但这次涉及到两个槽之间的物品交换。 此外,这个信号只针对机器人实际可寻址的物品栏,也就是说,它不会因设备(工具、卡槽内的卡、升级槽内的升级组件)的变化而被触发。

抽象总线

  • bus_message(protocolId: number, senderAddress: number, targetAddress: number, data: table, metadata: table)
    1. protocolId 是所使用的协议的版本。
    2. senderAddress 是发送消息的设备的地址。
    3. targetAddress 是消息所指向的设备的地址(网络广播为 -1)。
    4. data是发送的数据的表。
    5. metadata 是发送者设备所特有的数据的表。

运输组件

重要: 这个组件已经被移动到附属模组 OpenComponents。

  • carriage_moved(success: boolean[, reason:string[, x:number, y: number, z: number]])
    这个信号会在运输组件发出移动或模拟命令后进入队列。success 参数指出移动或者模拟指令是否执行成功,即运载工具是否被移动了。如果移动失败,reason 包含的就是错误信息。取决于错误信息,(x, y, z)会是造成移动失败的方块在世界中的坐标。

目录