Jianghu Storm

✅ 可玩

江湖风云

jhfy

🔑 fluffos / Mud@2026 更新 66a3bd8 2026-10-28 源码 下载 ZIP

▶ 开始游玩 · Play Now

本游戏自称 江湖风云单机,是一款传统中文武侠题材 mudlib:玩家从"客店"起步闯荡江湖,可在武当、少林、丐帮、明教、桃花岛等门派间游历、拜师习武,注册后会随机落在客店、北疆小镇、铁枪庙等四个新手出生点之一,每次开局体验略有不同;地图规模中等(约八千文件),门派/任务/武功体系较为完整。经过与本项目内另外两个同源作品(夕阳再现·疯狂江湖、未明空间)的核心文件比对,确认三者同出一脉,都源自"夕阳再现之江湖风云"这一支中文武侠 MUD 血脉——本作在三者中与共同祖先最接近,可以看作这一系列的核心版本;这一支和另一轮处理过的 `xyzx`/`jhfy3`/`xajh4gkb`/`xyzxyl201412` 是同一个真正的"夕阳再现"血统,而本项目里另一批同样打着"夕阳再现"招牌、地图却是完全不同的"天涯"家族档案(`xysylmhb`/`xyzxiiylzymh`/`yzxiiizylfy`/`xyzx3` 等)与此无关,品牌名称不能作为判断血统的依据。

English

The game calls itself Jianghu Storm: Single-Player Edition. Core-file comparison against two related titles in this project (Sunset Reappears: Frenzied Jianghu, and Unknown Space) confirms all three descend from the same lineage — the “Sunset Reappears: Jianghu Storm” branch of Chinese wuxia MUDs — with this version standing closest to their common ancestor, making it the core release of the series. This is the same true “Sunset Reappears” lineage as xyzx, jhfy3, xajh4gkb, and xyzxyl201412 handled elsewhere in this project; note that a separate, unrelated “Tianya” family of archives (xysylmhb, xyzxiiylzymh, yzxiiizylfy, xyzx3, etc.) also carries “Sunset Reappears” branding despite having an entirely different map — the brand name alone isn't a reliable lineage signal.

README

内容亮点

在线试玩

https://mudlibs.fluffos.info/jhfy/

管理员账号 / Admin account

警告:Mud@2026 是本地游玩用的公开默认密码。若要正式对外开放主机,
请先修改此密码(或从 wizlist 中删除该账号)。

本地运行

cd libs/jhfy
~/src/fluffos/build-debug/src/driver config.fluffos

游戏端口:40053。

NOTES · 移植与修复记录

jhfy — 江湖风云

