Xiao Ao Jiang Hu IV — Public Edition (Sunset Reappears)

✅ 可玩

笑傲江湖4公开版

xajh4gkb

🔑 fluffos(密码见 README) 更新 66a3bd8 2026-10-28 源码 下载 ZIP

▶ 开始游玩 · Play Now

游戏内品牌为"夕阳再现"之《笑傲江湖Ⅳ》,是作者阿飞在"炎龙"引擎核心基础上打造的第四代版本,其"世界之巅"跳崖场景与本项目收录的 jhfy3(江湖风云3)、xyzx(夕阳再现)逐字节相同,同属一支"夕阳再现"代码血统——需注意同样打着"夕阳再现"旗号的 xysylmhb/xyzxiiylzymh 实际上是完全不同的"天涯"家族地图,品牌名称并不代表血统。除了华山、武当、峨嵋、丐帮、少林等常见门派场景外,还有一整片同类档案里少见的海外区域——日本神户城(东门、海港、海鲜摊等场景),供玩家跨海历练;"杀手楼"是独立于正统门派体系之外的刺客势力,坐落在一座由"金刚神师"把守的豪门巨宅之中,走黑道路线。游戏支持专属客户端的自动地图与组队巡街功能,账号找回与自毁绑定在注册时单独设置、且不可更改的"身份标识"上,权限阶梯细分为 (ceo) > (boss) > (admin) 三级,档案里预置了两个 (boss) 级创始人账号。

English

Branded in-game as "Sunset Reappears: The Smiling, Proud Wanderer IV," this is the fourth-generation version author Afei built atop the "Yanlong" engine core, and a genuine member of that "Sunset Reappears" lineage — its "Peak of the World" cliff-jump scene is byte-identical to this collection's jhfy3 and xyzx (unlike another group of archives that reuse the same brand name but actually descend from the unrelated "Tianya" codebase). Beyond the familiar Huashan/Wudang/Emei/Beggars'-Sect/Shaolin sect map, it adds a whole overseas region unusual for the genre: Kobe, Japan (east gate, harbor, seafood stalls) for players to venture across the sea, plus the Killer Tower, an assassins'-guild faction that operates outside the orthodox sect system out of a lavish mansion guarded by a "Vajra Deity" enforcer. It supports a companion client with automap and street-patrol/party features, ties account recovery and self-destruction to a separate, unchangeable "identity marker" set at registration, and runs an unusually deep permission ladder — (ceo) > (boss) > (admin) — with two pre-seeded (boss)-level founder accounts.

README

内容亮点

本次处理内容

没有发现需要修复的程序 bug。唯一做的事情是在 /adm/etc/wizlist 里加入管理员账号(已有 afei/tianya 两个 (boss) 级创始人账 号;权限阶梯最高是 (ceo) > (boss) > (admin),但 (admin) 已 经足够获得 / 的完整写入权限,和本轮其他档案的惯例一致; SECURITY_D 正确指向 /adm/daemons/securityd,globals.h 里有一 条注释掉的 securd 分身档案备用行,未启用)。

注册流程比较特别:除了普通密码之外,还要单独设置一个"身份标识" (自杀、找回密码时使用,不可修改)。游戏内会夹杂一些 lbadd0/lbclear0 之类的自定义地图协议标记,这是给专属客户端用 的标记,不是错误。

深度功能测试(§10.7)修复的 bug

管理员账号 / Admin account

警告:对外公开架设前请务必修改此密码。

本地运行

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

游戏端口:40154。

NOTES · 移植与修复记录

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

笑傲江湖Ⅳ(公开版),游戏内品牌「夕阳再现」,是在"炎龙"代码核心基础上的第四代分支。在 WASM 下启动并完整完成注册,没有任何编译或运行时错误——没有发现任何 LPC bug。唯一采取的行动:把 fluffos (admin) 播种进 adm/etc/wizlist(已有两个 (boss) 级创始人账号——afei/tianya;wiz_levels 顶层是 (ceo) > (boss) > (admin),但 (admin) 按 trusted_write 已经能获得完整的 '/' 写入权限,和本轮惯例一致;SECURITY_D 正确指向 /adm/daemons/securityd,globals.h 里有一条注释掉的 '// #define SECURITY_D "/adm/daemons/securd"' 诱饵提醒但未生效)。注册流程在一次连续的 WASM 客户端会话里完整验证过:英文 id→y/n 创建确认→中文名字→密码+确认→一个独立的"身份标识"(用于自杀/找回密码)+确认→天赋数值选择(0 为随机,y 接受)→电子邮件(需要 id@address 格式)→性别→带着完整角色属性表进入游戏世界,包括一串自定义地图协议标记('lbadd0'/'lbclear0' 等,无害的客户端标记,不是错误),全程没有任何意外错误。管理员权限已直接通过游戏内横幅"★ 您目前的权限:(admin)"确认。LPC 格式化工具对全部 16167 个档案运行(写入 16133 个,4 个报错,30 个未改动)。没有 :: 父类呼叫拆分命中,没有 CJK 重新加空格命中,没有 case 标签带尾随注释的候选。全部 4 个 map.lpc 档案确认内容完全相同(只是空白差异)。格式化后用同样的完整注册流程重新验证过——干净,管理员权限依然是 (admin)。

