AFN 高级频段网络
模组知识库
围绕 Create 公开双频无线链路构建的分层频段、鉴权、信道值、票务、桥接器与外部设备系统。CC:Tweaked 和 Synaxis 是可选集成;API 参数、返回值和错误码见函数手册。
围绕 Create 公开双频无线链路构建的分层频段、鉴权、信道值、票务、桥接器与外部设备系统。CC:Tweaked 和 Synaxis 是可选集成;API 参数、返回值和错误码见函数手册。
AFN 不替换 Create 的无线链路,而是在其上增加可编辑的层级地址、历史库、别名、规则匹配、鉴权板、信道值和多种交互设备。普通 Create 设备仍按强度收发;AFN 设备之间还可以同步文本、布尔值和实数组。
| 组成 | 作用 | 是否需要额外模组 |
|---|---|---|
| 频段板 | 保存主频、别名和鉴权信息 | 仅需 AFN |
| 无线设备 | 把频段板接入发送、接收和收发设备 | 仅需 AFN + Create |
| 桥接器 | 管理最多 64 条信道,连接红石、玩家、无线、Synaxis 和 CC | CC、Synaxis 可选 |
| 票务设备 | 签发、验证和保存鉴权票券 | 仅需 AFN |
| 信箱 | 单信道收发并与 Create Display Link 互读写 | 仅需 AFN + Create |
普通频段板保存一个主频和最多五个别名。主频是默认发送地址,别名是同一块板追加的匹配地址;别名可以使用 OR 或 AND 逻辑。历史库只记录纯字面地址,按层级整理,不把含有规则字符的表达式写入历史。
鉴权频段板额外保存 Owner、READ / WRITE ACL 和隐藏鉴权主频。READ 控制查看和接收,WRITE 控制修改;Owner 管理授权。锁定后,绑定设备中的鉴权板不能被普通拆卸操作取出。没有权限时,隐藏主频不会出现在 GUI、Tooltip 或护目镜悬浮信息中。
| 语法 | 范围 | 说明 |
|---|---|---|
? | 当前层 | 匹配一个字符 |
* | 当前层 | 匹配任意字符,但不跨越点号 |
** | 跨层 | 匹配任意层级和点号 |
[A-C] | 当前层 | 匹配一个大小写敏感的字符范围 |
! | 上一层 | 只排除紧邻上一层的简写项,可连续使用 |
1.2.[1-9].!1!2!3![4-8].[2-4].!2!3上式只匹配 1.2.9.4。规则在服务端编译后匹配,不交给正则表达式执行;历史库仅保存不含规则字符的地址。
| 设备 | 能力 |
|---|---|
| 无线红石信号终端 | 兼容 Create 双槽无线链路;频段板方向和终端水平、垂直摆放不影响匹配。 |
| 信箱 | 单信道发送、接收或收发;可安装普通板或鉴权板,保存接收内容,并与 Display Link 支持的来源和目标互读写。 |
| AFN 桥接器 | 64 条信道、CRT、红石绑定、信道值、Synaxis 端口和 CC:T 外设。 |
| 大型桥接器 | 2×1×2 触控大屏版本;实体电源键和锁定键控制屏幕。 |
| AFN 高级电脑 | 受保护的 CC:T 主机;允许白名单 ComputerID 使用 AFN 函数。 |
设备中的鉴权板是安装凭证,不会被消耗。未锁定时,Owner 或有权限玩家可以查看和按设备规则拆卸;锁定后只能破坏设备移除。护目镜只显示当前玩家有权限读取的频段。
发票机需要有效鉴权板,批量读取 Owner、标题和主频,为普通票券写入票据元数据。相同鉴权板签发的票券可以堆叠到 64;票面展示标题和发行人,Tooltip 不显示隐藏主频。
验票机先检查票券主频是否符合自身规则,再检查票券 Owner 是否满足鉴权板 ACL。验证成功后,只有在 27 格留票库存在空位时才扣除一张票并放行;库存已满时不扣票、不触发脉冲。成功输出 20 tick 红石脉冲,可同步发送配置的普通信号和鉴权信号。鉴权刷卡机与身份验证柱同样输出一秒脉冲,待机暗色、成功绿光、失败红光。
每条信道可以同时拥有主频、可选副频、可选值和激活状态。值类型为文本、布尔或 1~7 项有限实数组;空文本和无值状态不同。写值不会激活,激活也不要求存在值。AFN→AFN 可以携带值,普通 Create 设备只处理 0~15 强度。
| 模式 | 显示与交互 |
|---|---|
| 默认 | 液晶风格显示信道名、文本或实数组。 |
| 开关 | 把布尔值显示为开关;无法解释时回退为关闭。 |
| 柱状图 | 按上下限显示实数组,可配置名称。 |
| 仪表盘 | 按上下限显示实数组刻度,可配置名称。 |
| 地图 | 读取坐标实数组前三项或文本坐标,绘制设备、信道和收藏点。 |
屏幕设置可控制展示顺序、可见性、交互确认、整数输入和地图背景。地图只低频读取客户端已加载区域;关闭背景时只绘制线条、点和收藏文本,不生成或强制加载区块。大型桥接器使用实体按键切换电源和锁定,锁定后屏幕不可编辑。
AFN 通过 Create 的公开双频无线链路工作。未修改 Create 接口的附属设备可以继续完成基础频率匹配;航空学物理化设备按物理化域坐标参与匹配,方向以设备自身朝向计算。绕过 Create 公开链路、使用独立通信协议的设备不在自动兼容范围内。
CC:Tweaked 和 Synaxis 都是可选集成。桥接器为 CC 提供 afn_bridge 外设和 require("afn") 模块;Synaxis 提供激活输入、值输入和值输出端口。完整 API 见 FUNCTIONS.md。
权限策略在鉴权板、白名单或能力开关变化时推送到会话。普通调用只读取 O(1) 会话缓存,不逐次扫描世界、NBT、容器或 ACL;电脑生命周期检查每 tick 执行,完整物理凭证审计低频执行。撤销准入或激活能力会清理对应 ComputerID 的持续租约和临时发送。
door、notice、yard_gate、boiler 均为示例信道名。运行时应替换为桥接器 GUI 左侧的实际信道名;信道名不是无线主频表达式。| 信道名 | 主频 | 可选值 | 本节用途 |
|---|---|---|---|
door | factory.door | OPEN | 同时演示无线脉冲和值 |
notice | 留空 | 候车中 | 只在本机展示和修改文字 |
每条信道都可以同时拥有主频和值,`frequency` 与 `information` 不是互斥的存储类型。主频留空表示不加入无线网络,值仍可保存和显示。信道创建后始终有效;在 CC:T 页开放本节需要的读取、激活和配置权限。安装鉴权板后,还需把本机 ComputerID 加入白名单。详见权限章节。
让电脑紧贴桥接器,或使用有线调制解调器联网,然后在 CC 终端创建程序并运行:
local afn = require("afn")
print("ComputerID:", os.getComputerID())
for _, channel in ipairs(afn.channels()) do
print(channel.name, channel.primary_frequency, channel.value_present)
end第一行用 CC 的 require 加载 AFN 模块,并把返回的函数表保存在普通局部变量 afn 中;之后的 afn.pulse 等调用都来自这张表。
预期:终端能列出 door factory.door true 和主频为空的 notice。若提示找不到桥接器,请检查相邻连接或有线网络;若提示权限问题,请检查白名单和读取权限。
local afn = require("afn")
local result = afn.pulse("door")
assert(result.success, result.error)pulse 省略参数时使用 15 强度、20 tick;20 tick 通常就是 1 秒。成功后,door 信道会短暂激活,对应 AFN 无线接收设备应响应。若得到 unknown_channel,说明填的是不存在的名称(请从 GUI 复制信道名,而不是复制主频);权限异常请检查白名单和激活权限。
local afn = require("afn")
local before = assert(afn.value("notice"))
print("修改前:", before.value)
local result = afn.set_value("notice", "列车即将进站")
assert(result.success, result.error)
local after = assert(afn.value("notice"))
print("修改后:", after.value)这里只想覆盖一次内容,所以不需要先处理 revision。写值需要配置权限,而且不会激活信道。若要变成真正的无值状态,请调用 clear_value;写入 "" 得到的是一个存在的空文本。
以下写法假定只连接一台桥接器,且示例信道已在 GUI 中创建。每段程序先加载 local afn = require("afn")。
| 操作 | 最短写法 | 需要的权限 | 详细说明 |
|---|---|---|---|
| 查看全部信道 | afn.channels() | 读取 | afn.channels |
| 查看一条完整信道 | afn.get("door") | 读取 | afn.get |
| 读取值(含无值状态) | afn.value("door") | 读取 | afn.value |
| 直接修改值 | afn.set_value("door", "OPEN") | 配置 | afn.set_value |
| 清除值 | afn.clear_value("door") | 配置 | afn.clear_value |
| 激活 1 秒 | afn.pulse("door") | 激活 | afn.pulse |
| 持续激活 | afn.set("door") | 激活 | afn.set |
| 关闭自己的持续激活 | afn.clear("door") | 仍通过准入 | afn.clear |
| 修改主频 | afn.set_primary_frequency("door", "factory.door") | 配置 | afn.set_primary_frequency |
| 切换 CRT 当前显示项 | afn.set_display_channel("door") | 读取 | afn.set_display_channel |
| 向任意主频发送 1 秒 | afn.pulse_temporary("station.bell") | 激活 | afn.pulse_temporary |
手册中的签名:
afn.set_value(channel, value[, revision[, bridge]])| 部分 | 含义 |
|---|---|
channel | 必填。桥接器 GUI 中的信道名,例如 notice。 |
value | 必填。准备写入的新值。 |
[revision] | 可选。用于防止覆盖别人刚写入的值;简单覆盖时省略。 |
[bridge] | 可选。CC 看到的桥接器外设名,例如 left;只有一台时通常省略。 |
方括号不应输入。若要跳过中间的 revision,却指定最后的桥接器,需要用 nil 占位:
afn.set_value("notice", "新内容", nil, "left")old 到底是什么?local old = assert(afn.value("notice"))old 只是示例作者随意取的普通 Lua 局部变量名,换成 info 或 current 都不影响 AFN。它保存函数返回的表:
{ present=true, kind="text", value="当前内容", revision=12 }result、r、changed 也都是普通变量名,不是关键字。
bridge 是什么?它是 CC 分配给外设的名称,例如直接相邻时可能是 left,有线网络上可能是 afn_bridge_3;不是方块标题、信道名、主频,也不是 afn.find() 返回的代理对象。可用 CC 的 peripherals 命令查看名称。
-- 指定名为 left 的桥接器
afn.pulse("door", 15, 20, "left")| 字段 | 说明 |
|---|---|
| 信道名 | 供 GUI 与 API 查找;绝大多数 channel 参数都填它。 |
| 主频 | 可为空。有效且信道被本地来源激活时发送无线信号。 |
| 副频 | none、普通 manual 或鉴权板 auth。 |
| 可选值 | 文本、布尔或 1~7 项有限实数组;可与主频同时存在。 |
| 激活状态 | 和值独立;写值不激活,激活也不要求有值。 |
AFN 桥接器之间可沿同一条已放行连接携带强度和值;普通 Create 设备只处理强度。无线入站不会自动中继,只有本地红石、玩家、CC:T 或 Synaxis 激活输入驱动 TX。
所有信道始终有效。receive_enabled 收发为 false 时仅发送,为 true 时允许发送和接收;active 激活表示当前至少有一个有效来源;displayed 展示决定是否列入 CRT。新信道默认允许收发并展示,激活不会自动改变展示清单。
强度范围为 1~15。20 tick 通常为 1 秒。set 建立本电脑的持续租约,pulse 建立定时租约,clear 只清本电脑的来源;红石、其他电脑与 Synaxis 可以同时存在,实际强度取有效来源最大值。
设置、改变或清除值时,revision 单调前进;无值状态也保留版本号。直接覆盖可以不传;只有“先读取、根据旧值计算、再写回”时才传入旧 revision。冲突返回 revision_conflict,应重新读取后再计算。
动作函数通常返回 {success,error,active,strength},配置函数通常返回 {success,error,channel};业务拒绝表现为 success=false 与错误码。最短程序可用 assert(result.success, result.error)。assert 是 Lua 自带的“失败就中止并显示原因”,不是 AFN 函数。连接、参数、白名单或权限问题可能直接抛 Lua 异常,长期运行程序应再用 pcall 包住调用。完整模板见错误章节。
默认、开关、柱状图、仪表盘和地图不会限制信道存什么。无法解释时只做视觉回退:开关显示关闭、图表显示 0、地图只显示设备点;只有真实触控才写入规范值。地图读取实数组前三项或可解析文本坐标。整数模式只影响玩家屏幕触控,不影响 CC:T、Synaxis、无线或普通 GUI 写入。
snapshot 是 get/channels 返回的一条完整信道状态;handle 是临时发送函数返回的唯一句柄,传给 clear_temporary 才能停止那一次发送;Synaxis 的 Schema 是接线两端必须一致的数据形状,例如 vec3 或 quaternion;CRT 是桥接器的主屏幕。
前置:door 已填写有效主频;电脑具有激活权限。
local afn = require("afn")
local opened = afn.set("door", 15)
assert(opened.success, opened.error)
sleep(5)
local closed = afn.clear("door")
assert(closed.success, closed.error)clear 只移除本电脑建立的租约,不会关闭其他电脑、红石或 Synaxis 的来源。
前置:三个信道都已存在;它们是否有主频不影响写值。电脑具有配置权限。
local afn = require("afn")
local text_result = afn.set_value("notice", "列车进站")
assert(text_result.success, text_result.error)
local bool_result = afn.set_value("maintenance", true)
assert(bool_result.success, bool_result.error)
local array_result = afn.set_value("target", {120.5, 64, -31.25})
assert(array_result.success, array_result.error)仅想设置新值时,这就是完整写法,不需要先读取 revision。
适用:counter 当前保存单分量实数,新值依赖旧值。其他玩家、CC、Synaxis 或无线可能在两步之间改值。
local afn = require("afn")
local current = assert(afn.value("counter"))
assert(current.present and current.kind == "real", "counter 不是实数值")
local next_value = current.value + 1
local result = afn.set_value(
"counter", next_value, current.revision
)
if not result.success and result.error == "revision_conflict" then
printError("内容已变化,请重新读取后再试")
else
assert(result.success, result.error)
endcurrent 是普通变量;真正起防覆盖作用的是传入的 current.revision。
local afn = require("afn")
local called, result = pcall(afn.pulse, "door", 15, 20)
if not called then
printError(result) -- 连接、参数或权限异常
elseif not result.success then
printError(result.error) -- 信道业务规则拒绝
else
print("已激活,强度:", result.strength)
end一次性脚本通常用 assert 足够;无人值守程序更适合这个模板。
print("ComputerID:", os.getComputerID())
-- 也可以在 CC 终端直接运行:idComputerID 是非负整数,0 合法。没有鉴权板时忽略白名单并准入所有非负 ID;安装鉴权板后启用目标桥接器 GUI CC:T 页的鉴权板白名单,此时空名单拒绝全部电脑。读取、激活、配置三个开关始终分别生效:读取负责查询和 CRT,激活负责租约与临时发送,配置负责信道值、主副频、展示清单、Synaxis 与红石绑定。
| 变化 | 会话行为 |
|---|---|
| 外设刚连接 | 服务端推送一次当前策略;初始化完成前 fail closed |
| 鉴权板、白名单或三权限改变 | 立即推送到已连接会话,无需重启或重新连接 |
| 安装鉴权板后移出白名单 | 停止事件,并清理该 ComputerID 的持续租约和全部临时发送 |
| 关闭激活权限 | 清理持续与临时输出;仍获准时可使用自己的故障安全清理函数 |
普通函数调用只读取附件会话中的 O(1) 固定时间权限缓存,不会逐函数遍历方块实体、白名单,也不会反复读取 NBT 或玩家 ACL。require("afn") 与 afn.find() 只能证明模块或外设可见,不代表 ComputerID 已获得对应能力。
参数:name 可选 string。返回:bridge, peripheral_name。查找本身不调用受保护方法,因此不检查读取权限或准入条件;返回的代理方法仍要求 ComputerID 通过当前准入条件并具有对应权限。
local bridge, name = afn.find("left")
print(name)
-- bridge.listChannels() 还需要通过准入 + 开启读取权限local ok, err = pcall(afn.find, "missing")
if not ok then printError(err) end
-- no AFN bridge named missing返回:按配置顺序排列的快照数组。需要读取权限。新字段包含 schema_version,primary_frequency,secondary_mode,secondary_frequency,value_present,value_kind,channel_value,value_revision,synaxis_activation;旧 type/subtype/value/attach_auth 仅为兼容投影。
for _, c in ipairs(afn.channels()) do
print(c.name, c.primary_frequency, c.value_present, c.strength)
endlocal ok, err = pcall(afn.channels)
if not ok then printError(err) end
-- computer read access is disabled...返回:string 数组。红石、CC 或 Synaxis 任一来源有效即算激活;需要读取权限。
for _, n in ipairs(afn.active()) do print("active", n) endlocal ok, err = pcall(afn.active, "missing")
if not ok then printError(err) end返回:被明确设为展示的信道名数组;需要读取权限。激活状态不会改变此清单。
print(textutils.serialize(afn.display_channels("left")))local ok, err = pcall(afn.display_channels, 123)
if not ok then printError(err) end
-- bridge name must be a string参数:信道名称。返回:完整快照;不存在为 nil。需要读取权限。
local c = assert(afn.get("boiler"))
print(c.primary_frequency, c.value_present, c.synaxis_receive.enabled)assert(afn.get("no_such_channel") == nil)返回:{receive_enabled,active,strength,displayed,value_present,value_kind,revision},同时保留旧 type/subtype 投影;不存在为 nil。需要读取权限。
local s = assert(afn.state("boiler"))
print(s.active, s.strength)local ok, err = pcall(afn.state, "boiler", "missing")
if not ok then printError(err) end读取权限返回 {present,kind,value,revision};信道不存在才返回 nil。present=false 时 value="" 只是 CC 表占位,不能当成空文本;是否有值必须看 present。
local v = assert(afn.value("door"))
if not v.present then
print("没有值,版本", v.revision)
elseif v.kind == "text" and v.value == "" then
print("这是存在的空文本")
else
print(v.kind, textutils.serialize(v.value))
end参数、权限和返回值与 afn.value 完全相同。
local v = afn.channel_value("door")
print(v and v.present)读取权限返回 {primary,secondary_mode,secondary_frequency,attach_auth};信道不存在返回 nil。attach_auth 是兼容投影,新程序应看 secondary_mode。
local f = assert(afn.frequency("door"))
print("主频", f.primary)
print("副频模式", f.secondary_mode)兼容接口有值时返回 {value,subtype,revision},无值或信道不存在时返回 nil。它无法区分“不存在的信道”和“存在但无值”,新程序应使用 afn.value。
local legacy = afn.information("notice")
if legacy then print(legacy.subtype, legacy.value) end返回:错误 string;正常、未知信道或无错误为 nil。典型值:invalid_frequency_or_auth、wireless_unavailable。
local err = afn.last_error("secure_gate")
if err then printError(err) endlocal ok, err = pcall(afn.last_error, "secure_gate")
if not ok then printError(err) end -- 读取权限关闭返回:名称;展示清单为空时 nil。需要读取权限。
print(afn.get_display_channel() or "standby")local ok, err = pcall(afn.get_display_channel, "missing")
if not ok then printError(err) end返回:boolean。切换 CRT 不激活、不停止、不修改信道;需要读取权限。
assert(afn.set_display_channel("notice"))local ok = afn.set_display_channel("hidden")
if not ok then printError("not in display list") end返回:切换后的名称;空清单为 nil。需要读取权限。
print(afn.next_display_channel() or "standby")local ok, err = pcall(afn.next_display_channel)
if not ok then printError(err) end返回:切换后的名称;空清单为 nil。需要读取权限。
print(afn.previous_display_channel("left") or "standby")local ok, err = pcall(afn.previous_display_channel, false)
if not ok then printError(err) end一条信道可以同时有红石、多个 CC 电脑、Synaxis 和无线来源,实际强度取有效来源最大值。只要主频有效,本地来源激活就会发送无线信号;是否存在信道值不改变这一点。AFN→AFN 可附带值,普通 Create 设备只处理强度,无线入站不自动中继。
参数:strength 1~15,默认 15。返回:{success,error,active,strength}。需要激活权限。
local r = afn.set("yard_gate", 12)
assert(r.success, r.error)local r = afn.set("missing", 15)
print(r.success, r.error) -- false unknown_channelstrength 默认 15;ticks 默认 20。到期自动清理并可产生 timeout 事件。
local r = afn.pulse("bell", 15, 40)
assert(r.success, r.error)local ok, err = pcall(afn.pulse, "bell", 15, 1201)
if not ok then printError(err) end不会清除其他电脑、红石或 Synaxis 来源。返回动作结果;需要激活权限。
local r = afn.toggle("maintenance", 8)
print(r.success, r.active)local r = afn.toggle("missing", 8)
print(r.error) -- unknown_channelComputerID 仍获准时,这是不要求激活权限的故障安全清理;其他来源不受影响。安装鉴权板后移出白名单会由桥接器自动清除该电脑的租约。返回动作结果。
assert(afn.clear("yard_gate").success)local r = afn.clear("missing")
print(r.error) -- unknown_channel清除 CC、红石和 Synaxis 租约;需要配置权限。返回动作结果。
assert(afn.clear_all("emergency").success)local ok, err = pcall(afn.clear_all, "emergency")
if not ok then printError(err) end -- configuration disabled配置权限接受文本、布尔、有限 number 或 1~7 项连续有限数字数组。文本最多 1024 个 Unicode 码点且不超过 4096 UTF-8 字节。写值不激活;简单覆盖不必传 revision。
assert(afn.set_value("notice", "列车即将进站").success)
assert(afn.set_value("door_open", true).success)
assert(afn.set_value("pose", {12.5, 64, -8, 0, 0, 0, 1}).success)
assert(afn.set_value("blank", "").success) -- 存在的空文本空数组、稀疏表、NaN、无穷大或超过 7 项会整次拒绝。需要防覆盖时先用 value 读取 revision,再作为第三个参数提交。
参数、权限、校验和返回值与 set_value 相同。
assert(afn.set_channel_value("counter", 42).success)配置权限清除值但保留单调 revision;它不同于写入空文本。可选 revision 用于防止并发覆盖。
local old = assert(afn.value("notice"))
local r = afn.clear_value("notice", old.revision)
assert(r.success, r.error)
assert(afn.value("notice").present == false)参数和行为与 clear_value 相同。
assert(afn.clear_channel_value("notice").success)兼容接口映射到统一值写入;名称无法表达“主频和值可以共存”。新程序应使用 set_value。
local result = afn.set_information("notice", "列车即将进站")
assert(result.success, result.error)这段兼容代码仍会直接覆盖 notice 的值,但新代码请改为 afn.set_value("notice", "内容", nil, "left")。
配置权限频段必须是合法表达式;传空字符串可让信道退出无线网络,但不会删除值、屏幕设置或端口。
assert(afn.set_primary_frequency("door", "factory.door.*").success)
assert(afn.set_primary_frequency("local_note", "").success)配置权限mode 为 none、manual 或 auth。只有 manual 必须提供合法 frequency;auth 只使用桥接器当前有效鉴权板,Lua 不能提交隐藏身份。
assert(afn.set_secondary("door", "manual", "station.public").success)
assert(afn.set_secondary("secure", "auth").success)
assert(afn.set_secondary("local", "none").success)返回:boolean。目标必须存在;需要配置权限。展示状态不影响信道收发或激活。
assert(afn.set_channel_displayed("notice", true))assert(not afn.set_channel_displayed("missing", true))names 是连续数组,可为空;名称必须存在且不重复。返回 boolean;需要配置权限。清单外的信道即使激活也不会自动显示。
assert(afn.set_display_channels({"notice", "boiler", "gate"}))assert(not afn.set_display_channels({"boiler", "boiler"}))
-- 失败时旧清单完整保留新字段为 name,primary_frequency,secondary_mode,secondary_frequency,value_present,value_kind,channel_value,receive_enabled,displayed。主频和值都可省略;若 value_present=true 必须同时给 channel_value。新信道默认允许收发并展示;receive_enabled=false 表示仅发送。返回配置结果;需要配置权限。
local r = afn.create_channel({
name="yard_gate",
primary_frequency="station.gate.*.!test!staff",
secondary_mode="none",
value_present=true, value_kind="text", channel_value="READY",
displayed=true
})
assert(r.success, r.error)local r = afn.create_channel({
name="broken", value_present=true
})
print(r.success, r.error) -- 缺少 channel_value,整次拒绝只修改给出的字段,失败不会部分提交。同一表中不得混用相互冲突的新旧别名;value_present=false 表示清除值,不能同时提供 channel_value。
local r = afn.update_channel("yard_gate", {
name="yard_exit",
primary_frequency="station.exit.[1-4]",
secondary_mode="auth"
})
assert(r.success, r.error)assert(afn.update_channel("yard_exit", {
value_present=false
}).success)成功结果的 channel=nil;同步清租约、无线 actor 与 Synaxis endpoint。需要配置权限。
local r = afn.remove_channel("temporary_config")
assert(r.success and r.channel == nil)local r = afn.remove_channel("missing")
print(r.error) -- unknown_channel兼容期只为旧程序保留,无法表达同一信道同时拥有主频和值。新代码应组合使用 set_primary_frequency、set_value 和 clear_value。
local r = afn.set_channel_type("old_text", "frequency", "factory.line.*")
assert(r.success, r.error)local r = afn.set_channel_type("old_text", "frequency")
print(r.error) -- frequency_required_for_type_change兼容期只为旧程序保留。新代码直接用类型明确的 Lua 值调用 set_value;旧 coordinate/player 仍可读取但不可新建。
local r = afn.set_information_subtype("counter", "real", 42.5)
assert(r.success, r.error)local r = afn.set_information_subtype("counter", "boolean", "yes")
print(r.error) -- invalid_information_value激活输入只控制 0~15 强度,支持 real / boolean;值输入只写统一值,不激活;值输出只发布统一值,也不激活。三者拥有稳定且独立的 endpoint key。Synaxis 要求接线两端 Schema 完全一致,因此必须在接线前选择格式,不能根据第一帧内容动态猜测。
值端口支持 real、boolean、vec3、quaternion。短数组输入覆写前部并保留旧尾部,长数组扩展;输出截断多余项、补齐缺项,Quaternion 缺少的 w 补 1。无法转换的输出使用 Schema 安全默认值;非法输入整次忽略并保留旧值。Pose / Twist 只保留旧存档兼容,Bundle 暂不支持。
配置权限format 为 real 或 boolean。Real 的值小于 1 表示关闭,达到 1 后转换并限制到 1~15;Boolean 的 false/true 对应 0/15。x/y 必须同时提供,省略格式时保留当前格式。
assert(afn.set_synaxis_activation(
"door", true, "real", 12, 20
).success)
assert(afn.set_synaxis_activation("door", false).success)明确给出 format 时可选 real/vec3/quaternion/boolean;省略或传空字符串保留值输入当前格式。x/y 必须同时提供。该端口只改值,不激活,也不修改另外两个端口。
assert(afn.set_synaxis_receive(
"vehicle_rotation", true, "quaternion", 20, 70
).success)
-- 省略 format 关闭并保留接收格式;发布方向不受影响
assert(afn.set_synaxis_receive("vehicle_rotation", false).success)local r = afn.set_synaxis_receive("notice", true, "boolean")
print(r.error) -- invalid_synaxis_port格式与坐标规则同值输入,但独立配置。比如 4 项实数组发布为 vec3 时只取前三项;Quaternion 缺少的 w 补 1。不存在或无法转换的值输出 Schema 安全默认值。该端口不激活信道。
assert(afn.set_synaxis_publish(
"vehicle_rotation", true, "quaternion", 88, 70
).success)
assert(afn.set_synaxis_publish("vehicle_rotation", false).success)local r = afn.set_synaxis_publish("vehicle_rotation", true, "quaternion", 200, 70)
print(r.error) -- invalid_synaxis_positionside 以桥接器大屏幕正面为基准,为 front/back/left/right/up/down 或字符串 "all"(左右是玩家正对屏幕时看到的左右);strength 为精确整数 1~15 或字符串 "all"(任意非零输入)。支持具体方向/全向与具体强度/全强度的四种组合;匹配时采用实际输入强度。数字不是阈值。一个信道最多保存 112 个不同组合且不会重复保存完全相同项;GUI 新增行默认双 all。返回配置结果;需要配置权限。
assert(afn.bind_redstone("yard_gate", "front", 15).success)
assert(afn.bind_redstone("site_alarm", "all", "all").success)
assert(afn.bind_redstone("precision_alarm", "all", 7).success)
assert(afn.bind_redstone("left_input", "left", "all").success)
-- 依次表示:精确组合、双通配、全向精确强度、具体方向全强度local r = afn.bind_redstone("yard_gate", "north", 15)
print(r.error) -- invalid_redstone_binding传具体方向只移除该方向的行;传 "all" 只移除全向行,不会连带删除六个具体方向。返回配置结果;需要配置权限。
assert(afn.unbind_redstone("yard_gate", "front").success)
assert(afn.unbind_redstone("site_alarm", "all").success)local r = afn.unbind_redstone("missing", "front")
print(r.error) -- invalid_redstone_binding临时发送不创建持久信道、展示项、红石绑定或 Synaxis 端口。同一电脑可并发创建多个 handle;桥接器总计上限 32。鉴权只能来自桥接器自己的有效板。
frequency 必须合法非空;strength 1~15,默认 15;auth 默认 false。返回动作字段和唯一 handle。需要激活权限。
local r = afn.transmit_temporary("factory.*.!test!maintenance", 12, false)
assert(r.success, r.error)
print(r.handle)local r = afn.transmit_temporary("secure.gate", 15, true)
print(r.error) -- auth_board_unavailableticks 1~1200,默认 20。返回 handle;到期关闭并产生 timeout 事件。
local r = afn.pulse_temporary("station.bell", 15, 40, false)
assert(r.success, r.error)local ok, err = pcall(afn.pulse_temporary, "station.bell", 15, 0)
if not ok then printError(err) end不能清其他电脑的 handle;ComputerID 仍获准时不要求激活权限。安装鉴权板后移出白名单会自动关闭该电脑全部 handle。返回动作结果。
local tx = afn.transmit_temporary("factory.test")
assert(tx.success)
assert(afn.clear_temporary(tx.handle).success)local r = afn.clear_temporary("unknown")
print(r.error) -- unknown_temporary_handle返回:removed_count integer。其他电脑和持久信道不受影响;ComputerID 仍获准时不要求激活权限,安装鉴权板后撤销白名单时同一清理会自动执行。
afn.transmit_temporary("test.one")
afn.transmit_temporary("test.two")
print(afn.clear_temporary_all()) -- 2local ok, err = pcall(afn.clear_temporary_all, "missing")
if not ok then printError(err) endafn_bridge 外设索引当前没有信道启用/禁用 API;raw 动态方法索引为 0~38。下表列出统一信道方法的索引。
| 索引 | raw 方法 | Lua 包装函数 |
|---|---|---|
| 32 | getChannelValue | afn.value / channel_value |
| 33 | setChannelValue | afn.set_value / set_channel_value |
| 34 | clearChannelValue | afn.clear_value / clear_channel_value |
| 35 | getFrequency | afn.frequency |
| 36 | setPrimaryFrequency | afn.set_primary_frequency |
| 37 | setSecondary | afn.set_secondary |
| 38 | setSynaxisActivation | afn.set_synaxis_activation |
local bridge = peripheral.wrap("left")
local value = bridge.getChannelValue("door")
print(value.present, value.kind, textutils.serialize(value.value))新快照字段和新方法进入兼容层的同时,旧方法仍保留至少一个大版本;旧投影无法完整表达主频和值共存,新程序应迁移到上表。
只有已完成策略初始化、ComputerID 仍获准并具有读取权限的附件会话会收到事件;未授权电脑不注册监听。第二个返回值是 payload table,刚连接不会补发历史状态。
| 事件 | 主要字段 |
|---|---|
afn_channel_started | channel, active=true, strength |
afn_channel_changed | 有效强度变化后的信道字段 |
afn_channel_stopped | channel, active=false, strength=0 |
afn_channel_value_changed | revision, value_present, value_kind, channel_value |
afn_information_changed | 上一事件的旧名称兼容副本 |
afn_channel_rejected | operation, error,可能含 channel |
afn_channel_timeout | 信道脉冲字段;或 operation, handle, active=false |
afn_display_changed | channel;待机时为空串 |
while true do
local event, data = os.pullEvent()
if event:sub(1, 4) == "afn_" then
print(event, textutils.serialize(data))
end
end外设不存在、ComputerID 未通过准入、会话尚未初始化、参数类型错误或对应权限关闭时会抛 Lua 异常;业务拒绝通常返回 success=false 与错误码。配置返回形如 {success,error,channel},失败时 channel=nil 且原配置不变。同 tick 值写入按玩家 > CC:T > Synaxis > 无线仲裁,较低优先级返回 information_write_conflict。
local called, result = pcall(afn.set, "yard_gate", 15)
if not called then
printError(result) -- Lua 异常
elseif not result.success then
printError(result.error) -- 业务拒绝
else
print(result.strength)
end常见错误:unknown_channel、revision_conflict、information_write_conflict、invalid_information_value、value_present_conflict、invalid_frequency、invalid_secondary、secondary_frequency_requires_manual_mode、unsupported_synaxis_activation_format、invalid_synaxis_port、invalid_redstone_binding、auth_board_unavailable、temporary_transmitter_limit、wireless_unavailable。
| 看到的现象 | 通常原因 | 下一步 |
|---|---|---|
require("afn") 失败 | 电脑未安装 CC:Tweaked,或 Lua ROM 未加载 | 确认 CC:Tweaked 已安装并重启电脑。 |
unknown_channel | 把主频、标题或拼写错误当成信道名 | 复制桥接器 GUI 左侧的信道名。 |
value(...).present == false | 信道存在,但当前没有值 | 用 set_value 创建值;不要把占位的空串误认为空文本。 |
computer configuration access is disabled... | 对应 CC:T 能力开关关闭 | 在 CC:T 页开启调用需要的读取、激活或配置权限。 |
revision_conflict | 读取后,其他来源先修改了值 | 重新调用 value,根据新值重新计算。 |
| 返回成功但无线设备不响应 | 主频为空或非法、副频鉴权不可用、距离/物理化域不通或接收规则不匹配 | 用 get 检查 primary_frequency、secondary_mode、receive_enabled 与 last_error;仅发送模式不影响本地发送。 |
| Synaxis 接线变红 | 两端 Schema 不一致 | 在接线前把两端设为相同格式;激活端口仅 real/boolean,值端口另行选择。 |
| 操作了错误的桥接器 | 多台外设时省略或写错 bridge | 运行 peripherals 查看名称,并把它作为最后参数。 |
information_write_conflict 与 revision_conflict 不同:前者表示同一服务器 tick 已接受优先级更高的玩家、CC:T、Synaxis 或无线写入。等待下一 tick、重新读取当前值,再决定是否提交。