info.html · 介绍 · play.html · 游玩 · llms.txt · 下载与本地运行 · ZIP · GitHub
"三界神话"系列第五个、也是最后一个档案(另见 099 `sjsh`/宝鸡站、100 `sjshv150`/紫藤分站、101 `sjshv2578bb`/测试二区、102 `sjshwzb`/泉州师院完整版),与 `sjshwzb` 共享同一份泉州地图、宗门配置(含独有的少林、峨嵋、昆仑支线)以及阿修罗界、魔界、天空界等神话场景,核心系统档案 99% 以上逐字节相同,是同一世界观的加强版而非另一款独立游戏。出生地〖南城客栈〗人物齐全:留言板、送礼物的☆小宁宁☆、热心店小二,以及暗示存在邮件系统的邮差"千里眼"(`d/ourhome/npc/bigeye.lpc`);死亡→复活循环完整可玩,在朱雀大街击杀敌人后会被送入〖阴阳界〗,由判官崔珏引导完成生死簿对话,再复活落地南城客栈。
English
The fifth and final build in the "Myth of the Three Realms" series (see also sjsh, sjshv150, sjshv2578bb, and sjshwzb) — an enhanced edition sharing sjshwzb's Quanzhou map, sect roster (including the exclusive Shaolin/Emei/Kunlun additions and the Asura/Demon-Realm/Sky-Realm mythology zones), and core system files almost exactly (99%+ of shared-path files are byte-identical). The starting Southern-City Inn is fully populated: a message board, a gift-giving NPC (☆小宁宁☆), an innkeeper, and a postman ("Farsighted Eye," d/ourhome/npc/bigeye.lpc) hinting at a mail system. Killing a mob on Vermilion Bird Street sends the player through death to Judge Cui Jue in the Yin-Yang Realm before respawning at the inn. The main operational difference from sjshwzb is that its wizlist started empty rather than pre-seeded.
README
内容亮点
- 是
sjshwzb(泉州师院完整版)的"加强版",地图与宗门内容几乎完全 一致(阿修罗、魔界、天空界等场景都在,另含少林、峨嵋、昆仑独有 分支)。 - 和
sjshwzb的主要区别在于运维细节:这份档案的wizlist原本 是空文件(sjshwzb已经有两个既有巫师),管理员账号是完全从零 写入的。 - 出生地〖南城客栈〗人物齐全:留言板、送礼物的☆小宁宁☆、店小二, 以及暗示存在邮件系统的邮差"千里眼"(
d/ourhome/npc/bigeye.lpc)。 经 §10.7 深度功能测试确认死亡→复活循环完整可玩:真实战斗击杀 朱雀大街的疥顶小僧后,送入〖阴阳界〗由判官崔珏走完生死簿对话, 复活落地荒郊小店;峨嵋〖华严顶〗(d/emei/)也已修复至可正常 进入,详见下方「本次修复的关键 bug」。
本次修复的关键 bug
1. 损坏的 convertd.lpc 字节:和 sjsh/sjshv150/sjshwzb
完全相同的损坏模式,同样的非 UTF8 杂散字节紧贴闭合引号("Illegal
character 0xce/0xb2/0xee/0x96/0xa3",第 258 行附近)。用同样的
字节级 Python 脚本修复了 45 处。
2. 经典 §8.1 check_legal_name() 的 i%2 奇偶假设:和
sjshwzb 完全相同的 bug 和修法——adm/daemons/logind.lpc 改成
逐字符检查(is_chinese(name[i..i]),去掉奇偶门槛),长度限制
从字节数 2-12 改成字符数 1-6。adm/simul_efun/chinese.lpc 的
is_chinese() 本身已经正确,不用改。
emoted.lpc/message.lpc/channeld.lpc 逐一检查过,均不存在
已知 bug。
3. §10.7 深度功能测试(2026-08-08)新发现并修复的 bug,详见
NOTES.md 的完整记录:logind.lpc 遗留调试 printf(§7.34)、
file.lpc 的 log_file() 缺 assure_file() 防护(§7.11)、
峨嵋〖华严顶〗房间引用大写 .C 文件在运行时 case-mismatch 崩溃
(§8.15,EMEI_B.C/YINGKE.C 已重命名为小写)、以及移植 §8.15
修复时新发现的 carry_object() 存在性检查对无扩展名路径假阴性
(新增 AGENTS.md §7.99)——起始房间南城客栈的邮差"千里眼"
NPC 原本会因为这个假阴性在每一次新角色注册时 100% 崩溃,已连带
修复并回填到 sjshwzb。§7.97(LISTNODES 死亡死循环)、§8.13
(WIZ 密码二次登录死锁)等其余家族已知 bug 类别均已逐条核实,
本档案不适用。
管理员账号 / Admin account
- ID:
fluffos - 管理密码 / Admin password:
Mud@2026 - 普通密码 / Regular password:
Mud@2027(双密码机制,规则要求 两个密码不能相同) - 权限 / Level:
(admin),通过/adm/etc/wizlist授予(这份 档案的 wizlist 原本是空文件,本次重新写入),登录横幅直接显示 "您的系统权限目前是:(admin)"确认生效,update指令验证写权限 正常。经 §10.7 深度测试确认可正常二次重连(本档案无 §8.13 类的 WIZ 密码登录死锁)。
警告:对外公开架设前请务必修改此密码。
注册流程提示
和 sjshwzb 完全相同:选择内码(GB/BIG5)→ 是否中小学生(回答
no)→ 输入 new → 英文 ID → 中文名字 → 管理密码 + 确认 → 普通密码
(必须与管理密码不同)+ 确认 → email(需要 [email protected] 格式)→
个人主页/ICQ(可留空)→ 性别 → 是否接受赠礼 → 天赋点分配。
本地运行
cd libs/sjshwzjqb
~/src/fluffos/build-debug/src/driver config.fluffos游戏端口:40173。
NOTES · 移植与修复记录
WASM 修复摘要(迁移自 meta.json 的 group_note)
三界神话「泉州师院」完整加强版,sjsh 家族集群的第五个也是最后一个。和 sjshwzb 同一血统——逐字节相同的 bug 组合:master.lpc 的 log_error()/standard_trace() 里没有 CHANNEL_D 呼叫(§7.60 不适用),securityd.lpc 的 valid_read() 从不覆盖驱动的 user 参数(§7.59 不适用),没有 sited.lpc(没有回环闸门)。WASM 修复:(1)熟悉的 convertd.lpc 字节级损坏(45 行,和 sjsh/sjshv150/sjshwzb 完全相同的 0xce/0xb2/0xee/0x96/0xa3 非法字符签名,第 258 行附近,同样的"杂散非 UTF8 字节转义闭合引号"模式)——用标准的字节级 Python 脚本修复。(2)adm/daemons/logind.lpc 里 §8.1 类的 check_legal_name() i%2 奇偶门槛,和 sjshwzb 完全相同的 bug 和修法:改成逐字符呼叫 is_chinese(name[i..i]),不设奇偶门槛,长度界限从字节数(2-12)改成字符数(1-6)。adm/simul_efun/chinese.lpc 的 is_chinese() 本来就是正确的码点区间检查——不用修。emoted.lpc/message.lpc/channeld.lpc:直接检查过,已知的 bug 都不存在也不需要修。管理员账号播种:fluffos (admin) 加入 adm/etc/wizlist(这份快照的 wizlist 档案是空的/只有空白字符,不像 sjshwzb 那份已经有两个其它巫师——是全新写入的)。注册流程在一次连续的 WASM 客户端会话里完整验证过,和 sjshwzb 完全相同的流程(GB/BIG5 选择→非学生关卡→"new"→英文 id→中文名字→管理密码+普通密码,必须不同→电子邮件,需要 [email protected] 格式→可选的个人主页/ICQ→性别→拒绝赠礼→属性分配),全程没有意外错误。管理员权限已直接通过登录横幅"您的系统权限目前是:(admin)"确认。LPC 格式化工具对全部 11569 个档案运行(写入 11286 个,72 个因为杂乱的历史代码报错,211 个未改动);还原了和 sjshwzb 相同的 2 个档案(panshi_dan.lpc、npc/mm.lpc),确认是转档之前就存在(作者一方,早于本轮)的缺引号损坏被格式化工具进一步重新加了空格。没有 :: 父类呼叫拆分命中。逐一比对了同一个 case 密集的档案(d/calvin/esman.lpc,内容和 sjshwzb 那份逐字节相同)——干净,没有语句被吞掉。通过去空白差异比对了全部 4 个 map.lpc 档案——所有差异都只是大括号排版风格(K&R 合并),内容零变化。格式化后用同样的完整注册流程重新验证过——干净,管理员权限依然是 (admin)。
§7.86 跨库扫描修复(留言板 post 崩溃)
BBS_BOARD、BULLETIN_BOARDinherit+ 多余replace_program()致命形状(AGENTS.md §7.86,post命令崩溃):全档案 42 处命中,已删除多余的replace_program(...)调用(保留inherit),逐文件保留原有行尾格式(CRLF/LF 按文件原样)。本次为跨库 §7.86 扫描修复(触发原因:该 bug 已在 6+ 个互不相关的血统家族独立确认,属于近乎普遍的拷贝粘贴模式),仅做编译检查(驱动干净启动、端口正常监听),未做完整 §10.7 深度游玩测试。
深度功能测试(§10.7,2026-08-08)
三界神话系列的第五个、也是最后一个档案。用原生驱动(build-debug/src/driver,端口 40173)通过 scripts/tmux_mud.sh 走完整轮,对照同家族已深挖的 sjsh(宝鸡站)/sjshv150(紫藤分站)/sjshv2578bb(测试二区)/sjshwzb(泉州师院完整版)NOTES.md 逐条核对候选 bug——README 已注明本档案和 sjshwzb 同源、核心文件(master.lpc/securityd.lpc/logind.lpc)与已知 bug 集合逐字节一致,但仍按项目惯例逐条独立验证,不直接照搬结论。
- §7.97(sjsh 上发现的 LISTNODES 死亡死循环 bug)——不适用,已核实排除:
work/include/net/config.h第 20 行#define LISTNODES ([ \本身就带着正确的续行反斜杠(cat -A确认行尾是\^M$,不是裸^M$),LISTNODES表项"SK": "61.141.216.74 6668"和sjshwzb完全相同(本档案与sjshwzb这个头文件是逐字节同源的少数几个文件之一)。为求实证,仍然用管理员测试角色fluffos(中文名"紫电仙人")在朱雀大街对疥顶小僧(d/city/npc/jieding.lpc,命中用它注册的 idxiaoseng)打kill xiaoseng到真实死亡:屏幕只打印一次"你死了",系统频道正常广播"【三界神话】某人:紫电仙人在长安城被疥顶小僧杀死了。",角色被送进〖阴阳界〗(/d/death/gate),判官崔珏(朱笔判官 崔珏)自动完整走完"你莫乱跑→生死有命→翻生死簿→命不该死送还阳"对话,角色活着落地复活室〖荒郊小店〗(/d/ourhome/kedian,气血:重伤),全程log/debug.loggrepdns_master/gchannel/No program in object均为零命中。确认本档案没有这个 bug。 - §7.11(log_file 缺 assure_file 防护)适用,已修:
adm/simul_efun/file.lpc的log_file()是裸seteuid(ROOT_UID); write_file(LOG_DIR + file, text);,同一份文件里紧接着定义的assure_file(file)辅助函数从未被调用(和sjsh/sjshv150/sjshwzb相同的形状,不像sjshv2578bb已经用MONITOR_D->log_file()转发做了防护);ls work/log/确认本档案确实没有随仓库分发nosave/目录。已按既定套路修:补一行前向声明void assure_file(string file);(assure_file()在文本顺序上定义在log_file()之后,这个编译器不会自动做前向解析),并在write_file()前调用assure_file(LOG_DIR + file)。防御性修复,本轮实测没有直接触发这几条日志路径(崩溃处理器、promote指令),按既定"看到就修"的低风险改动处理。 - §7.34(logind.lpc 遗留 debug printf)适用,已修:
adm/daemons/logind.lpc第 772 行get_name()里,在ob->set("name", arg)之前有一行裸printf("%O\n", ob);,会把登录对象的内部路径原样打印在中文名字确认和密码提示之间——用fluffos账号首次注册(中文名"紫电仙人")时现场复现确认。已删除该行;重新走一遍注册/重连流程,全程 grep 输出确认没有任何login#/obj/user//obj/login字样泄漏。全档案只有这一处printf("%O命中,logind.lpc里没有第二条并行的"接受系统建议名字"路径需要一并检查。 - §8.13(sjshv150 上发现的 WIZ 密码二次登录死锁)——不适用,本档案是完全不同的登录架构,和
sjshwzb一致:全档案 grepwiz_password/get_wizpwd零命中——adm/daemons/logind.lpc走的是双密码架构(管理密码 + 普通密码,注册时就必须两个都设置且不能相同),重新登录时只走一次get_passwd(),没有任何"密码从未设置就永久卡死"的死结。用fluffos账号实测反复重连(含一次跨越驱动重启的重连,score显示"您是第 三 次连接三界神话「泉州师院」"),每次都正常用普通密码登录进入游戏,无一次卡死,之前的死亡/复活状态(重伤、被杀害次数)也正确保留。 - §8.15(sjshwzb 上发现的 Windows 大写
.C文件 runtime case-mismatch 崩溃)——适用,已修,且比sjshwzb多发现一层新崩溃:obj/board/EMEI_B.C(峨嵋"仙石碑"留言板)和d/emei/NPC/YINGKE.C(峨嵋"女童"迎客 NPC)两份大写扩展名文件与sjshwzb完全对应(家族共享的同一处历史遗留)。d/emei/huayanding.lpc(〖华严顶〗房间)的create()里set("objects", (["npc/yingke": 1]))引用的小写路径解析到磁盘上不存在的位置(真实文件是d/emei/NPC/YINGKE.C),new()静默返回0,紧接着std/room.lpc的make_inventory()对0调用ob->move(...)抛出Bad argument 1 to EFUN call_other();同一create()末尾"obj/board/emei_b"->foo();既缺前导/、又指向大写的EMEI_B.C,同样解析失败。用update /d/emei/huayanding强制重编译复现(编译期干净,只有第一次真正reset()/setup()时才炸,和sjshwzb记录的诊断方式一致)。修复:git mv obj/board/EMEI_B.C obj/board/emei_b.lpc、git mv d/emei/NPC/YINGKE.C d/emei/NPC/yingke.lpc,huayanding.lpc两处引用相应改成__DIR__ "NPC/yingke"和"/obj/board/emei_b"->foo();,emei_b.lpc顺带清理掉多余的replace_program(BULLETIN_BOARD)(本档案自己的跨库 §7.86 扫描因为大写.C扩展名同样漏掉了这一处,和sjshwzb的EMEI_B.C完全同一形状)。新发现的第三层崩溃、以及对 §8.15 修复本身的一处必要修正:yingke.lpc的create()有一句carry_object("/d/shaolin/obj/cloth.c")->wear();,指向一个从未真正转档的路径(work/d下没有小写shaolin目录,只有大写d/SHAOLIN/,和sjshwzb完全同一形状),照搬sjshwzb已经验证过的std/char/npc.lpc::carry_object()存在性防护(file_size(file) < 0直接return 0)后,这个防护本身在本档案上暴露了一个更大范围的假阴性回归:d/city/kezhan.lpc(起始房间〖南城客栈〗)里的d/ourhome/npc/bigeye.lpc(邮差"千里眼",README.md记载的邮件系统提示 NPC)的create()有carry_object("/d/ourhome/obj/linen")->wear();——这个文件是真实存在、正确大小写的合法内容(d/ourhome/obj/linen.lpc),但因为调用方没带扩展名,新加的file_size(file) < 0检查对它也返回真(file_size()是字面stat(),不像new()/load_object()那样做.lpc→.c扩展名解析),于是每一个全新角色第一次踏入起始房间就必定崩溃——比原来"只影响峨嵋一间偏僻房间"的范围严重得多,命中率从"极少数玩家去过峨嵋"变成"100% 的新注册玩家"。已就地根治并记录为新的 AGENTS.md §7.99:把存在性检查改成同时探测file_size(file)/file_size(file+".lpc")/file_size(file+".c")三种形式都失败才判定为缺失。已回填同一修法到sjshwzb自己的std/char/npc.lpc(该档案携带同一份bigeye.lpc/carry_object()组合,同样具备触发条件,现场重新验证:fluffos账号重连南城客栈,look显示"千里眼"正常在场,debug.log无崩溃——详见sjshwzb/NOTES.md补充说明)。三处改完(大小写重命名 ×2、carry_object()三态检查 ×1)后驱动重启验证:全新账号完整注册 → 落地〖南城客栈〗(千里眼/店小二/小宁宁全部正常在场,无崩溃)→update /d/emei/huayanding手动重编译峨嵋房间"成功!",log/debug.log全程零Bad argument/No program in object/call_other错误。 - §8.9(食物/饮水初始化)不适用:
confirm_gift()直接user->set("food", user->max_food_capacity())/user->set("water", user->max_water_capacity()),没有对象混用、没有年龄闸门。测试角色fluffosscore食物/饮水全程显示"正常"(满格)。 - §7.88/§7.12(message() varargs 缺陷)不适用:
adm/simul_efun/message.lpc里根本没有自定义message()包装函数(只有message_vision()/tell_room()/say()/printf()),不存在"4 参数声明、3 参数调用"的缺陷形状;本轮死亡广播、频道消息等大量触发message/tell_room的路径全程零崩溃。 - §8.3a(
private nomask command_hook)不适用:feature/command.lpc里command_hook()声明就是nomask int command_hook(string arg),注释里留着一行被注释掉的旧声明// private nomask int command_hook(string arg),说明这条修复在更早的一轮已经存在。 - §8.3b(
commandd.lpc的.c后缀 sscanf)不适用:整个档案没有commandd.lpc这个文件,指令分派走feature/command.lpc的add_action机制。 - §7.5(securd/securityd 自定义 ACL 拒绝编译期访问)不适用:
adm/daemons/securityd.lpc的valid_read()对不在{read_file, file_size, stat, read_bytes, tail, ed_start}白名单里的 func 一律直接return 1,不是"默认拒绝"的 fail-closed 形状;!euid分支同样直接return 1(放行),不是 §7.5/§7.98 那种"未认证即拒绝"的形状。本轮完整跑过注册、战斗、死亡、复活、post、update(触发大量首次编译/首次读取)等路径,log/debug.log未观察到任何 access-denied 类报错。 - §7.98(daemon
create()缺seteuid())不适用:全程log/debug.log没有出现任何 preload 期的explode()/sscanf()崩溃(驱动启动日志本身也完全干净,只有大量无害的Unknown #pragma/Number of arguments to 'save'/'remove' disagrees编译警告)。 - §7.90(eval cost 上限)本次未观察到问题,
config.fluffos保持项目默认700000未改动:跨越注册、天赋分配、多次移动到未编译过的房间(朱雀大街、峨嵋华严顶等)、真实战斗到死、完整复活流程、post/read/update(连续多次强制重编译)等操作,全程未见任何cost limit reached/Too long evaluation报错。 - §8.3/§7.68/§7.86 其它变体均未见新增实例:
command_hook()无private;没有第二个"WIZ 密码"式登录闸门;本轮死亡/复活是一次全新账号、无任何外力打断的正常流程,没有触及 §7.68 那种 present() 语义分歧,未做任何"重试代替放弃"式改动。 - 管理员写权限已现场验证:用
fluffos账号连续执行update /d/emei/huayanding(两次,一次修复前的失败重现、一次修复后的成功确认)全部按预期动作,确认default_trusted_write对(admin)授予的不受限写入权限确实生效。 - 留言板
post/read验证通过,§7.86 修复线上确认有效:在〖荒郊小店〗对"生死之间留言板"(obj/board/common_a.lpc)成功post一条标题「深度测试」的留言并用look board读出,无崩溃。这份留言板数据在测试前是全新/空白的(look board显示"没有任何留言"),不是转档带来的历史内容,测试留言在提交前已用git restore撤销(git diff确认改动前后仅这一条新增记录,没有需要保留的历史内容)。南城客栈的"南城客栈留言板"全程显示"没有任何留言",同样是空白状态,未受影响。 - 商店
list验证通过:荒郊小店"店小二"list出炸鸡腿/红烧狗肉/西瓜/花雕酒袋及价格,buy本轮时间有限未实测。 - 完整死亡→复活循环、注册、
look/score/quit、二次重连均已现场验证:全新角色注册(new→fluffos→中文名"紫电仙人"→双密码→邮箱→个人主页/ICQ 留空→性别→天赋分配9/y→落地〖南城客栈〗)→移动到朱雀大街kill xiaoseng打死疥顶小僧(真实战斗,非秒杀)→"你死了"仅出现一次→〖阴阳界〗判官崔珏对话→复活落地〖荒郊小店〗(重伤但存活)→post/look board→list→quit(正常退出提示"你历了太多的江湖风风雨雨……",连接干净关闭);随后二次重连同一账号(score显示"第 三 次连接"),look正常,quit再次干净退出。log/debug.log全程 grep执行时段错误\|Bad argument\|No program in object\|Segmentation零命中(仅有大量无害的编译时段错误:...Unknown #pragma, ignored/Unused local variable编译警告,与实际运行时错误无关)。 - 未覆盖:帮派/门派拜师流程未触及;
d/emei/NPC/、obj/board/、d/SHAOLIN/之外的其它大写目录残留(和sjshwzb记录的一样,find . -type d -regex '.*/[A-Z][A-Z0-9_]*$'命中多个非binaries/目录)未逐一探查是否也有类似的死链,留给后续转档专项;邮件系统(千里眼NPC 暗示存在)未实测具体指令。
家族总结(5/5 成员全部深挖完毕,2026-08-08)
sjshwzjqb 是三界神话「三界」系列 5 个档案家族(sjsh/sjshv150/sjshv2578bb/sjshwzb/sjshwzjqb)里最后一个完成 §10.7 深度功能测试的成员。基于本档案自己的发现和其余 4 份手足档案各自 NOTES.md 记载的结果,按 bug 类别汇总复现频率(分母固定为 5):
| Bug 类别 | 命中家族成员数 | 备注 |
|---|---|---|
| §7.34(logind.lpc 遗留 debug printf) | 5/5 | 全员命中,逐一确认并删除,是本家族最普遍的问题 |
| §7.11(log_file 缺 assure_file 防护) | 4/5 | sjsh/sjshv150/sjshwzb/sjshwzjqb 命中;sjshv2578bb 通过 MONITOR_D->log_file() 转发已自带防护 |
| §7.86(board inherit+多余 replace_program()) | 5/5 | 全员命中(跨库扫描批量修复),另有 sjshwzb/sjshwzjqb 各自独立发现的一处大写 .C 扩展名漏网实例(§8.15 附带) |
| §7.97(LISTNODES 缺续行反斜杠死循环) | 1/5 | 仅 sjsh 命中,其余 4 份档案该头文件各自独立维护、内容不同源 |
| §8.13(WIZ 密码二次登录死锁) | 1/5 | 仅 sjshv150 命中;sjshv2578bb 通过 #ifdef NO_CHECK_WIZPWD 已自行规避;sjshwzb/sjshwzjqb 走双密码架构、压根没有这个登录闸门 |
| §8.15(大写 .C runtime case-mismatch 崩溃) | 2/5 | 仅 sjshwzb/sjshwzjqb(同一血统分支)命中,sjsh/sjshv150/sjshv2578bb 无此内容 |
| §7.99(file_size() 存在性检查对无扩展名路径假阴性,本轮新增条目) | 2/5 | sjshwzjqb 现场发现并修复,回填修复到同血统的 sjshwzb |
| §8.9/§7.88/§7.12/§8.3a/§8.3b/§7.90/§7.5/§7.98 | 0/5 | 全员均不适用(各自独立验证,非假设性排除) |
结论:这个家族最稳定、跨全部 5 个快照复现的问题是 §7.34(遗留调试输出)和 §7.86(留言板崩溃),说明这两处很可能是某个更早的共同祖先档案里就已经存在的缺陷,被逐代快照原样复制。§7.97/§8.13/§8.15 则是各快照独立分叉演化后产生的差异——同一代码库的不同存档时间点,会因为管理员各自的修补历史不同而携带不同的遗留 bug 子集,"血统相同"不能替代逐份验证。§7.99 是本轮唯一一个纯技术性的新发现:不是这份档案原始代码的 bug,而是本项目自己在移植 §8.15 修复时引入的一个新的假阴性风险,提醒未来任何"加一层 file_size() 存在性检查"式的防御性修复都要连带检查同一辅助函数的其它调用方。
§7.100 扫描修复(ROOM 基类多余 replace_program())
#define ROOM "/std/room":删除 644 处多余的、独立成行的
replace_program(ROOM);(保留 inherit ROOM;),636 处脚本自动
删除;另有 4 份房间建造工具副本手动修正——obj/roommaker.lpc、
u/calvin/obj/roommaker.lpc 是标准的"两套模板"简单变体;
u/qkl/roommaker.lpc、u/koker/obj/teshu/roommaker.lpc 是手足
sjshwzb 同批也命中的"3 处出现"room_code/str 变体,三处均手动
删除。work/data/room/*.lpc(4 个文件,与 sjshwzb 同名同构)确
认无此调用,无需处理。修复后全库仅剩 26 处历史遗留的
//-注释掉实例,均确认无害、未改动。已用 build-debug 驱动干净
启动验证(0 个新增编译错误,端口 40173 正常监听,debug.log 无新
增 "cannot replace"/"cannot bind" 行);未做完整 §10.7 深度游玩
测试。
§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): 3 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.
深度功能测试第二轮(2026-08-23):死亡计数器、buy、拜师、大写目录死链、邮件系统
用既有的 fluffos 账号(§10.7 深挖账号)通过原生驱动(端口 40173)+
scripts/tmux_mud.sh 逐条核实 2026-08-08 那轮记录的「未覆盖」四项。
本档案和刚测完的同源手足 sjshwzb 逐字节同源的核心文件集合完全一致
(combatd.lpc/weapon.h/std/room.lpc/d/nanhai/*),所以本轮直接
对照 sjshwzb 那轮的发现逐项复核,而不是从头盲测——多数命中的是同一
血统里独立分叉演化出的同一个 bug。
- 被杀害次数计数器(
combatd.lpckiller_reward())——本档案自己的 §10.7 深挖会话之前已经确认并修复(commit74a85438aae):这是sjshwzb那轮现场发现的 bug(killer->add("PKS", 1);之后缺killer->add("PKD", 1); victim->add("DIE", 1);两行),因为两份combatd.lpc逐字节相同,直接比对确认后原样移植过来,无需重新调查。 本轮现场复核:score基线"被杀害:0 次" →kill xiaoseng致死疥顶小僧 → 判官崔珏送还阳 → 复活后score显示"被杀害:1 次", 确认修复在真实驱动上生效,debug.log全程无combatd相关报错。 list/buy——真实 bug,已修(新发现,sjshwzb没有这一处): 南城客栈"店小二"(d/city/npc/xiaoer.lpc)的list指令 (feature/vendor_sale.lpc/d/city/npc/xiaoer.lpc的do_vendor_list())现场执行时崩溃:*No program in object '/d/lingtai/obj/shengmao'!("三界神帽",货架上第五项商品)。追查到d/lingtai/obj/shengmao.lpc第 8 行set_name( HIC "三界神帽 NOR , ({...}) );——"三界神帽"这个中文字符串字面量缺了闭合引号(正确形状 应为HIC "三界神帽" NOR,对照同档案std/skill.lpc里HIC "举世无双" NOR等一致写法确认),导致后面的NOR被吞进字符串、 再往后一路吞到下一个真正的引号("sheng mao"前那个),使编译器在 随后的set("unit", "顶")等语句处把已经是合法 UTF-8 的中文字节序列 当成裸源码字符解析,报Illegal character 0xe9等一串虚假的"非法字符" 错误,最终整个档案*No program in object*——和 README 记载的 convertd.lpc"杂散非 UTF8 字节转义闭合引号"损坏是同一个根因类别(缺引号), 只是这次落在货物档案而不是转档脚本产物。逐字节比对确认sjshwzb的 同名档案d/lingtai/obj/shengmao.lpc携带完全相同的缺引号损坏,同样 会在list时炸——是两份档案共同祖先里就存在的 bug,不是本次转档 引入的,但此前两轮 §10.7 测试都只测了list本身没崩(sjshwzb那轮的货架里没炸到这一项,或没触发到list全量遍历),这是本档案 第一次真正命中并定位。已在d/lingtai/obj/shengmao.lpc第 8 行 补回闭合引号。lpcc --batch确认档案编译通过;驱动重启后现场复测list正常显示全部 12 项货物(含"三界神帽"),随后buy jitui from xiaoer(炸鸡腿,八十文钱)用clone一两银子(一百文)购买,找零 精确为"二十文钱"、炸鸡腿正确入包——找零/库存运算本身没有 bug。- 拜师(
apprentice)流程已实测,正反两条路径都正常,无 bug: 南海普陀山"大圣国师王菩萨"(d/nanhai/npc/master.lpc)对无门派角色apprentice pusa正确按战功/佛法门槛拒绝("老夫不收外门弟子……"), 南门"赵神将"(d/nanhai/npc/zhao.lpc,attempt_apprentice()的else分支对非本门弟子直接收徒、无门槛)apprentice zhao成功拜师,score的"师承"字段正确显示"南海普陀山赵神将"。feature/ apprentice.lpc/cmds/std/apprentice.lpc机制本身没有 bug;具体 门槛数值属于内容设计,未改动。(sjshwzb用的是zuozhizhu.lpc这个不同的掌门 NPC,本档案没有d/swordman-map/这个区域,改用 同样具备"无条件收徒"else分支的zhao.lpc,效果等价。) - 大写目录死链——和
sjshwzb完全同一血统的三层修复,已提前在apprentice测试前一并核实存在并修复:d/nanhai/npc/master.lpc的carry_object("/d/xuyi/obj/tianlong")->wield()会命中include/weapon.h缺失的HALBERD/F_HALBERD宏定义(对比同档案 其它 14 种武器类型都有对应宏),这本来会让 7 个现役戟类武器档案 (d/xuyi/obj/tianlong.lpc等)编译期直接语法错误、goto /d/nanhai/xiaoshi现场必崩,挡住apprentice pusa的第一次测试。 比对sjshwzb那轮的诊断和修法(weapon.h补#define HALBERD "/std/weapon/halberd"/#define F_HALBERD "/std/weapon/_halberd")后原样移植过来,逐字节 相同问题。同时移植了std/room.lpc的make_inventory()防护 (new()失败返回 0 时不再对 0 调用->move(),改为if (!objectp(ob)) return 0;)和reset()case 1分支的objectp(ob[list[i]]) &&短路检查——d/nanhai/zhulin0.lpc(〖紫竹林〗) 的objects表里同样有__DIR__ "npc/tianji": 1指向不存在的小写 路径(真实文件是大写/d/youxia/NPC/TIANJI.C),goto /d/nanhai/zhulin0复现过同一个Bad argument 1 to EFUN call_other()崩溃,修完后房间正常加载(缺失的 NPC 不出现,不崩)。lpcc --batch批量复查(11568 个档案,11261 通过/307 失败)确认失败集里只有已知的 历史遗留死档案(/d/nanhai/obj/tianlong等),没有新增回归。 - 邮件系统("千里眼" NPC)已实测,机制本身没有 bug,但发现一个值得 记录的"read"动词歧义(非崩溃,未改动):
d/ourhome/npc/bigeye.lpc的inquiry表把"mail"/"发信"/"收信"等关键词映射到send_mail()/receive_mail(),ask qianli yan about mail在 南城客栈里成功领到一个私人信箱(obj/mailbox.lpc,千里眼只在startroom里才发放)。mail fluffos现场完整走完标题→正文 (edit(),.结束)→是否留底稿(y)的流程,成功寄出(因为收件人 就是自己,send_mail()的ppl && this_player()->visible(ppl)分支直接命中同一个信箱对象,from/readmail 1都能看到 2 封信)。 发现的歧义:obj/mailbox.lpc把do_read同时注册在"read"和"readmail"两个动词上(add_action("do_read", "read"); add_action("do_read", "readmail");),但南城客栈本身还有一块留言板 (obj/board/nancheng_b.lpc,继承BULLETIN_BOARD)也注册了"read"动词;现场验证裸read 1命中的是留言板的do_read()(返回"留言板上目前没有任何留言。")而不是信箱的,readmail 1则正确显示信件内容——说明这个驱动/mudlib 的多对象同名动词搜索顺序里, 房间内其它对象(留言板)的add_action排在玩家自己随身物品(信箱) 前面。这不是崩溃、不是数据丢失(信件一直都在,只是要用没有歧义的readmail才能读到),而且 mailbox.lpc 自己已经预留了无歧义的readmail别名,符合"没有错误信号(崩溃/debug.log 报错/结构性 计数器失效)的多半是设计/边界情况"的既定判断标准,所以未作为 bug 修复,只记录在案,供后续如果要统一多对象动词优先级时参考。另外 确认了信箱是房间绑定的临时道具:一旦离开千里眼所在的startroom(南城客栈),信箱会被自动收回("你将信箱交回给邮差。"), 角色死亡时也会被强制收回("你看到紫电仙人的信箱破空而去……")——均 是既有设计,非 bug。测试产生的邮件数据(data/mail/f/fluffos.o) 在提交前已删除,不留存测试内容。 - 管理员写权限、驱动重启持久化均已现场复核,与既有记录一致:本轮 全程使用既有
fluffos(admin) 账号,score显示"第 五 次连接", 之前记录的〖重伤〗气血状态、门派/被杀害计数在跨会话/跨死亡后均正确 持久化。
修复文件清单(本轮):d/lingtai/obj/shengmao.lpc(缺引号,真实
崩溃修复)、include/weapon.h(补 HALBERD/F_HALBERD 宏,移植自
sjshwzb)、std/room.lpc(make_inventory()/reset() 空指针防护,
移植自 sjshwzb)。工具调用数约 90 次,在预算范围内。
AGENTS.md §7.19 sweep (2026-09-01): enable_player() reentrancy from init()
Same corpus-wide bug class as mhxy/wuhanzhan (AGENTS.md §7.19): this
lib's feature/command.lpc enable_player() wrapper (around the raw
enable_commands() efun) is reachable from an NPC's init() via a
redundant create()-then-init()-calls-setup() (or reset_me()
calling setup()) chain -- confirmed live via a static scan of every
init() body in this lib: 50 NPC/item files call setup() directly
or via reset_me() from init(), after create() already called
setup() once (which already made the object living()). Calling
enable_commands() a second time on an already-living() object makes
the driver re-invoke that object's own init() as a side effect, which
re-enters this same chain while the original call is still on the
stack -- genuine reentrancy, crashing with "Too deep recursion" (most
likely to surface on an NPC's first-ever preload/compile).
feature/damage.lpc's revive() and cmds/std/sleep.lpc's wakeup1()/wakeup2() call enable_player() again while the object is still living(). This confirms a bare if (living(this_object())) return;
guard would be the WRONG fix (it would silently break that legitimate
re-enable) -- used the same true reentrancy-flag fix as mhxy instead:
a nosave private int in_enable_player_now; set for the duration of the
wrapper's body, guarding only genuine same-call-stack reentrancy while
leaving every legitimate re-enable (revive/wakeup/disguise) unaffected.
feature/command.lpc's enable_player() had a single fall-through exit
(no early returns), so one guard-at-top + one clear-at-bottom pair was
sufficient. Verified via a single-file lpcc --batch compile check
(PASS) -- not individually live-boot-tested.