深度功能测试(§10.7,2026-08-05)

WASM 阶段"没有发现任何 LPC bug"的结论基本站得住(没有发现代码逻辑 bug),但深挖发现了一个会在普通游玩中反复打断玩家的资源限制配置问 题,此前从未被触发过,因为 WASM 阶段的测试范围只到"完成注册"为止, 没有继续在世界里走动。

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

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

针对升级后的驱动(quest_times/win_times %-operator 修复 + Warning/warning 大小写驱动兼容回退)做的第二轮 §10.7 重测。config.fluffos 里 round one 的 maximum evaluation cost(700000→5000000)修复仍 然在位,重测期间移动未再触发"Too long evaluation"崩溃。

发现并修复的 PROGRAMMING bug

1. log_error()(adm/obj/master.lpc)完全没有严重度检查 (AGENTS.md §7.103 的又一确认实例):if (this_player(1)) efun::write("编译时段错误:" + message + "\n");——任何一次编译警 告(不只是真正的错误)都会原样丢给当前连线玩家,包括普通玩家在 正常游玩中触发的懒编译警告。修复:加上大小写不敏感的 strsrch(message, "arning:") == -1 判断,与本项目现行惯例一致。 2. log_file()(adm/simul_efun/file.lpc)完全没有 assure_file() 保护(AGENTS.md §7.11-class):write_file(LOG_DIR + file, text) 前没有先建目录,而 assure_file() 恰好就定义在同一个文件里稍后 的位置。全档案所有 log_file() 调用点(feature/command.lpc、 feature/condition.lpc、feature/move.lpc、feature/autoload.lpc、 inherit/char/npcsave.lpc、多个 d//clone/ 下的调用点等)都经 由这个 simul_efun,一次性全部修复。修复:assure_file(LOG_DIR + file); write_file(LOG_DIR + file, text);,并在文件顶部加了 void assure_file(string file); 前向声明(assure_file() 定义在 log_file() 之后,这个驱动不做前向解析)。 3. adm/daemons/logind.lpc 里两处遗留的 printf("%O\n", ob); 调 试残留(AGENTS.md §7.34 的形状):分别在"确认中文名字后进入密 码设置"的两条并行分支(手动输入名字 get_name()、接受随机名字 get_resp())里,每次注册确认名字后都会原样把 ob 的 file_name(如 /clone/user/login#18)打印给玩家——live 实测已 确认复现(用测试号 gktestqq 注册时屏幕上出现了裸的 /clone/user/login#18)。两处均已删除该行,只保留紧邻的 ob->set("name", ...)。同目录下还有一份 logind碎梦.lpc,含相 同形状的调试残留,但确认全档案没有任何地方 inherit/call 它 ——是未接入编译树的废弃备份文件,未做改动。

§5/dbase.lpc 密码守卫检查:不适用

feature/dbase.lpc 的 set(prop, data) 是纯粹的无守卫赋值,没有任 何 wizhood()/password 相关的特殊分支,跟 tybxjh/wlhd 那个类的 bug 形状完全不同。也没有单独的 ad_password 密码守卫代码路径。

管理员播种验证:round one 的 wizlist 条目此前没有对应存档

adm/etc/wizlist 里 fluffos (admin) 这一条 round one 就已写入, 但 data/login/f/、data/user/f/ 下都没有 fluffos.o——和本次重 测系列里其他几个 lib 遇到的情况一样,"wizlist 里看起来对"但从未真 正走过一次注册流程留下真实存档。本轮用 fluffos 这个 id 走了一次 完整注册(英文 id→y/n 创建确认→中文名"王五测"→密码 testpass123+确认→身份标识+确认→天赋 0 随机→邮箱 [email protected](id@domain 格式)→性别 m→进入游戏世界), 入世后游戏内横幅确认 ★ 您目前的权限:(admin),score 面板头衔显 示"天界总管"。强制验证步骤:quit 断线后重新连接,输入 fluffos/testpass123 完成一次真正的断线重连,密码验证通过,管理 员权限保持 (admin)——不是只看世界进入和权限横幅就下结论,是真正做 了断线-密码-重连这一步。新产生的 data/login/f/fluffos.o、 data/user/f/fluffos.o 已提交,fluffos 现在是真正可用的种子管理 员账号。

移动/驱动兼容性检查

kedian→south→up→north 往返移动多次未触发任何"Too long evaluation"崩溃或其他异常,debug.log 全程只有一条无关紧要的编译期 Unused local variable 'time' 警告(preload 阶段产生,未连线玩家, 不受 §7.103 修复影响也无需影响)。

quest_times/win_times %-operator 修复:抽查确认在位

d/city2/npc/refereew.lpc 现有 to_int(query("win_times")) % 5, 是corpus-wide 2026-08-12 sweep(commit c571a53629f)已经打过补丁 的写法,无需额外改动。

未在本轮测试

拜师门派、商店购物、完整战斗到死亡/复活循环(round one 已用测试号 testrole/王五在北大街对郭靖打过一次完整的死亡/复活循环,本轮认为 不需要重复;本轮重点是驱动升级后的回归检查 + 正常游玩中顺手发现的 bug)。

深度功能测试(2026-08-19,round four,补测此前五项未测系统)

针对 round one/two 均标注"本次未测试"的五个系统做的专项补测:拜师门派、 商店购物、组队巡街、日本神户跨海区域、杀手楼路线。用全新测试号 rfourtest/肆轮测在真实驱动(~/src/fluffos/build-debug/src/driver, build(ASAN/UBSAN) 目录在本机会因 evthread_use_pthreads 内的一条 非法指令直接崩溃,与本 lib 代码无关,改用 build-debug 正常启动)上 完整走完注册流程,全程通过 nc localhost 40154(而非 telnet,避免 telnet IAC 转义误报)驱动。全程 debug.log 始终为空文件,没有任何 一条编译/运行时错误——五项系统的机制本身均可正常触达和运行,没有 发现任何需要修复的 PROGRAMMING bug。

1. 拜师门派:找到新手盟教练 NPC「阿飞」(d/new/npc/xinshou-afei.lpc ,位于 fly new → northwest),bai xinshou afei(注意:set_name 的 id 是整个 "xinshou afei" 字符串,单独 bai afei 找不到人,属于 命名习惯不是 bug)。以零级新号身份尝试,cmds/skill/apprentice.lpc 的等级门槛检查正常触发,返回"阿飞斜眼瞟了你一眼,就你这种实力还想拜 师?我不收无能之人。"——机制本身(feature/apprentice.lpc 的 attempt_apprentice/recruit_apprentice)正常运行,用合理理由拒绝, 属于干净通过(EITHER 接受或拒绝都算通过,见任务范围说明)。顺手 观察,未改动:kungfu/class/huashan/yue-buqun.lpc 里 recruit_apprentice() 覆写用 add("apprentice_availavble", -1)(拼写 错误,多了个 v),实际字段名是 apprentice_available——这个 typo 使得该 NPC 的"招满三个弟子就不再收徒"计数永远不会真正递减,可能是一 个真实的编程 bug(变量名打错),但没有观察到任何报错或崩溃,且是否 "应该限流收徒"本身是设计意图问题,按标准审慎存疑不动,仅记录在案。 2. 商店购物:fly yz 进城后经 西大街→中央广场→东大街→杂货铺(或 d/city/zahuopu.lpc,杨永福 老板,inherit F_VENDOR* 类似的自定义 do_buy/list)完成一次真实购买:list 正常列出货物表,buy budai 成功购得"麻布袋"一个,扣款/发货全部正常,无任何报错。未测试卖出(按 hell 教训,不同 NPC 是否收购属于内容设计,不在没有报错的情况下当 bug 处理)。 3. 组队巡街:team found rfourteam 得到明确的拒绝提示——"鉴于组队 没任何用处,巫师关闭组队功能。"——这是巫师主动关闭的、带清晰理由的 拒绝,机制本身运行正常,不是 bug。进一步代码走查发现这与"组队巡街" 的抓奸细任务(quest/kangwo/teamjob.lpc 的 ask_jianxi():要求 2-4 人组队,随机分派到某条街道设伏拦截"日本奸细",正是"组队+巡街" 的字面对应)是一致的:该任务函数唯一被 #include 的宿主 NPC quest/hyhusong/wang.lpc(王坚,泉州守备)的整个 inquiry 映射表都 被注释掉了(连 job/fangqi 等其他条目也一并注释),也没有其他任何 活跃代码路径调用 ask_jianxi()。也就是说该任务在当前档案里完全没有 入口——但这和"组队"功能被巫师主动关闭一样,属于内容被有意停用/未完 工,没有任何报错,符合"内容缺失可能是有意为之"的判断标准,未改动。 4. 日本神户跨海区域:确认可达,且有两条独立路径:(a) fly dy 直达 /d/japan/zhongxin.lpc("这里是神户的中心");(b) 真实航海路径 d/quanzhou/haigang2.lpc("城外海港,有商船前往东瀛")enter chuan → /d/feitian/dahai(有几率遭遇倭寇海盗)→ 20-50 秒后 rfeitian() 送达 /d/japan/haigang.lpc;日本境内另有 /d/gaoli/gangkou.lpc (高丽港口)到日本、日本到高丽的对向航线。本轮走了 (a) 路线并在神户 境内 市中心→east→街道(当铺/铁匠铺子)继续走了一步,房间/出口/ 描述均正常加载,无任何错误。 5. 杀手楼路线:fly ssl 直达 /d/shashou/enterance.lpc("杀手楼大 门"),沿 north→north→north 连续穿过"小路"→"枫林"→"校场"(杀手楼 校场,含留言板),全程四个房间连续加载、出口正常、无任何报错。

标准清单巡检(§7.90/§7.111/§7.112/§7.113/§7.114/§7.115):全部确认在位/不适用

测试环境说明

~/src/fluffos/build (ASAN/UBSAN 编译) 在本机启动时于 evthread_use_pthreads() 内直接 Illegal instruction 崩溃(与 mudlib 代码无关的驱动/环境问题),改用 ~/src/fluffos/build-debug 正常启动, 干净监听 40154 端口,Initializations complete.。测试全程用 nc localhost 40154(tmux 会话)而非 telnet,避免 telnet IAC 转义把 中文字节误判为控制序列导致的假阳性。测试号 rfourtest/肆轮测已在 quit 时被游戏自身的"半小时内退出自动删号"机制清理,data/login/、 data/user/ 下未留下任何新存档,git status 确认无新增/改动文件。

AGENTS.md §7.100 修复(2026-08-19)

ROOM 基类冗余 replace_program(ROOM); 自崩溃地雷(详见 AGENTS.md §7.100):本 lib 4745 个房间文件的 create() 末尾(紧跟 inherit ROOM;)都有这一行多余调用,第一次对该房间对象绑定闭包会永久失败。 同款地雷也烤进了自带建房工具 clone/misc/roommaker.lpc 的字符串拼 接代码生成模板。

修复:脚本化删除所有房间文件里独立成行的 replace_program(ROOM);, 加上 roommaker.lpc 里手动摘除字符串拼接片段。git diff --stat: 4746 files changed, 1 insertion(+), 4747 deletions(-),与预期精确吻 合。

验证:build-debug 驱动真实冷启动,端口 40154 正常监听, debug.log 全程干净。既有管理员账号 fluffos/testpass123(本文 件上方记录)登录正常,goto 走访 14 个刚修复的房间(d/migong/ d/wizard/d/xiangyang/d/qingcheng/d/baituo/d/city/ d/zhongzhou/d/wanjiegu/d/wudang),均无 "cannot replace"/ "cannot bind" 新增日志行。走访过程中顺带遇到两个与本次修复无关的既 有问题:/d/migong/lev7/dong47 一场 NPC 战斗把测试角色打死(正常 游戏机制,非 bug);/d/wudang/bolin 的 NPC (kungfu/class/wudang/famu.lpc)create() 里呼叫 carry_object() 抛出 "*Read access denied."——均已确认与 replace_program(ROOM) 无关,不在本次修复范围内,如实记录未修。按 精确 PID 结束驱动;测试期间产生的 fluffos 存档增量(登录计数器 + 死亡状态)已 git checkout -- 还原。

§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.

§7.19 enable_player() reentrancy fix (2026-09-01)

Corpus-wide mechanical fix (AGENTS.md §7.19, Batch F of 6), byte-identical sibling of ylfyxa3's feature/command.lpc. Originally flagged as a possible false positive (pre-existing nosave int enabled = 0; flag, the shape confirmed sufficient on xiaoyuxiyou/xyxyutf8/xyxy2 in earlier batches) -- but this is NOT the safe shape: enabled = 1 is set AFTER enable_commands() returns, not before, so it does not guard the synchronous reentrant init()->setup()->enable_player() call that happens DURING enable_commands(). Confirmed the reachable chain is real: d/shushan/npc/zhangmen.lpc's init() unconditionally calls me->setup(), which unconditionally calls enable_player(). Fixed by adding a true in_enable_player_now reentrancy flag alongside the existing enabled bookkeeping variable (left untouched, disable_player() still needs it). Verified via single-file lpcc --batch PASS.

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

scripts/lpc_fix_negative_ranges.py: 4 line(s) in 1 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)— here-document terminators