Archive: 江湖风云.rar (#59, byte-identical duplicate: 江湖风云 (1).rar, already listed in AGENTS.md's Duplicate archives table — only this one processed; confirmed via md5sum before extracting, 5607c63bab7ebe67dd44896b145ccda7 for both). Port: 40053. Status: done (boots clean, full registration flow verified end-to-end three times across two driver sessions, with three different real Chinese names, all reaching the actual game world).

What this is

The archive extracts to raw/Jhfy/, a Windows MudOS 0.9.20 bundle (mudos.exe, mudos.dll, mud.log) with the actual mudlib root at Jhfy/world/ (confirmed via Jhfy/config.jh's mudlib directory : ./world / master file : /adm/obj/master directives — the archive's own config file, not a guess). config.jh's name field decodes (GB18030→UTF-8) to "江湖风云单机" ("Jianghu Fengyun — standalone/single-player build"), matching the archive's own filename — no slug rename needed, jhfy is a direct, accurate transliteration. ~8,979 raw files, 8,071 .lpc after the rename — a mid-sized lib for this batch.

Layout: adm/{daemons,obj,simul_efun,etc,tmp} (not adm/single/).

Lineage: a genuine third fork of the 夕阳再现 ("Sunset Reappears") family

The task brief flagged that two already-done libs in this repo — xyzxfk (#46, 夕阳再现-疯狂江湖.rar) and wmkj (#55, 未明空间.rar, live banner "江湖风云之夕阳再现") — both show a "江湖风云" name somewhere. Checked via md5sum on the three core files, per AGENTS.md's standing "verify via diff, never assume from title alone" rule, before doing anything else:

| file | jhfy | xyzxfk (#46) | wmkj (#55) | |---|---|---|---| | adm/simul_efun/chinese.c | 961d77af... | 961d77af... (same) | 961d77af... (same) | | adm/obj/master.c | 8841d611... | 861c587c... (different) | 8841d611... (same) | | adm/daemons/securityd.c | d1bd5477... | d1bd5477... (same) | a33cb521... (different) | | adm/daemons/logind.c | 24ef0ce8... | dbc4a7af... (different) | efd6e03e... (different) |

This is a genuine three-way shared lineage, not a coincidence of title: this lib's chinese.c is byte-identical to BOTH #46 and #55; its master.c is byte-identical to #55's; its securityd.c is byte-identical to #46's; only logind.c (and the room/world content) is independently maintained in each fork. This lib's own logind.lpc banner literally reads "夕阳再现" / 之 / 「江湖风云」 — i.e. this archive is very plausibly close to (or is) the actual upstream "夕阳再现之江湖风云" build that both #46 and #55 forked from/around, given it shares the *most* files (2 of 3 core files matched, vs. 1 of 3 for each of the other two). Confirmed further during the lpcc sweep: d/quanzhen*/hudi{4,5,6}.lpc, d/player/fyue_room.lpc, and several u/fyue/huashan/* files are the exact same room content (same filenames, same pre-existing typos) already documented in wmkj's NOTES.md — genuine shared world-content, not independently authored.

All of #46's and #55's proven fixes were ported/re-verified directly against this lib's actual source rather than rediscovered from scratch, per the task brief's instruction — see below for exactly which applied, which didn't, and how each was confirmed.

Fixes applied

1. AGENTS.md §15h (standard shape, ported from #46/#55 — verified this lib's chinese.c is the identical file, so the identical fix applies): adm/simul_efun/chinese.lpc's is_chinese() — GBK lead-byte range check (strlen(str)>=2 && str[0]>160 && str[0]<255) rewritten to a CJK Unicode codepoint check (strlen(str)>=1 && str[0]>=0x4e00 && str[0]<=0x9fff). 2. AGENTS.md §15h, check_legal_name() in adm/daemons/logind.lpc (this lib, like #55, has no separate named.lpc — check_legal_name is defined directly in logind.lpc, and its shape is NOT byte-identical to #55's copy since logind.c is one of the files that differs across this family — read and fixed independently, not blind-ported): - Byte-count bound strlen(name) < 2 || > 10 → character-count bound < 1 || > 5 (message text "必须是 1 到 5 个中文字" already stated the correct intended character count). - Sliding check i%2==0 && !is_chinese(name[i..<0]) (alternating GBK-lead-byte offsets, variable-length tail slice) → !is_chinese(name[i..i]) on every index (one whole character per index under UTF-8). 3. AGENTS.md §15p: adm/etc/preload had /adm/daemons/network/dns_master live — commented out proactively before the first boot attempt (CRLF-terminated file, edited carefully to preserve line endings elsewhere).

Confirmed NOT needed (verified by reading source directly, not assumed)

Registration-flow verification (the critical check)

Read adm/daemons/logind.lpc's full callback chain (logon → get_id → confirm_id → get_name/get_resp → new_password → confirm_password → select_gift/set_gift/get_gift → get_email → get_gender → init_new_player/enter_world) before scripting any test. No hidden pre-id BIG5/student/client-version gate — the very first prompt ("请输入您的英文名字:") really is get_id, gated only by check_legal_id() (3-14 lowercase English letters only — no digits, confirmed the hard way, see below) and a banned_id substring check (admin, arch, wizard, apprentice, immortal, player, fuck) plus a literal "guest" ban. A valid non-empty Chinese name is accepted with no y/n confirmation step — straight into the password prompt.

Gotcha hit and documented: a first attempt used id qinfeng2 (digit in the English id) — check_legal_id() only allows a-z, so it was rejected, and every subsequent scripted --send line landed on the still-active "please re-enter your English name" prompt, cascading into a confusing multi-line rejection sequence (exactly the class of gotcha AGENTS.md warns about: re-verify with a clean id, don't assume the Chinese-name fix is broken from a cascaded transcript). Confirmed by re-running with an all-letters id.

Test 1 (first successful full run) — python3 scripts/mudclient.py 127.0.0.1 40053 --timeout 30 --idle 2 --send "qinfengsan" --send "y" --send "秦风三" --send "test1234" --send "test1234" --send "0" --send "y" --send "[email protected]" --send "m" --send "look" --send "quit":

Test 2 (independent, after all content fixes below were applied and the driver was restarted — LPC objects don't recompile from an on-disk edit alone) — same script, id linfeng / name 林风 (2 characters), gender f: accepted through the identical full chain, landed in a different start room this time (/d/xingxiu/beijiang, "北疆小镇" / Northern Frontier Town — confirming the random(4) start-room pick works), correct gender-appropriate broadcast (听说又来了一位叫做林风的小姑娘), look/ quit both worked.

Test 3 (final re-verification after ALL fixes, on a fresh driver restart) — id qinfengsi / name 秦风四 (3 characters), gender m: accepted immediately again, landed in "铁枪庙" (Iron Spear Temple) — a third distinct start room — quit worked cleanly.

All three sessions' debug.log grep clean for error/denied/ segmentation/Undefined function beyond the two expected benign boot-time echo lines (mudlib error handler : 1, a config-flag echo, not an actual error) and the intentional live log_error()-to-player mechanism surfacing harmless Unknown #pragma, ignored / Unused local variable compiler warnings to whoever triggers a lazy compile (original mudlib behavior, not a bug introduced here).

Driver process management note: the very first boot (launched via a plain nohup ... & disown from a Bash tool call) was killed by an unexplained external SIGTERM sometime between two tool-call turns, even though ps confirmed it alive and had already served one full successful test in between — strongly suggests the sandbox's per-tool-call process group cleanup can reap a background process that isn't in its own session. Fix: launch with setsid nohup ... & disown (own session id, ps -o pgid,sid confirms PGID==SID==PID) — the driver then survived cleanly across every subsequent tool call for the remainder of testing.

All driver processes were killed (kill -TERM) after each round of testing; no driver process is left running on port 40053.

lpcc_check.sh sweep

8,071 files. Host memory stayed healthy throughout (free -h: 3.7-4.2GB free / ~3.6GB used out of 23GB at every check — nowhere near AGENTS.md §6b's OOM-risk territory; other agents' concurrent conversions for archives #58/#61 were also running on the same host at points during this pass without issue).

| Pass | Result | |---|---| | 1 (pre-fix) | 7933 / 8071 = 98.3% | | 2 (+ 20 file fixes, see below) | 7953 / 8071 = 98.5% | | 3 (+ 8 more file fixes) | 7959 / 8071 = 98.6% (final) |

Content bugs found and fixed via the sweep (all pre-existing, confirmed

against raw pre-conversion bytes where relevant — not introduced by this pipeline)

Remaining 112 failures — triaged by category, not fixed further (per

AGENTS.md §6b: fix genuine shared/impactful bugs, document the rest; this matches the same triage rigor applied on wmkj)

Encoding

convert_lib.sh's automated pass: 8,649 converted cleanly, 295 already-UTF-8, 33 lossy (invalid bytes dropped via iconv -c fallback — mostly NPC/room/data files, e.g. d/quanzhen_old/obj/bookshelf.c, u/fyue/huashan/{map.c,intro}, cmds/usr/{nick.c,whotest.c}), 2 skipped as genuinely binary. One of the lossy files (d/heimuya/shenggu.c) was confirmed via xxd to have a genuine invalid-GBK-lead-byte-then-newline sequence at the exact failure point — the specific "iconv -c eats an adjacent real newline" gotcha from AGENTS.md's Encoding section, fixed as described above. No un-converted GBK stragglers found (re-ran the AGENTS.md straggler check: file -b reports text/script/empty for every .lpc/.h in work/).

Config

config.fluffos adapted from Jhfy/config.jh (labeled "MudOS 0.9.20", GBK→UTF-8 converted before any other edit, per AGENTS.md §5). Original port number : 6666 replaced with 40053 (this project's port assignment for archive #59, per the task brief — next free port after 40051-40052 reserved for archives #57-58). mudlib directory points at /home/sunyc/src/mudlib/libs/jhfy/work (absolute path). All other directives carried over, matching the tuning-knob template used for the last several libs in this batch (wmkj/xiakexing3 shape). log/ directory created as a sibling of config.fluffos (not inside work/), driver always launched via cd libs/jhfy && setsid nohup .../driver config.fluffos (see the "Driver process management note" above for why setsid specifically was needed in this session).

2026-07-23 re-verification pass (driver rebuild + formatter + WASM)

WASM-enablement pass (2026-07: loopback-allow + throttle exemptions + admin seeding)

Standard pass per AGENTS.md §1.3b/e + §1.5. Gates found and patched:

- :173 — ban_cnt > 16 cap on concurrent same-IP pre-login connections in logon(); - :235 — ip_cnt > 8 same-IP player cap in get_id() (the non-welcome/non-netclub branch).

Admin account: fluffos / Mud@2026 / 浮浮, registered through the real native flow (id → y → Chinese name → password ×2 → gift 0/y → email → gender m). Granted (boss) — NOT (admin) — via adm/etc/wizlist (added fluffos (boss) alongside the original fyue (boss)): this lineage extends the ES II wiz_levels ladder with (president)/(admin)/(boss)/(ceo) above (arch), and (boss) is the top rank the securityd ACL tables actually trust (trusted_read/ trusted_write "/"), as well as what the original admin fyue holds. Verified after restart: login shows 您目前权限:(boss), update /cmds/usr/score recompiles successfully. Save files (must be committed): work/data/user/f/fluffos.o, work/data/login/f/fluffos.o.

Retest: fresh registration (秦风/ceshizhe) end-to-end + look/score/quit clean; fluffos login + update clean; debug.log free of errors; test character saves removed.

Dual-mode verification pass (2026-07-24)

WASM 修复摘要(迁移自 meta.json 的 group_note)

此前被错误标记为某个不存在于本项目任何档案的原始压缩包文件名的 duplicate_of;这里的内容其实是完全独立、可游玩的游戏(有自己的 -N 变体编号、自己的端口、自己的 README)——duplicate_of 已清除。

深度功能测试(§10.7,本轮):直接核对手足档案 jhfy2 已确认的 bug

jhfy2(本项目里的另一个"江湖风云"变体)此前的 §10.7 深度测试发现 了 3 个 bug(printf 调试残留、§8.9 食物/饮水年龄检查错对象、2 处 §7.68 死亡软锁)。这次直接核对了 jhfy 是否也带着这几个 bug,而不 是从零排查:

用真实驱动完整验证了一次全新注册(英文 id→中文名字确认→密码→天赋 点数(随机 0)→email→性别,比 jhfy2 多了"是否满意随机中文名字"这一 道确认),进入"客店"后 score 正确显示食物/饮水两条状态全满、属性 数值和分配一致;移动到"南大街"实际攻击 NPC"小贩",角色被打死,干 净地触发"你死了"→"鬼门关"死亡场景→NPC"白无常"自动完成整套复活对 白(不需要玩家任何操作)→魂魄归位→正确送达 REVIVE_ROOM("武庙", 和宏定义一致)——debug.log 全程保持空白,确认三处修复全部生效, 没有任何遗留问题。

未继续测试的部分

时间关系,没有测试拜师、购物、留言板。

更正(2026-08-05):§7.68 复活软锁"修复"已撤销

上面提到的"鬼魂离开/不在场时被永久放弃复活流程"曾被当作 AGENTS.md §7.68 记录的一类 bug 修复(把单次判定改成每 5 秒重试)。经用户指出并 重新审视:这更可能是有意的游戏设计,不是 bug——大多数这类档案里 鬼魂根本无法自行移动,所以"不在场"要么从未真正发生,要么是"离开去 在阴间游荡,想回来时再走回这个房间、流程会通过 init() 重新从头开始" 这种有意为之的宽松机制,而不是需要强制追上玩家的错误。强行重试还可能 引入新问题:如果鬼魂之后又走回这个房间,旧的重试和 init() 重新触发的 新一轮流程可能同时运行,导致对话重叠错乱。已把这处改动撤销,恢复成 原始的 if (!ob || !present(ob)) return; 单次判定写法(bmxkx2001 除外——那份档案里这确实是一个真实存在、经过实际复现验证的 bug:鬼魂 本身完全无法移动,是另一个不相关的 NPC 强行把鬼魂拖走导致的)。详见 AGENTS.md §7.68 顶部的撤销说明。

§7.86 跨库扫描修复(留言板 post 崩溃)

深度功能测试(2026-08-13,round two,新驱动重测)

Re-tested against the freshly-rebuilt build-debug/src/driver(post 全库 quest_times/win_times %-operator 修复 + Warning/warning 驱动文本回退)。log_error()(adm/obj/master.lpc)已经在更早一轮 (引用注释里的"AGENTS.md #15w")正确修复过,本轮只发现并修复了 log_file() 一处。

发现并修复的 PROGRAMMING bug

1. log_file()(adm/simul_efun/file.lpc)完全没有 assure_file() 保护(AGENTS.md §7.11-class 的又一确认实例,与本轮 ffxymud/ hc 完全同一形状):adm/daemons/logind.lpc 的 get_gender()(新角色注册流程的最后一步)紧跟着调用 log_file("login/newid.log", ...)——LOG_DIR 下的 login/ 子 目录若不存在,会在每一个全新角色注册完成的那一刻未捕获抛出,属 于会影响核心注册路径的高优先级实例(不只是 nosave/* 这类只在 管理指令才会触发的低优先级路径)。已补上 assure_file(LOG_DIR + file);(含前向声明)。

Proactive checks(无需改动)

(data/{login,user}/c/chenba.o 是此前会话遗留的未提交测试存档 ——Aug 5 mtime,早于本次会话,未受本轮任何操作影响,未触碰。)

§7.100 房间基类 replace_program() 扫尾修复(2026-08-19)

ROOM 宏(/inherit/room/room,见 include/globals.h)在本档案 2,245 处房间文件的 create() 里紧跟 inherit ROOM; 之后又多余调 用了一次 replace_program(ROOM);——AGENTS.md §7.100 记录的同一个 休眠 bug(多余调用给对象打上永久"pending replace"标记,对象一旦绑 定任何闭包就会崩溃);本档案属于 XYZX/fyue 房间生成工具血统, clone/misc/roommaker.lpc/u/fyue/misc/roommaker.lpc 两份逐字节 相同的副本。用 fix_710_room.py 扫过 work/,删除 2,243 处标准 形状;两份房间生成工具各剩 1 处字符串拼接变体 str += "...replace_program(ROOM);..."(heredoc 模板里的独立行 已被脚本正常扫到),手工改成 str += "\n\tsetup();\n}\n";。修复 后 work/ 下 0 处存活 replace_program(ROOM) 残留,105 处转档之 前已注释掉的 // 行原样保留,work/data/ 下没有真实 .lpc 源码 命中。git diff --stat 显示 2243 个文件净删 2245 行,与脚本自报 数字 + 2 处手工编辑吻合。

驱动干净启动(零新增编译错误、端口正常监听、debug.log 无任何 "cannot replace"/"cannot bind"行),巫师账号 fluffos/Mud@2026 确认"您目前权限:(boss)"后 look/goto 走读了 2 个曾经命中过这 个 bug 的房间(u/snow/wudujiao/yaoshi.lpc、 u/snow/wudujiao/zhushe.lpc)均正常,quit 干净退出。登录存档 的时间戳增量已用 git checkout HEAD -- 撤销,未落入提交。

深度功能测试(round four, 2026-08-20):拜师 / 购物 / 留言板 + 清单复核

环境说明:本轮会话开始时宿主机之前已重启过(archives-side build-debug/ 符号链接不存在),实际驱动二进制路径是 /home/sunyc/src/fluffos/build-debug/src/driver (不是任务提示里写的 mudlib/build-debug/src/driver——那个路径这台机器上 从未存在过,lpcc_check.sh 自己引用的也是 ~/src/fluffos/build-debug/...), 从这个路径正常编译启动,端口 40053 正常监听。

1. 拜师(sect apprenticeship):干净通过

attempt_apprentice() 的实际调用点在 cmds/skill/apprentice.lpc(apprentice/bai 指令),选了武当派开山祖师张三丰(kungfu/class/wudang/zhang.lpc),通过 d/wudang/xiaoyuan.lpc("金殿")房间的 set("objects", ...) 克隆放置定位到该 房间。管理员 fluffos 用 goto /d/wudang/xiaoyuan 抵达后 bai zhang:

☆你想要拜张三丰为师。
张三丰说道:我武当派乃内家武功,最重视内功心法。

命中 zhang.lpc 里 taiji-shengong 技能不足 50 的合理拒绝分支(fluffos 账号没有武当内功技能),机制走通、拒绝理由合理,无崩溃、debug.log 无新增 错误——按验收标准算干净通过(不需要真正收徒成功才算过)。

2. 购物(shopping):完整验证买入 + 当铺卖出双向交易,两级货币确认正常

`` ☆你向小贩买下一串冰糖葫芦。 ☆ 你身上带着的物品有(负重 4%): 五十个铜板(Coin) √布衣(Cloth) 糖葫芦(Bingtang hulu) 法传送帖(Trans site) `` 一两银子买五十文的东西,正确找零五十个铜板——两级/三级货币(金/银/铜)换算 正确。

`` ☆你把身上的一串冰糖葫芦卖掉四十文钱。 ☆ 你身上带着的物品有(负重 5%): 九十个铜板(Coin) ` 五十文的东西按 do_sell()` 的 80% 折算卖得四十文(50+40=90,与背包铜板 数吻合)——买入/卖出双向真实交易全部走通,无崩溃。

3. 留言板(board posting):确认 §7.114 不适用,真实多行留言完整验证

先静态核对 feature/edit.lpc(本档案 F_EDIT 的实际实现):

void input_line(string line, string text, function callback) {

没有 private 修饰符——grep -n "private.*input_line" libs/jhfy/work/feature/edit.lpc 零命中,§7.114(input_to() 递归回调被误标 private 导致多行输入第二行起 静默丢失)在本档案不成立。

再用真实驱动做端到端多行留言测试:goto /d/city/kedian("有间客栈"), post 测试留言标题,输入两行正文,. 结束,read new:

留言完毕。
☆
[1] 测试留言标题                             浮浮(fluffos)(Thu Aug 20)
----------------------------------------------------------------------
这是第一行测试内容。
这是第二行,确认多行留言能完整保存。

两行正文全部保存并读出(不是只有第一行)——§7.86 之前修复的 replace_program() 崩溃 bug 也没有复发(post 指令本身没有崩溃)。测试帖 用 discard 1 清除,board 存档目录(work/data/board/kedian_b.o,测试前 不存在)测试后一并删除,不留churn。

4. 清单复核(静态检查,均确认无需改动)

本轮结论

四项深度测试(拜师、购物买入、购物卖出、留言板多行发帖)全部干净通过, 七项清单复核全部确认无需改动,本轮未发现任何新的 programming bug, 未做任何代码改动。debug.log 全程只新增两行良性 Unknown #pragma, ignored 编译期警告(inherit/char/master.lpc、feature/dealer.lpc 首次被本次会话触发懒编译时输出),没有任何 error/denied/segmentation 等级别的新增内容。驱动测试结束后按精确 PID 正常终止(kill -TERM, ss -ltnp 确认端口 40053 不再监听)。测试产生的存档 churn (fluffos.o 的 last_on 时间戳、临时 data/board/kedian_b.o)已全部 撤销/删除,git status 干净(仅剩此前会话遗留、与本轮无关的 data/{login,user}/c/chenba.o,原样未动)。

§7.30 uninitialized-mapping accessor sweep (2026-08-20)

Corpus-wide mechanical sweep of the feature/skill.lpc shared-lineage bug (confirmed independently on xiakexing2017/jqxz2015/haiyang2 via round-four testing): 4 accessor(s) in this file returned a raw never-initialized mapping instance variable (defaults to int 0, not ([]), until first assigned), crashing any unguarded keys()/sizeof()/indexing caller for a fresh/untrained character. Fixed at the accessor level (mapp(x) ? x : ([])) per the documented remedy. Verified via lpcc --batch static compile check only (not a live boot) as part of a large mechanical sweep; not individually functionally re-tested live on this lib.

深度功能测试(§10.7,2026-10-04)— negative range ends

scripts/lpc_fix_negative_ranges.py: 5 line(s) in 2 file(s) count a range from the end with < (x[a..-1] -> x[a..<1], x[-2..] -> x[<2..]; KB 06 §7.209). In this driver a negative constant end gave "" / ({ }) and a negative start the whole value, so each of these returned the wrong slice; the compile warning A negative constant as the second element of arr[x..y] is gone from the files that compile. Range lvalues (s[0..-1] = text, the prepend idiom) are left alone. A paired compile of the changed files at HEAD and in the working tree showed no new error.

深度功能测试(§10.7,2026-10-05)— 任务表里的 .c 路径与任务守护进程的防护

scripts/lpc_dynamic_rows.py:d/obj/quest/dynamic_location、d/obj/quest/dynamic_quest 里 86 行写的是原档案的 .c 路径。转档时文件已改名 .lpc,而显式后缀按原样解析,load_object("/d/x.c")、new("/d/obj/quest/x.c") 返回 0 且不报错(KB 03 §4.2,KB 06 §7.220),所以 adm/daemons/questd.lpc、u/fyue/questd.lpc 读到的每一行都加载不出来:随机任务和任务物品从未生成,在 create() 里直接对结果调用 tar->set() 的版本还会崩溃,连带加载它的 cron 守护进程和 give 的任务钩子。这些行已改为 .lpc;另有 1 行指向的文件两种后缀都不存在(档案缺内容),保持原样。 scripts/lpc_dynamic_quest_guard.py:2 处 spread_quest() 调用(init_dynamic_quest() 的循环里)包进 catch(),缺失的任务物品或编译不过的房间只跳过那一个任务,守护进程照常加载、其余任务照常生成。 验证:adm/daemons/questd.lpc、u/fyue/questd.lpc和 cron 守护进程在新进程里加载(HEAD 一次,工作树三次,选房是随机的):HEAD 通过 3 个,工作树三次分别通过 3、3、3 个(共 3 个),无回退。

深度功能测试(§10.7,2026-10-05)— 房间列出的物件缺档时房间照常加载

房间基类 inherit/room/room.lpc:make_inventory() 用 catch() 包住 new(file),做不出来就返回 0;reset() 的 case 1: 拿到 0 就跳过这一项(if (!objectp(ob[list[i]])) break;);reset() 的 default: 拿到 0 就跳过这一项(if (!objectp(ob[list[i]][j])) continue;)。档案里没有的 NPC 或物品(或 create() 出错的物件)原先会让列出它的房间整个加载失败(Bad argument 1 to environment(),或对 0 的 call_other()),连带这个房间后面的区域;现在房间照常加载,只是少了那个物件,下次 reset() 再试(KB 05 §7.25;scripts/lpc_resilient_room.py、scripts/lpc_room_reset_guard.py)。 验证:探针(scripts/lpc_room_reset_probe.py:房间基类列出一个不存在的物件,再调用 reset())HEAD 单件 崩溃、多件 崩溃,工作树 单件 OK、多件 OK。

深度功能测试(§10.7,2026-10-07)— 空的 if (current_water == 0) {}

5 个房间的 valid_leave() 里有一行什么也不做的 if (current_water == 0) {}(编译警告 Expression has no side effects),删去,行为不变:d/gaochang/room11.lpc、d/gaochang/room12.lpc、d/gaochang/room13.lpc、d/gaochang/room14.lpc、d/xingxiu/shanjiao.lpc。

深度功能测试(§10.7,2026-10-08)— 编译警告整理

scripts/lpc_warnings.py jhfy --fix 加 scripts/lpc_fix_no_effect.py --apply,共改动 345 个 .lpc 和 3 个 .h(多为删去未用的局部变量)。HEAD 与工作树分别加载(新进程):330 -> 330 通过,无回退;改过的头文件的 34 个包含者 34 -> 34 通过。启动时警告 8 -> 0;新进程登录(输入名字)正常。

深度功能测试(§10.7,2026-10-08)— .lpc 后缀的定宽切片

.c 改名 .lpc 时只改了字符串没改切片宽度:f[<2..] == ".lpc" 拿两个字符比四个字符,永远不成立(!= 永远成立),按后缀筛文件、去后缀的代码因此从不运行或截成 x.l(KB 06 §7.238)。scripts/lpc_lpc_suffix_slice.py --apply 改了 1 处比较、0 处去后缀(如 cmds/app/ls.lpc);改动的文件 HEAD 与工作树分别加载(新进程),无回退。

编译警告收尾(2026-10-13)

scripts/toolkit_fix.sh 一轮去掉 2 处多余的 inherit F_CLEAN_UP(adm/daemons/network/services/temp.lpc、kungfu/class/taohua/obj/cloth.lpc);kungfu/skill/huashan-jian.lpc 招式表后单独一行的 ; 删去。能编译的文件警告清零;改动的 3 个对象在 HEAD 与工作树各载入一次,regress 0。

内力/精力当作伤害种类(2026-10-15,KB 06 §7.241 第二类)

本库 feature/damage.lpc 的 receive_damage() 不接受 jingli/neili/force 等种类,me->receive_damage("jingli", 30) 之类在练功、绝招、吸取时报 F_DAMAGE: 伤害种类错误。13 处改为 add(type, -N)(scripts/lpc_fix_damage_calls.py 第二步)。

无门派玩家的 family 映射(2026-10-15,KB 05 §7.30 第三种)

mapping fam = ob->query("family"); 之后直接 fam["family_name"]:没有门派(新人或叛师后)的玩家在学习、练功、拜师、进入门派房间时报 Value being indexed is zero,而不是作者写好的提示。8 处在声明行加上 if (!mapp(fam)) fam = ([ ]);(scripts/lpc_fix_family_guard.py)。

东方故事/西游记体系的技能文件(2026-10-15,KB 06 §7.241 第三类)

这些 kungfu/skill 文件来自 gin/kee/sen/force 体系,本库人物只有 jing/qi/neili:receive_damage("kee", 30) 报 伤害种类错误,query("force") 永远为 0,技能学不了也练不了。按 kee→qi、gin/sen→jing、force→neili、max_force→max_neili、force_factor→jiali 改了属性名(scripts/lpc_port_es_props.py),共 1 个文件。

family 映射(再补)(2026-10-15,KB 05 §7.30)

mapping fam; fam = (mapping)ob->query("family");(先声明后赋值)和泥潭式的 query("family", me) 同样直接取下标:无门派的新人拜师(attempt_apprentice/recognize_apprentice)、NPC 的 greeting、房间的 valid_leave、ask_me 等报 Value being indexed is zero。5 处补上 if (!mapp(fam)) fam = ([ ]);(刚 recruit_apprentice() 之后的除外)。

技能按另一门武功的等级取招(2026-10-15,KB 06 §7.243)

这些技能文件是从别的武功复制改名来的,query_action() 仍用原武功的等级查招式表:只会本技能的人等级为 0,取不到招,每次出招都报错。改为读本技能自己的等级(scripts/lpc_fix_action_level.py):quanzhen-jian、taixuan-gong。

把经验、属性、内力当技能读(2026-10-15,KB 06 §7.247)

当前内力、精这类名字有时指的是内功技能,逐处读过后手改:落英缤纷 luoying-shenjian/lybf:自己的注释说成功率由“精神高低”决定,两处 query_skill("jing") 改为 query("jing")。

碧海生潮曲空手报错(2026-10-15,KB 06 §7.246)

iceforce/roar(碧海生潮曲)先 ob = me->query_temp("weapon"),再直接拿 base_name(ob) 判断是不是玉箫;空手 exert roar 时 base_name(0) 报错,提示“你必须先找一只玉萧来才可以吹--曲”根本出不来。条件前补 !objectp(ob) ||。

iceforce「chillgaze」从未编译通过(2026-10-15)

iceforce/chillgaze 原档在第一个 return notify_fail(...) 后多了一个 },exert() 就此结束,后面的语句全落在函数外,skill、damage 也没有声明,文件编译失败,这个 exert 从来用不了。照 bixiecanyang、hc、xyzx3 已修好的版本删去多余的 }、补上 int skill, damage;,其余字句不变,只是缩进进函数体。

技能名拼错(2026-10-15,KB 06 §7.249)

query_skill() 里的技能名拼错了,或用的是本库改名前的旧名;本库没有这个技能,调用永远得 0:门槛(< N 就拒绝)永远过不去,相关功夫或绝招学不了、用不了;内功互斥(> N 就拒绝)从不生效;公式里这一项一直是 0。经汉字名(提示文字或中文名词典)或纯拼写差异(_/-、少一个连字符、相邻字母颠倒)核对后,改为本库的技能名(scripts/lpc_fix_skill_typo.py):beimin-shengong→beiming-shengong(/d/quanzhen_old/kungfu/skill/xiantian-qigong、tiangang-zhengqi、xiantian-gong);douzhuan-xignyi→douzhuan-xingyi(/d/mr/npc/obj/shu1、/d/mr/obj/shu1);jinwu-dao→jinwu-daofa(jinwu-daofa);mizongxinfa→mizong-xinfa(longxiang/fanchang);yihua-jimu→yihua-jiemu(yihua-jiemu);zhenfen-xinfa→zhenfeng-xinfa(zfwy-bu)。

技能名拼错:技能文件里拼错自己的名字(2026-10-15,KB 06 §7.249)

技能自己的文件(或它的绝招目录)里,query_skill() 读的是差一个字母的自己的名字,永远得 0:“基本功夫要高过本技能”之类的限制从不生效,按等级取招、计算伤害的那一项一直是 0。改为本技能的名字(scripts/lpc_fix_skill_typo.py 的 self 判据):hujian-daofa→hujia-daofa(hujia-daofa);jinggang-quan→jingang-quan(jingang-quan);xuantie-jiafa→xuantie-jianfa(xuantie-jianfa);xuanxie-jianfa→xuantie-jianfa(xuantie-jianfa)。

family 映射内联取下标(2026-10-15,KB 05 §7.30)

ob->query("family")["master_name"]、me->query("family")["family_name"](泥潭式为 query("family", ob)[...])直接对门派映射取下标:没有门派的人(新玩家、叛师者、大多数 NPC)在 NPC 的打招呼和问话、绝招的门派判断、房间的 valid_leave 里报 Value being indexed is zero,而不是得到拒绝。6 处(5 个文件)改为 dbase 路径查询 query("family/master_name"):有门派时值相同,没有时得 0;原有的判断照常生效(scripts/lpc_fix_family_index.py)。给映射赋值的写法未动。

存档读不出来:字符串里的换行、空行(2026-10-15,KB 03 §4.4)

d/city/obj/bingqipu.o:字符串里有原样的换行(save_object() 存成 \r,restore_object() 逐行读,原样的换行让字符串收不了尾),或有空行(Illegal file format),读档的对象(留言板、NPC、玩家)从空白开始。换行改写成 \r、删去空行(scripts/lpc_save_encoding.py --from-raw),驱动核对全部能读回(scripts/lpc_save_restore_check.py)。

移进不存在的巫师房间(2026-10-15,KB 06 §7.251)

用完的物品、要“离开”的 NPC、掷在空中的兵器被移进巫师的工作室(/u/llm/、/u/wind/),本库没有这些房间。本库的 move() 用 load_object() 找目的地,找不到就返回 0,不报错,东西留在原处:被雇来打晕或杀人的李凌(d/city2/npc/liling2)办完事后没有离开,留在原地(d/city2/npc/liling2 本身还载入不了:create() 里 carry_object() 的物品文件缺失或编译失败,见 KB 06 §7.73,另行处理);婚礼结束(d/nanyang/npc/meipo 的 last_marry)时月老没有离开喜堂,每办一次婚礼喜堂里就多一个月老;喜宴结束后喜来福(d/nanyang/npc/xi-laifu)没有退回内堂,每办一次婚礼迎宾楼就多一个喜来福。3 个文件改为移进本库的虚空房间 VOID_OB(/clone/misc/void),与原作把它们“停放”在巫师房间的用意相同(haiyang2 的维护者把月老送进 /d/city/empty,也是同样的做法)。

玉女剑法「合壁」用一次就永久改动经验和剑法(2026-10-15,KB 06 §7.253)

收尾的 hebi() 声明时没有参数(void hebi() { object me, target, env; int i, j, o, p, count; ...),call_out 传进去的人和数值全被同名的局部变量(0)挡住,开头的 if (!me && !target) return; 每次都返回:合壁的攻击、闪避加成和 hebi 标记要到重新登录才消失。更糟的是夫妻判断写成了 target->querry("id")(没有这个函数,得 0),没成亲的人 marry/id 也是 0,于是人人都被当成夫妻:自己的玉女剑法和经验乘以玉女素心功的级数/80(至少变成浮点数,160 级以上翻倍),随后给对方 set_skill("combat_exp", ...) 时报 No such skill,收尾的 call_out 也就没排上,乘过的等级和经验永远不还原。测试里用一次合壁,经验 100000 变成 200000.0、剑法 100 变成 200.0。改正:hebi() 按它自己再次 call_out 时传的八个参数声明,perform 的 call_out 去掉多余的 h, k,querry 改为 query,给对方的 set_skill("combat_exp") 改为与上一行一样的 set("combat_exp")。测试里加成照常生效,hebi() 结束时还原并清除标记,没成亲的人经验和剑法不变。

NPC 带着本库没有的物品,载入失败(2026-10-15,KB 06 §7.73)

12 个文件、16 处在 create() 里 carry_object("<本库没有的文件>")->wear()(或 wield()、set_amount()):carry_object() 得 0,接着的调用报 Bad argument 1 to EFUN call_other(),NPC 根本载入不了,该有它的房间里就少了这个人。多是从别的系统搬来的 NPC 用了原系统的物品路径(最常见:/obj/cloth/cloth、/obj/weapon/blade、/d/city/obj/tudao)。每处改为 { object carried_ob = carry_object(...); if (carried_ob) carried_ob->wear(); }(scripts/lpc_guard_carry_object.py):NPC 照常出现,只是不带这件东西;文件补回来(或是虚拟对象)照样会带上。载入检查:改动的文件改前能载入 0 个,改后 11 个(11 个原来载入不了),没有退步;其余 1 个另有原因(多为 set_skill() 了本库没有的武功)。

物品清单把名字的第一个字吃掉(2026-10-18,KB 07 §8.1)

inventory、房间的物品列表(feature/move)和部分 look 把同名物品合并计数,键是 query("unit") + short(),只有一件时按 key[2..] 去掉量词。量词是一个汉字,在原来的 GBK 里占 2 字节,[2..] 正好去掉量词;转成 UTF-8 以后一个汉字只占一个下标,这一刀把名字的第一个字也切掉了(「把长剑」只显示「剑」,带颜色的名字切掉的是转义序列开头)。改为 [1..](scripts/lpc_fix_unit_cut.py):cmds/usr/inventory.lpc、feature/move.lpc。

去掉的预定义宏 SAVE_EXTENSION(2026-10-18,KB 04 §6.11)

老版 MudOS 给每个 LPC 对象预先定义了 SAVE_EXTENSION(".o");FluffOS 的 ChangeLog(COMPAT_BUSTER 一条)把它删了,改用 __SAVE_EXTENSION__。本库没有自己 #define 这个宏,用到它的文件一律 Undefined variable 'SAVE_EXTENSION',整个对象载入不了。改成 __SAVE_EXTENSION__(scripts/lpc_fix_predefined_macro.py):adm/daemons/network/netmail.lpc。netmail 是网络邮件守护进程(本库缺 mailer.h 等头文件,改后仍载入不了)。改后用 lpcc 逐个载入这些对象:0 个通过,1 个还有别的错误(adm/daemons/network/netmail:/adm/daemons/network/netmail.lpc:17: error: Cannot #include mailer.h)。

水潭里 ging_cost 是 jing_cost 的笔误(2026-10-18)

shuitan 先算 jing_cost,倒水时却扣 receive_damage("jing", ging_cost),ging_cost 从没声明过:Undefined variable 'ging_cost',整个物件载入不了。改成 jing_cost:d/shaolin/npc/obj/shuitan.lpc。改后用 lpcc 逐个载入这些对象:1 个通过。

全真心法 valid_learn() 里没声明的 lvl(2026-10-18)

kungfu/skill/quanzhen-xinfa.lpc 的 valid_learn() 判断 me->query("gender") == "无性" && lvl > 49,可是函数里只有 nk、nf、nh、ns 四个变量,没有 lvl:Undefined variable 'lvl',这门心法的文件载入不了,学它、用它都失败。nh 正是全真心法的等级(nh = query_skill("quanzhen-xinfa", 1)),改成 nh > 49。改后用 lpcc 逐个载入这些对象:1 个通过。

set_skill() 遇到本库没有文件的武功不再抛错(2026-10-18,KB 06 §7.256)

feature/skill.lpc 里的 set_skill()、map_skill()、prepare_skill() 碰到没有武功文件的名字就 error("F_SKILL: No such skill (…)"),调用它们的 NPC create() 整个中断:NPC 载入不了,刷出它的房间也少一个人。本库有 6 个对象设了本库没有文件的武功(4 个名字,最多的是 yiyang、hunyuan-force、ruyi-blade)。三处都改成 return:这一门武功不给、不映射,对象照常载入,只是少了它(缺的武功本身仍是内容缺口)。抽样载入这些对象:6 个里 6 个通过。(scripts/lpc_guard_set_skill.py)

武功名拼错的 NPC(2026-10-19,KB 06 §7.258)

set_skill("kunlun-shnfa", …)、map_skill("dodge", "shaolin-shnfa") 这样的调用把武功名拼错了:本库没有这个武功文件,有的是拼对的那个。以前这种 NPC 在 create() 里报 No such skill 载入不了;武功缺失时跳过之后它们能载入,可是少了那门武功(set_skill 被跳过,map_skill 映射不到,门派弟子用普通轻功/拳脚)。按核对过的对照表改正,共 16 处、15 个文件:yan-fly→yanfly(3 处)、xinxiu-duzhang→xingxiu-duzhang(2 处)、tiaji-jian→taiji-jian(2 处)、kongmingquan→kongming-quan(2 处)、taiji-shenfong→taiji-shengong(2 处)、lingbo-weibu→lingboweibu(2 处)、poyu-qua→poyu-quan(1 处)、tiangang-zhangqi→tiangang-zhengqi(1 处)等共 9 个名字。(scripts/lpc_fix_skill_names.py)

删掉 exert_function(整数)(2026-10-19,KB 06 §7.266)

/d/player/ltsh/npc/saveme.lpc create() 里的 exert_function(10); 把整数传给了要字符串的直接调用(让 NPC 闲聊时自己运功),驱动报 Bad type for argument 1 of exert_function ( string vs int ),整个 NPC 载入不了。这是存档里的笔误,不知道作者想传哪个字符串,删掉这一句(只影响闲聊时的运功表现)。chidi 的同一个 NPC 早先就是这样处理的。

区域物件的零碎修正(2026-10-19,KB 06 §7.267–§7.271)

逐个物件与 HEAD 对比载入,没有退步。

RANK_D 对 0 的称呼(2026-10-19,KB 06 §7.273)

adm/daemons/rankd.lpc 的 query_respect()、query_rude()、query_self()、query_self_rude() 里 4 个函数开头补上 if (!objectp(ob)) ob = this_object();。NPC 在 create() 里写 "…" + RANK_D->query_respect(this_player()) + "…"(inquiry 对话、chat_msg),驱动自己跑 reset() 时没有人在场,this_player() 是 0。旧驱动里 0->query("age") 返回 0,称呼走默认分支;新驱动直接报 Bad argument 1 to EFUN call_other(),房间的 make_inventory() 吞掉错误,被打死的 NPC 再也刷新不回来。用 scripts/lpc_reach_census.py --walk 找到(xkx100 的武当弟子、一灯、汴梁书生…);修在守护程序里,不动 1,800 个 NPC 文件。

玩家打造兵器模板被 NPC 带上(2026-10-19,KB 06 §7.275)

/d/npc/m_weapon/weapon/m_club.lpc、/d/npc/m_weapon/weapon/m_sword.lpc(共 2 个)的 create() 用 this_player() 读打造数据(me->query("weapon/lv") 等)。NPC 的 weapon 属性是兵器文件名(字符串),NPC 在别的 NPC 的命令环境里 carry_object() 这个模板时,set_desc() 里 switch (w_lv) 拿到的是那个字符串,驱动报 Bad argument 1 to switch,房间和 NPC 都载入不了(旧驱动里 switch 落到 default)。把 if (me) { 改成 if (me && mapp(me->query("weapon"))) {,玩家打造的流程不变。

玩家打造兵器模板没有打造者时(2026-10-19,KB 06 §7.275)

/d/npc/m_weapon/weapon/m_staff.lpc、/d/npc/m_weapon/weapon/m_whip.lpc、/d/quanzhen/npc/obj/m_sword.lpc、/d/quanzhen_old/npc/obj/m_sword.lpc(共 4 个)的 create() 开头 me = this_player(); 之后无条件读 me->query("weapon/name") 等打造数据。房间刷新时没有人在场(me 为 0),或者 NPC 在别的 NPC 的命令环境里 carry_object() 这个模板(NPC 的 weapon 属性是文件名字符串),旧驱动里读出来是 0 或字符串,switch 照样落到 default;新驱动报 Bad argument 1 to EFUN call_other() / Bad argument 1 to switch,NPC 和它所在的房间载入不了(--walk 普查里一个玩家走进房间就触发)。在 //读入数据 之后加 if (!me || !mapp(me->query("weapon"))) { setup(); return; }:没有打造者就留一个没有名字的空模板,玩家打造的流程不变。

补回丢失的标点(2026-10-19,KB 03 §4.6)

转换时丢掉的分号、逗号、引号或文件末尾的 },共 3 个文件,修前 HEAD 载入失败。别的库里同路径的完好副本只比这里少几个标点,按它补回(括号里是那个库):/d/city2/npc/zhengmen.lpc(jqxz2008)、/kungfu/skill/huang.lpc(bixiecanyang)、/quest/murong/qlist3.lpc(bixiecanyang)。修后与 HEAD 逐个对比载入:这 3 个物件全部载入,没有退步(scripts/lpc_restore_from_twin.py、lpc_fix_eaten_quote.py --comma、lpc_fix_eof_braces.py)。

玩家买店用的 feature/vendor_sale.lpc 补回(2026-10-19,KB 03 §4.6 第四轮)

/feature/vendor_sale.lpc(/kungfu/class/npc/xiaoer.lpc 继承它)从 pay_back 起约 160 行的行尾丢了最后一个字符(; ) { },else { 只剩 els,msg 只剩 ms),另有一行 if(wizardp(who) || getuid(who)==owner_id) 被拼进了前面的 log_file( 调用里。文件载入失败,继承它的物件也跟着失败。别的库(ldtx、ldtxii、xhcii、syxjl、hy3)里有这个文件的完好副本,但那是另一个版本:没有作者后来加的投标公告(string mesg; 和 message("channel:chat", ...))。所以按完好副本补回丢失的字符(scripts/lpc_restore_from_twin.py --diff --extra),公告两段原样保留;被拼到别处的 if(...) 放回完好副本里它所在的 write("\n盈利 之前;message_vision("channel:chat", ...) 多出来的第一个参数删掉(message_vision 的签名是 (string, object, object),每次 bid 在扣完款之后都会报错)。补完后文件和继承它的物件都能载入,没有警告,也没有退步(HEAD 上两个都载入失败)。

== !"字符串" 多出来的 !(2026-10-19,KB 06 §7.280)

!"taoist" 是整数 0,x == !"taoist" 就是“x 等于 0”,作者为其余所有人写的那一支永远走不到。具体是:龙女对古墓弟子的机关暗门提示永远给不出来(5 处);孙婆婆的“你去吧”只对 class 没设置的人生效;性别检查(“你不是女的,无法领会其中至阴之理”)永远不拦人,男的照样能学玉女心法。全部改成 != "字符串"(scripts/lpc_fix_not_literal_cmp.py):/kungfu/class/gumu/long.lpc(5 处)、/kungfu/class/gumu/sunpopo.lpc(1 处)、/kungfu/skill/yunu-xinfa.lpc(1 处)。同样的行在 xkx 一系的 35 个库里都有。

x != "a" || x != "b" 和 x == "a" && x == "b":同一个值的比较链永远成立/永远不成立(2026-10-20,KB 06 §7.282)

if (arg != "wan" || arg != "丸") return notify_fail(...) 对任何 arg 都为真,dir == "south" && dir == "north" 永远为假:条件下面的守卫要么永远拦、要么永远不拦。作者要的是“既不是 A 也不是 B”(&&)或“是 A 或 B”(||)。!= 链的 || 改成 &&(仅当条件下面是 return 的拒绝/守卫),== 链的 && 改成 ||(scripts/lpc_fix_cmp_chain.py)。具体是:客栈小二从不拦住付了房钱又往南/往北走的客人。改动:/d/changan/ca2.lpc(1 处)。

登录密码超过 255 字节:crypt() 抛错(2026-10-20,KB 06 §7.294)

驱动的 crypt() 对超过 255 字节的密钥直接报错(Error in crypt(), check your salt),老驱动则按任意长度散列。在登录提示符下输入 256 字节以上的密码,密码检查那一行就抛错,连线停在一个裸的 > 提示符上,登录走不完(password 指令的旧密码检查同样);用 300 个 x 当参数的扫描发现的。/adm/obj/simul_efun.lpc 里补了一个同名的 simul_efun crypt(key, salt):只有超长的密钥才被截短(先截到 255 个字符,再逐字符截到 sizeof(to_buffer(key)) <= 255,限制按字节算,一个汉字占三个字节),再交给 efun::crypt();普通密码原样散列,已存的密码散列不受影响(scripts/lpc_add_sefun.py crypt)。

翻页器 start_more(read_file(...)):文件缺失时 explode(0)(2026-10-20,KB 06 §7.300)

东方故事系的翻页器 void start_more(string msg) { ... explode(msg, "\n") ... } 被这样调用:start_more(read_file(HELP_DIR + "help/topics"))、start_more(read_file(NEWS))。压缩包没带的文件使 read_file() 回 0,explode(0, ...) 在本驱动里报 Bad argument 1 to explode()(不带参数的 help 指令就是这样出错的),老驱动把 0 当空文本。在 start_more 开头加了 if (!stringp(msg)) return;(scripts/lpc_fix_start_more.py)。改动:/feature/more.lpc。

NPC 的 chat() 在 chat_msg 为空数组时下标越界(2026-10-21,KB 06 §7.334)

NPC 基类的 chat() 是 if (arrayp(msg = query(...))) { if (random(100) < chance) { rnd = random(sizeof(msg)); if (stringp(msg[rnd])) ...,不检查列表是否为空。本库现有的 NPC 文件里没有字面写成空 chat_msg 的(扫描只认 set("chat_msg", ({ })));守卫挡的是运行时才为空的列表和以后新增的 NPC。在 random(100) < chance 前面加 sizeof(msg) &&(scripts/lpc_fix_chat_empty.py;if (random(100) > chance) return 0; 的写法是 !sizeof(msg) ||)。改动:/inherit/char/npc.lpc(共 1 个文件)。

socket:dump_socket_status() 在本库没有(2026-10-21,KB 06 §7.291)

管理员扫描里 socket 指令(/cmds/bos/socket.lpc)编译不了:write(dump_socket_status()); 用的是 MudOS 有、本驱动没有的 efun。2026-10-20 的补丁只按名字找了巫师目录里的同名指令,这一条在 cmds/bos、cmds/hufa、cmds/island、cmds/ser 这类目录里;用 scripts/lpc_add_sefun.py dump_socket_status 在 /adm/obj/simul_efun.lpc 末尾补了一个由 socket_status() 构造表格的 simul_efun(没有 sockets 包的构建,比如 WASM,只打印表头)。指令 HEAD 编译失败,现在通过。

睡袋:/cmds/adm/bag 本库没有,使用者被留在聋哑状态(2026-10-21,KB 06 §7.344)

clone/misc/sleepbag.lpc、sleepbag2.lpc 的 do_sleep() 在设好 block_msg/all、no_get 和房间的 sleeping_person 之后调用 "/cmds/adm/bag"->main(me, "<休息中>")。这条巫师指令只有 hc、tianxiawuxue 带着,本库没有:call_other() couldn't find object '/cmds/adm/bag',玩家之后什么消息也收不到(look 一片空白),十秒后的 wakeup call_out 没有排上,房间一直 no_fight。城里的小贩 xiaofan 卖这个睡袋,没有人在扫描里买过它。bag 的全部内容就是 me->disable_player(msg)(feature/command.lpc 里的 nomask void disable_player(string type),没有权限检查),两个文件都改成直接 me->disable_player("<休息中>");。chidi 上实测:sleep 之后十秒 "你一觉醒来,只觉精力充沛",look 正常(HEAD 上玩家被留在空白屏里,log/debug.log 有 trace)。改动:/clone/misc/sleepbag.lpc、/clone/misc/sleepbag2.lpc。

香烟 smoke.lpc:do_smoking() 读没赋值的 me(2026-10-21,KB 06 §7.348)

smoke 指令的第一句是 jing = me->query("jing"),me 声明了没赋值,每次抽烟都抛 Bad argument 1 to call_other()。补 me = this_player();(后面的 this_player() 调用不变)。改动:/d/emei/user-room/melodies/smoke.lpc。

注册到不存在函数的 add_action(2026-10-21,KB 06 §7.349)

add_action("函数", "动词") 绑定的函数,在对象本身、它包含的头文件、它继承的父类和继承它的子类里都没有定义(scripts/lpc_scan_callout_targets.py 静态解析,子类用传递闭包复核,scripts/lpc_verify_handlers.py 运行时 function_exists() 复核)。驱动从玩家最新的一条动作往回找,遇到这样的句子就报 *Function for verb 'drop' not found.,同一个动词的其他处理函数不再尝试(不是最新的一条就悄悄跳过)。删除了 29 条注册(29 个文件,scripts/lpc_fix_dead_add_action.py),动词留给别的处理函数:/d/city/chatroom2.lpc(do_jump)、/d/city/npc/wei.lpc(do_sell)、/d/city2/qishi.lpc(do_pass)、/d/city3/npc/sister.lpc(do_vendor_list)、/d/player/yysz/hupan.lpc(do_han)、/d/quanzhen/npc/haodatong.lpc(do_decide)、/d/quanzhen/npc/mayu.lpc(do_decide)、/d/quanzhen/npc/qizhicheng.lpc(do_decide)、/d/quanzhen/npc/sunbuer.lpc(do_decide)、/d/quanzhen/npc/wangchuyi.lpc(do_decide) 等共 29 个文件。最多的函数名:do_send 15 处、do_decide 7 处、do_jump 1 处、do_sell 1 处、do_pass 1 处。

对象路径里的 ..:new(__DIR__ "../obj/x") 报 Read access denied(2026-10-22,KB 06 §7.351)

__DIR__ 是当前文件所在目录(带结尾斜杠),__DIR__ "../obj/x" 就是 /d/zhiye/npc/../obj/x;驱动的 legal_path() 不接受带 .. 的路径,new() / load_object() 直接抛 *Read access denied.(实测,find_object() 对它答 0)。走库自己的 carry_object() / 房间 objects 表的路径,库的基类会先规范化,能用;直接把路径交给 new() / clone_object() / load_object() / move() 的不行,调用到那一步才报错。改成规范化后的绝对路径(scripts/lpc_fix_dotdot_dir.py --direct):/d/wudang/npc/xiaocui.lpc(__DIR__ "../obj/nuerxiang" → "/d/wudang/obj/nuerxiang")。

缺失物品的 new() / carry_object() 调用链加了保护(2026-10-22,KB 06 §7.73 补充)

new(路径)->move(...); / carry_object(宏("x"))->wear(); 这类语句,路径指向的文件在这个压缩包里没有:new() 返回 0,->move() 在 0 上报 Bad argument 1 to EFUN call_other()。在 create() 里这个对象永远加载不了,在 reset() 里第一个缺失物品之后的刷新每次 reset 都被跳过。1 个文件里 1 处(new)改成 { object new_ob = new(路径); if (new_ob) new_ob->move(...); }(scripts/lpc_guard_carry_object.py --new:路径按这个文件自己看到的宏解析,宏名冲突、虚拟对象路径一律跳过)。 对这 1 个改动文件做加载检查(HEAD 与工作区对比):HEAD 能加载 1 个,现在 1 个(新增可加载 0 个,回归 0 个)。

调用了、但这个库自己的守护进程里没有的函数(2026-10-22,KB 06 §7.354)

MACRO->函数() 调用的函数在这个库的守护进程里不存在:call_other() 对不存在的函数不报错、只返回 0,所以这些功能(时间显示、昼夜事件、名字检查、价格文字……)一直没起作用。同一血统另一个库的同名守护进程里有这些函数,原文照抄到本库守护进程末尾(scripts/lpc_port_function.py;调用处传的参数个数、函数体用到的函数 / 全局变量 / 宏 / 字符串键都在本库里有,已核对;守护进程在 HEAD 和工作区都能加载,每个函数用固定参数各调用一次:HEAD 返回 0,现在返回正常的值):/adm/daemons/chinesed.lpc ← aoxiangtianji:chinese_month()(2 处调用);/adm/daemons/natured.lpc ← aoxiangtianji:room_event_fun()(9 处调用)。

(: 函数 :) 指针指向对象自己没有定义的函数(2026-10-22,KB 06 §7.355)

item_desc / inquiry / chat_msg_combat 里的 (: 函数名 :) 指向本对象(含包含文件、继承的父类)没有函数体的函数:编译不报错,用到时驱动报 *Undefined lfun pointer called: 函数名(look 某物、ask NPC about 话题 直接出错,战斗 / 闲聊里的指针在 NPC 的 chat() 里出错,这一拍心跳的后半段被跳过)。scripts/lpc_scan_callout_targets.py --kinds=lfun。 还剩 3 个函数没有补(inquiry 2, item_desc 1):原型还在函数体丢了、或者根本没写过,没有可以直接补回的捐赠(别的库同一路径的文件里没有这个函数,或者它还要用本库没有的辅助函数、签名不同),不编造:/d/city/npc/zhuziliu.lpc:give_job、/d/city/npc/zhuziliu.lpc:task_ok、/d/yihua/lianhuachi.lpc:look_CAI。

运行期目录 log/nosave 不存在,写日志的 write_file() 直接报错(2026-10-22,KB 03 §4.3 补充)

这个库的 14 个文件里有 18 处 write_file("/log/nosave/...") / log_file("nosave/...")(static 改 nosave 时连字符串里的日志路径一起改了,原来是 log/static/):/log/nosave/KILL_PLAYER、nosave/CRASHES、nosave/PURGE 等。压缩包和站点包里没有这个目录,write_file() 在目录不存在时抛 *Wrong permissions for opening file /log/nosave/... for append. "No such file or directory",调用它的函数(杀人记录、重启记录、call 日志……)当场中断。把 log/nosave 记进 scripts/wasm_keep_dirs.txt(站点和 pristine 树都按它建空目录);没有把字符串改回 static。证明(scripts/lpcc_eval.py,catch(write_file("/log/nosave/ZZTEST", ...)),fqyy2 / hy5 / bmxkx2001 的新进程):补目录前报上面的错误,补后写成功。

(: 函数名 :) 指针指向本库没有的函数:只含这个指针的行加了注释(2026-10-22,KB 06 §7.355 补充)

inquiry / item_desc / chat_msg* 里的 (: 函数名 :) 指向本对象(含包含文件、继承的父类)没有函数体的函数:用到时(ask、look、NPC 闲聊)驱动抛 *Undefined lfun pointer called: 函数名,这一拍心跳的后半段被跳过。这些函数没有可以补回的来源(别的库同一路径的文件里没有,或者它还要用本库没有的东西),所以 1 个文件里 1 行只含这个指针的行("CAI": (: look_CAI :),)加了注释,原文保留并写明原因,这一项当作没有这个话题 / 物品 / 闲聊条目(scripts/lpc_fix_dangling_lfun.py;#include 的文件在库里缺失的对象、指针不在整行上的写法没动)。 前提(function_exists())和加载检查(HEAD 与工作区对比,本库改动的 .lpc 文件)的结果见 KB 06 §7.355:没有一个回归。

写死的 "/路径"->函数() 指向库里没有的文件:改成现存的同名文件(2026-10-22,KB 06 §7.359)

1 处语句级的 call_other 字面量路径,库里没有这个文件(区域改了名 / 大小写不对 / 差一个字母 / 文件挪了地方):"/d/mj/obj/baihong-jian"->move()(/d/mingjiao/npc/yingwang.lpc)→ "/d/mingjiao/obj/baihong-jian"。call_other() 对不存在的对象抛 couldn't find object,所在函数当场中断。改成库里现存、并且定义了被调用函数的文件(scripts/lpc_fix_call_path.py;巫师目录、备份目录、名字不同的兄弟文件都不算候选)。 其中殷天正(白眉鹰王)的 do_answer():玩家念对暗语(answer 怜我世人,忧患实多;保护教主,同抗外敌)时把白虹剑 move 给玩家,区域目录改名 mingjiao 之后这个路径没跟着改,回答暗语只得到 couldn't find object,剑永远发不出来。

汉字按字节切片的老写法没有换成按字符:改法名 "澄" + name[2..3]、辈分判断 name[0..1] == "澄" 等 19 处(2026-10-22,KB 06 §7.360)

原档按字节算字符串区间(一个汉字 2 字节):name[2..3] 是名字的第二个字,name[0..1] == "澄" 问名字是不是以「澄」开头。转成 UTF-8 之后,这个驱动的区间和 strlen() 都按字符算(strlen("澄观") 是 2,"澄观"[0..1] 是两个字),老算术原样留着、意思全变:拜入少林 / 武当 / 峨嵋等派的玩家被改成错误的法名(二字名 张三 变成一个字的 澄,更长的名字取到第三个字);各派掌门的辈分判断(name[0..1] == "澄")永远不成立。

本库 19 处(14 个文件):拼名字的赋值 11 处、与汉字常量比较 8 处。例:name[2..3] → name[1..1](/kungfu/class/emei/jingxin.lpc:101);name[0..1] → name[0..0](/kungfu/class/shaolin/qing-fa.lpc:100);name[0..1] == "慧" → name[0..0] == "慧"(/kungfu/class/shaolin/cheng.h:108)。scripts/lpc_fix_gbk_slice.py 把下标按字符重算(社区的 UTF-8 版 xkx100utf8 里就是同样的写法,作对照);没有改的:截断(name = name[0..7],现在最多 8 个字,只是放宽)、ASCII 的区间(fname[0..3] == "room"、ctime(time())[4..19])和上下文看不出是汉字的区间。证明(scripts/lpcc_eval.py,bixiecanyang;其余各库是同一份文本):让澄字辈掌门 attempt_apprentice() 一个名叫「张三」的访客,HEAD 的法名是 慧,改后是 慧三;抽样 28 个库的 HEAD / 工作树加载对比 0 退步。工具不幂等([0..3] 折半得 [0..1],又是对齐区间),改过的文件记在 scripts/gbk_slice_converted.txt,不要重跑。

长度检查按字节写,旁边的提示按汉字写:6 处(2026-10-22,KB 06 §7.362)

老档的 strlen() 数字节(一个汉字 2 字节),转成 UTF-8 后它数字符:提示写「必须是 2 到 6 个中文字」的检查还是 strlen(name) < 4 || strlen(name) > 12,于是两三个字的房名、帮会名、群名、聊天室名、称号被提示自己说允许的那句话拒绝,上限却是提示的两倍;留言板的标题检查 i < 4 || i > 24 || i % 2 还会拒绝所有奇数个字的标题(post 你好吗)。本库 6 处(3 个文件):if ((strlen(name) < 2) || (strlen(name) > 12)) {(/cmds/bakcmds/csc.lpc:611);if (strlen(arg) < 2 || strlen(arg) > 30)(/d/player/fan_room.lpc:115)。scripts/lpc_fix_strlen_gate.py 以提示为准:条件里每个 strlen 门槛都恰是提示所说数字的两倍才折半,存长度的变量(i = strlen(arg);)的门槛和 || i % 2 奇偶项、其后循环的 i % 2 == 0 && 一并处理;提示里有英文 / 字母 / 字节的不动。证明(scripts/lpcc_eval.py,bxsj 的留言板,求值对象继承 NPC 并重写 edit() 记录调用,command("post 标题")):HEAD 拒绝「你好」和「你好吗」、放行 23 个字的标题;改后接受前两个、拒绝第三个;shenmo 的 named.lpc invalid_new_name("张三"):HEAD 回 名字只能是2-4个中文字。,改后回 0。抽样 24 + 15 个库的 HEAD / 工作树加载对比 0 退步。

按字节写的汉字循环、茶馆猜诗和同盟频道标题(2026-10-23,KB 06 §7.363)

老档按字节做「一个汉字」:while (i--) if (i % 2 == 0 && !is_chinese(name[i..<0])) 只检查偶数下标,奇数位上的拉丁字母(张a)会过;茶馆猜诗 mixup() 用 strlen(str)/2 再 j=j+j、str[k..k+1] 交换两字节;泥潭系 channeld 的 switch (strlen(fname)) case 4/6/8/10 和 strlen(family)==4/6 按字节长度给同盟 / 门派名加空格。本驱动的 strlen() 和区间都按字符算。scripts/lpc_fix_byte_char.py:去掉奇偶项、把区间改成 name[i..i],按字符重写 mixup() 并把 strlen(first)>=14 折成 7,频道标题的 case / 门派长度改成字符数(对照 aoxiangtianji)。本库 汉字循环 / is_chinese 区间 3 个文件。证明(scripts/lpcc_eval.py):sjplii 的 check_legal_name 在 HEAD 接受「张a」、改后拒绝,两边都接受「张三」;xkx100 的 clubpoem->mixup("离离原上草") 得到「离离原草上」(真交换汉字);nitan_san 两字同盟名得到 【 兄 弟 】。关键对象加载通过。

血条 / 表情标题按字节算显示宽度(2026-10-23,KB 06 §7.365)

老档把汉字当两字节:bar_string[0..(val * N / max) * 2 - 1] 把「格数」换成字节下标,半格血条在本驱动(按字符算区间)上会整条画满;巫师表情 edemote 的 repeat_string("─", 13 - (strlen(emotion) / 2)) 也会少减汉字宽度。scripts/lpc_fix_display_pad.py:去掉 CJK 血条 / 空白条上的 * 2(jings/qis 赋值和 blank_string3[0..(23-a)] 的 23→11 一并改),表情标题去掉 / 2;ASCII 空格的 none_string / empty_string 仍保留 * 2(一格两个空格)。本库 2 处(1 个文件)。证明(lpcc_eval.py hhsj):tribar_graph(6,9,12) 在 HEAD 画出整条 12 个■,改后为 6 个■+3 个□;麻将 strlen(tempB)/2 是两字符牌码,未改。

Beyond 出口仍指向 /u/beyond(2026-10-23,KB 06 §7.368)

宁波 / 苏州 / 慕容等区域已进 /d/ningbo、/d/suzhou、/d/mr、/d/hz,出口与任务物路径仍写 /u/beyond/…。scripts/lpc_fix_beyond_exits.py 在目标 .lpc 存在时改写(murong→mr)。本库 1 处。证明:sjplii xikou HEAD 西向 /u/beyond/ningbo/aywsi,改后 /d/ningbo/aywsi 可加载;bxsj hubian1 三向均可加载。

死巫师出口 gold/dock、sunrise、mei(2026-10-23,KB 06 §7.370)

/d/wanjiegu/road4 东向 /u/g/gold/dock、峨眉寿星居南向 /u/xinyue/sunrise_room、玩家卧室通往 /u/mei/… 均无对应房间。scripts/lpc_fix_drop_dead_u_exits.py 删除这些出口行,并去掉同方向的 create_door(否则 create_door 无出口会炸)。本库 5 处。证明:zxty08nxgbb 的 road4 HEAD 有东向,改后没有;mei_room1 可加载。

巫师区出口 faceoff / rence / niulang / yihua(2026-10-23,KB 06 §7.372)

/u/f/faceoff/、/u/r/rence/、/u/onskyer/niulang/、/u/skinys/yihua/ 对应区域已在 /open/world1/faceoff/bird/、/open/prayer/、/d/niulang/、/d/yihua/。scripts/lpc_fix_wizard_area_exits.py 在目标存在时改写,仍缺失的出口行删除。本库 1 处。证明:dreamofseven wood5 四向可加载;xlqy_new2007 天河东西向 niulang;kxkj kitchen7 → prayer。

hanbing `random 反引号(2026-10-27,KB 04 §6.25 Also)

hanbing-mianzhang / hanbing-mianzhang2 在 random( 前多了一个反引号,驱动按模板字面量读到 EOF。删掉。证明:HEAD 失败;改后加载。

深度功能测试(2026-10-27,§6.25 zhongling tell_object 引号错位)

d/wanjiegu/npc/zhongling(及同路径副本)的 tell_object("who, 钟灵脱下一双绣花鞋。\n") 把对象参数写进了字符串;改为 tell_object(who, "…")。证明:原文错位;改后加载,语料残渣 0。

深度功能测试(2026-10-27,§6.25 one-arg message_vision)

message_vision("…") 补第二参(me / TP / this_player())。

深度功能测试(2026-10-27,§6.10 未知 pragma save_binary/optimize)

删除本库中 FluffOS 不认的 #pragma save_binary / #pragma optimize… 行。