scripts/lpc_fix_heredoc_terminator.py --all --apply: 3 here-document block(s) repaired (3 with the terminator glued to the last text line, 0 with it indented), so End of file in text block no longer hides the room or object behind them: d/heimuya/shenggu.lpc, d/heimuya/tang.lpc, d/heimuya/npc/tang.lpc. The terminator must start its line (the lexer's own test, KB 04 §6.10); a glued one lost its newline in the GBK -> UTF-8 conversion together with a half character, which stays out.

深度功能测试(§10.7,2026-10-04)— paths named in another case

The archive comes from a case-insensitive host: files are stored as BAGUA0.lpc, longjing.C, d/SHAOLIN/, the code names them in lower case (__DIR__ "bagua0", "tea/longjing", "/d/shaolin/..."), so the rooms, NPCs and items behind them could not be loaded (a .C file is not an .lpc file; KB 03 §4.5). scripts/lpc_case_paths.py --convert --apply xajh4gkb: 7 file(s) renamed to lower case (.C -> .lpc, .H -> .h) and 0 path reference(s) in 0 file(s) rewritten to the new spelling; 0 skipped, 0 ambiguous. Load check of the 12 objects that were renamed, edited or name a renamed path (HEAD against the working tree, an object is the same under any spelling of its path): 4 PASS -> 12 PASS, 0 that loaded before fail now, 8 more load.

7 files moved (7 .C); mostly under d/feitian/ximen.C (1), d/japan/path1.C (1), d/japan/senlin1.C (1), d/japan/senlin2.C (1). A rescan with scripts/lpc_warnings.py xajh4gkb is still due: the renamed files are compiled for the first time.

深度功能测试(§10.7,2026-10-05)— room base survives a raising NPC

scripts/lpc_resilient_room.py --apply: make_inventory() of inherit/room/room.lpc loads each inventory object as if (catch(ob = new(file)) || !objectp(ob)) return 0;. new() of a file that is not there returns 0 (the room just lacks that NPC), but new() of a file whose create() raises (a skill file for set_skill() this archive never had, a carry_object() item that is not there, a header that never shipped) raised inside the room and the room did not load at all. The wrong-case renames of this lib (the section above) make the NPCs behind them reachable for the first time, so a room that holds one with such a content gap would have gone from "NPC missing" to "room missing"; now it loads without that NPC, as it did before. The room base compiles and loads with the change (HEAD against the working tree). KB 03 §4.5.

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

scripts/lpc_dynamic_quest_guard.py:1 处 spread_quest() 调用(init_dynamic_quest() 的循环里)包进 catch(),缺失的任务物品或编译不过的房间只跳过那一个任务,守护进程照常加载、其余任务照常生成。 验证:改动过的 adm/daemons/questd.lpc 在新进程里加载,HEAD 通过 1 个、工作树通过 1 个(共 1 个),无回退。

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

房间基类 inherit/room/room.lpc: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-08)— 编译警告整理

scripts/lpc_warnings.py xajh4gkb --fix 加 scripts/lpc_fix_no_effect.py --apply,共改动 6 个 .lpc(多为删去未用的局部变量)。HEAD 与工作树分别加载(新进程):6 -> 6 通过,无回退。启动时警告 1 -> 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 改了 2 处比较、1 处去后缀(如 cmds/app/ls3.lpc);改动的文件 HEAD 与工作树分别加载(新进程),无回退。

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

scripts/lpc_warnings.py xajh4gkb --fix 加 scripts/lpc_fix_no_effect.py --apply,共改动 1 个 .lpc(多为删去未用的局部变量)。HEAD 与工作树分别加载(新进程):1 -> 1 通过,无回退。启动时警告 0 -> 0;新进程登录(输入名字)正常。

深度功能测试(§10.7,2026-10-09)— 编译警告(分块扫描重跑)

上一轮的修正工具超时、什么也没写;这一轮分块扫描全部 16174 个文件,剩下的手改:

改动的文件单独加载都通过。

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

本库 feature/damage.lpc 的 receive_damage() 不接受 jingli/neili/force 等种类,me->receive_damage("jingli", 30) 之类在练功、绝招、吸取时报 F_DAMAGE: 伤害种类错误。6 处改为 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,而不是作者写好的提示。3 处在声明行加上 if (!mapp(fam)) fam = ([ ]);(scripts/lpc_fix_family_guard.py)。

family 映射(补)(2026-10-15)

mapping fam = (mapping)me->query("family");(带类型转换的写法)同样直接取下标,1 处补上 if (!mapp(fam)) fam = ([ ]);。

message_vision(msg, environment(me), me)(2026-10-15,KB 06 §7.242)

把房间当成了动作者:message_vision() 取房间的 name() 得 0,replace_string(msg, "$N", 0) 报错。在状态(中毒)里,这个错误发生在 apply_condition(name, duration - 1) 之前,状态永不结束,心跳里后面的恢复也每次被跳过。改为 message_vision(msg, me):/cmds/skill/exercise、/cmds/skill/respitate、/kungfu/condition/emerald_poison、/kungfu/condition/sanpoison。

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.249)

query_skill() 里的技能名拼错了,或用的是本库改名前的旧名;本库没有这个技能,调用永远得 0:门槛(< N 就拒绝)永远过不去,相关功夫或绝招学不了、用不了;内功互斥(> N 就拒绝)从不生效;公式里这一项一直是 0。经汉字名(提示文字或中文名词典)或纯拼写差异(_/-、少一个连字符、相邻字母颠倒)核对后,改为本库的技能名(scripts/lpc_fix_skill_typo.py):yihua-jimu→yihua-jiemu(yihua-jiemu);yuv-jianfa→yunv-jianfa(/d/gumu/gmlg3)。

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

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

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,而不是得到拒绝。4 处(3 个文件)改为 dbase 路径查询 query("family/master_name"):有门派时值相同,没有时得 0;原有的判断照常生效(scripts/lpc_fix_family_index.py)。给映射赋值的写法未动。

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

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

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

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

自制兵器的 id:名字按字节数拆(2026-10-18,KB 07 §8.1)

feature/item_make 的 get_item_id() 把自制物品的名字拆成一个或两个两字词,再到 name_id_arg 里查拼音(「失神」→ shishen)。原来按 GBK 字节数拆([0..3]、len > 4),UTF-8 里一个汉字只占一个下标:四个字的名字 [0..3] 取走整个名字,表里查不到,id 只剩下 sword(空的名字部分),玩家无法用名字指到自己做的兵器。改为按字符数拆([0..1]、[2..len-1]、len > 2):「失神炽日」得 shishen zhiri sword。

物品清单把名字的第一个字吃掉(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。

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 载入不了,刷出它的房间也少一个人。本库有 1 个对象设了本库没有文件的武功(1 个名字,最多的是 qiankun-danuoyi)。三处都改成 return:这一门武功不给、不映射,对象照常载入,只是少了它(缺的武功本身仍是内容缺口)。抽样载入这些对象:1 个里 1 个通过。(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 映射不到,门派弟子用普通轻功/拳脚)。按核对过的对照表改正,共 42 处、37 个文件:kunlun-shnfa→kunlun-shenfa(14 处)、shaolin-shnfa→shaolin-shenfa(12 处)、qiankun-danuoyi→qiankundanuoyi(6 处)、tiaji-jian→taiji-jian(2 处)、meimv-quanfa→meinv-quanfa(2 处)、qinashou→qinnashou(1 处)、kongmingquan→kongming-quan(1 处)、taiji-shenfong→taiji-shengong(1 处)等共 11 个名字。(scripts/lpc_fix_skill_names.py)

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 文件。

被注释吞掉的 inherit / include(2026-10-19,KB 06 §7.274)

/clone/cloth/red_cloth.lpc:#include <armor.h>;/clone/cloth/seng-xie.lpc:#include <ansi.h>。这些指令接在上一行 // 注释的末尾(档案里丢了换行),成了注释的一部分,驱动看不到:缺 inherit 的技能报 Undefined function offensive_target,缺 #include <weapon.h> 的兵器报语法错误。scripts/lpc_fix_swallowed_directive.py 把换行放回去。载入检查 2 个文件,1 个原来编译不过、现在载入,没有退步。

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

/d/npc/m_weapon/weapon/m_axe.lpc、/d/npc/m_weapon/weapon/m_club.lpc、/d/npc/m_weapon/weapon/m_dagger.lpc、/d/npc/m_weapon/weapon/m_fork.lpc、/d/npc/m_weapon/weapon/m_spear.lpc、/d/npc/m_weapon/weapon/m_sword.lpc(共 6 个)的 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.276)

32 个文件、32 处物件路径写成 //…(如 carry_object("//clone/cloth/hic_cloth")):/adm/daemons/logind.lpc、/d/dali/npc/liumang.lpc、/d/dali/npc/liumangtou.lpc、/d/gaochang/npc/jinxiangyu.lpc、/d/heimuya/zhaoze/npc/yinggu.lpc、/d/kunlun/npc/dizi.lpc 等。当年的驱动不介意(路径先被规范化);新驱动把原样的字符串交给 master 的 valid_read(),securityd 按 //clone 查目录,NPC 的 euid 没有权限,报 Read access denied.,NPC 载入不了。改成一个斜杠。载入检查:这批 NPC 在 HEAD 上都载入不了,现在都能载入。

d/lingjiu/jian.lpc 的 do_huode(2026-10-19,KB 04 §6.10)

do_huode() 里用了没有声明的 me(me->add("xyzx_sys/level", 1)),驱动报 Undefined variable 'me',整个房间(灵鹫宫的「剑」)载入不了;原档案里同样编不过。补上 object me = this_player();。注意:huode 技能 是本库作者自己写的命令——xyzx_sys/level +1、score +10000、全部技能 +10,没有任何限制;房间载入后这条命令按原样生效,是否保留由维护者决定。

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

/d/npc/m_weapon/weapon/m_staff.lpc、/d/npc/m_weapon/weapon/m_whip.lpc(共 2 个)的 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 06 §7.274)

scripts/lpc_fix_swallowed_statement.py 把换行放回去。逐个载入与 HEAD 对比,没有退步。

userp(0)(2026-10-19,KB 06 §7.277)

adm/simul_efun/player.lpc 的 userp(object ob) 先调 efun::userp(ob),没有人在场时(房间刷新里 NPC 穿会员衣服,wear() 里 userp(this_player()))ob 是 0,驱动报 Bad argument 1 to userp() Expected: object Got: 0,NPC 和房间载入不了。函数开头加 if (!objectp(ob)) return 0;(旧驱动里 userp(0) 就是 0)。

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

!"taoist" 是整数 0,x == !"taoist" 就是“x 等于 0”,作者为其余所有人写的那一支永远走不到。具体是:孙婆婆的“你去吧”只对 class 没设置的人生效。全部改成 != "字符串"(scripts/lpc_fix_not_literal_cmp.py):/kungfu/class/gumu/sunpopo.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 处)、/d/xuehepai/obj/bairiwan.lpc(1 处)、/kungfu/skill/yunshang-xinjing.lpc(1 处)。另有 /d/hainan/npc/ziyun.lpc(1 处) 的条件下面做的是别的事(== 和 || 也可能是本意),保持原样。

member_array('/', str) 改为 strsrch(str, "/"):字符字面量的 member_array 按字节搜索(2026-10-20,KB 06 §7.283)

member_array('/', str) 里的 '/' 是整数,驱动按 UTF-8 字节搜索,返回字节偏移(带第三个参数时起点也是字节);最新的 FluffOS(923cdbc0)在字符串里有非 ASCII 文字时,对每个调用点警告一次(Warning: member_array(int, string) searches BYTES)。而 str[0..idx-1] 按字符切,中文字符串会在错误的位置截断。改为 strsrch(str, "/")(找不到同样返回 -1,按字符计数;scripts/lpc_fix_member_array_char.py,JSON 编码器等少数几处手改)。改动:/adm/daemons/vrm_server.lpc(1 处)。

if (x = 常量):条件里写成赋值的比较(2026-10-20,KB 06 §7.290)

if (arg = "button" || arg = "按钮")、if (!arg || arg = "") return 0;、else if (check = 0 && tempB != ""):把 == 写成了 =,条件的值就是那个常量,分支对所有非零数和任何字符串(连 "" 都算)永远成立、对 0 永远不成立,变量还被覆盖;驱动对此没有任何警告。每一处 = 改成 ==(scripts/lpc_fix_cond_assign.py,共 9 处);其后 x == "a" && x == "b" / x == "a" || "b" 这类被 == 暴露出来的链也随之改成 || 或补全变量(/d/hainan/npc/xianhe.lpc、/d/hainan/npc/xiaohe.lpc、/d/shushan/shanjian.lpc)。改动:/clone/npc/man.lpc(1 处)、/d/hainan/npc/xianhe.lpc(3 处)、/d/hainan/npc/xiaohe.lpc(3 处)、/d/shushan/shanjian.lpc(2 处)。

get_config(__MUD_PORT__) 经旧版 runtime_config.h 得到字符串(2026-10-20,KB 06 §7.302)

本库的 include/runtime_config.h 是老 MudOS 的编号(整数设置从 15 起,本驱动从 256 起),get_config(__MUD_PORT__) 读到的是另一项设置(字符串),(int) 又只是编译期标注,于是 socket_bind(fd, LOCAL_PORT()) 报 Bad argument 2 to socket_bind(),版本守护进程 port = get_config(__MUD_PORT__) + VERSION_PORT 是字符串相加。头文件自己的注释写明 get_config(__MUD_PORT__) == __PORT__,所以代码里的这个调用(连同外面的 (int) / to_int())改成了驱动的预定义 __PORT__(scripts/lpc_fix_mud_port.py)。改动:/adm/daemons/network/fileserver.lpc(1 处)、/adm/daemons/network/server.lpc(1 处)。

chglog、jnlog、partyinfo 读不到运行日志就抛错(2026-10-20,KB 06 §7.326)

chglog 和 jnlog 把 /log/chglog.txt、/log/jnlog.txt 交给 trans_color(read_file(file)),partyinfo 把 read_file("/log/cmds/party") 直接 explode()。这三个文件都是运行中的 mud 才会写出来的日志,克隆出来的目录、站点和全新启动的树里没有,read_file() 答 0,于是 Bad argument 1 to replace_string()(在 trans_color() 里)和 Bad argument 1 to explode()。前两个现在先测 file_size(file) <= 0,用原来那句 没有找到/log/....txt。 回答;partyinfo 读不到时按空表处理,只打印表头。三个文件与 ylfyxa3 的逐字节相同,同样修改,只做了加载检查(3/3,回归 0)。

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 个文件)。

巫师命令不带参数时对 0 调用 efun(2026-10-21,KB 06 §7.336)

巫师(管理员)把命令敲成不带参数时,驱动把 0 传给字符串参数;下面的命令第一句就把这个 0 交给 efun,运行时报 Bad argument 1 to ...,这条指令从来没有用过。用 scripts/lpcc_bare.py 不登录、在一次 lpcc 求值里以 0 调用 main() 逐个确认后,由 scripts/lpc_fix_bare_arg.py 在第一处使用参数的语句前加守卫:文件自带 int help(object me) 的,守卫是 if (!arg) return help(me);(help() 定义在 main() 之后的 2 个文件补了原型 int help(object me);,否则编译报 Undefined function help)。改动(2 个文件,括号里是接住 0 的 efun):/cmds/adm/dallowip.lpc(find_player)、/cmds/adm/dbiaoshi.lpc(find_player)。加载检查 HEAD 与工作树对照,没有退步。

findfile、updir:不带参数(2026-10-21,KB 06 §7.336)

ToMud 升级用的两条指令(cmds/bos/findfile.lpc、updir.lpc)不带参数时报 Bad argument 1 to sscanf() Expected: string Got: 0.:findfile 的 sscanf(arg, "%s,%s", dir, str) 前面是一段注释掉的代码,updir 的 sscanf(arg, "%s -debug", arg) 在 if (playerp(previous_object())) 里面。findfile 补了 if (!arg) return help(me);(help() 在 main() 之后,补了原型),updir 在开头 if (!arg) arg = "";,不带参数就列出当前目录。

注册到不存在函数的 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.,同一个动词的其他处理函数不再尝试(不是最新的一条就悄悄跳过)。删除了 17 条注册(17 个文件,scripts/lpc_fix_dead_add_action.py),动词留给别的处理函数:/d/city/chatroom2.lpc(do_jump)、/d/city/warehousenew.lpc(do_zhuan)、/d/city2/qishi.lpc(do_pass)、/d/flypproom/npc/flypp.lpc(do_sell)、/d/mingjiao/npc/changjinpeng.lpc(do_join)、/d/mingjiao/npc/chengchaofeng.lpc(do_join)、/d/mingjiao/npc/fenggongying.lpc(do_join)、/d/mingjiao/npc/gaoshanwang.lpc(do_join)、/d/quanzhen/npc/haodatong.lpc(do_decide)、/d/quanzhen/npc/mayu.lpc(do_decide) 等共 17 个文件。最多的函数名:do_decide 7 处、do_join 4 处、do_jump 1 处、do_zhuan 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 都被跳过。2 个文件里 2 处(new)改成 { object new_ob = new(路径); if (new_ob) new_ob->move(...); }(scripts/lpc_guard_carry_object.py --new:路径按这个文件自己看到的宏解析,宏名冲突、虚拟对象路径一律跳过)。 对这 2 个改动文件做加载检查(HEAD 与工作区对比):HEAD 能加载 2 个,现在 2 个(新增可加载 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()(22 处调用)、outdoor_room_event()(2 处调用)。

(: 函数 :) 指针指向对象自己没有定义的函数(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。 还剩 7 个函数没有补(inquiry 5, item_desc 1, other 1):原型还在函数体丢了、或者根本没写过,没有可以直接补回的捐赠(别的库同一路径的文件里没有这个函数,或者它还要用本库没有的辅助函数、签名不同),不编造:/d/tangmen/npc/tanglaoye.lpc:ask_me、/d/tangmen/npc/tanglaoye.lpc:ask_guanyinlei、/d/yihua/lianhuachi.lpc:look_CAI、/d/zhongzhou/npc/old2.lpc:ask_hbd、/kungfu/class/mingjiao/fanyao.lpc:ask_me、/kungfu/class/mingjiao/yangxiao.lpc:ask_me、/kungfu/skill/chixin-jian.lpc:yunwu。

log/ 下的日志子目录没有人建:写日志的 write_file() / log_file() 报错(2026-10-22,KB 06 §7.358)

这个库的代码往 log/ 的 1 个子目录写日志:log/test(d/hangzhou/obj/jiasha.lpc)。压缩包、git clone 和站点包里都没有这些目录(本地启动没有写过它们,gen_keep_dirs.py 没记),write_file() 对不存在的目录抛 *Wrong permissions for opening file /log/dlog/money for append. "No such file or directory",调用它的函数在写日志那一行中断,后面的奖励、标志、步骤都没有执行。本库的 log_file() 会自己建目录(实测,或读源码:nitan 系的 assure_file()),所以这里只记了直接用 write_file() / save_object() 写的目录。把 log/test 记进 scripts/wasm_keep_dirs.txt(scripts/lpc_keep_log_dirs.py;站点和 pristine 树按它建空目录)。证明(scripts/lpcc_eval.py,在 /adm/daemons 这类目录下的求值对象里写 /log/zzdirprobe/...,新进程)见 KB 06 §7.358 的实测表。

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

inquiry / item_desc / chat_msg* 里的 (: 函数名 :) 指向本对象(含包含文件、继承的父类)没有函数体的函数:用到时(ask、look、NPC 闲聊)驱动抛 *Undefined lfun pointer called: 函数名,这一拍心跳的后半段被跳过。这些函数没有可以补回的来源(别的库同一路径的文件里没有,或者它还要用本库没有的东西),所以 6 个文件里 7 行只含这个指针的行("大闹唐门": (: ask_me :), "观音泪": (: ask_guanyinlei :) "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)

2 处语句级的 call_other 字面量路径,库里没有这个文件(区域改了名 / 大小写不对 / 差一个字母 / 文件挪了地方):"/d/Xuehepai/quest/xhquest"->query_quest()(/d/xuehepai/npc/caojob.h)→ "/d/xuehepai/quest/xhquest";"/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:107);name[0..1] → name[0..0](/kungfu/class/shaolin/qing-fa.lpc:102);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,不要重跑。

长度检查按字节写,旁边的提示按汉字写:14 处(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 你好吗)。本库 14 处(7 个文件):if ((strlen(name) < 2) || (strlen(name) > 10)) {(/adm/daemons/logind.lpc:1402);if ((strlen(name) < 2) || (strlen(name) > 12)) {(/cmds/bakcmds/csc.lpc:611)。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 区间 10 个文件。证明(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(一格两个空格)。本库 8 处(3 个文件)。证明(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 三向均可加载。

深度功能测试(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… 行。