info.html · 介绍 · play.html · 游玩 · llms.txt · 下载与本地运行 · ZIP · GitHub
笑红尘Ⅱ由拓勘资讯组(topkan.com)开发,地图(华山、武当、峨嵋、丐帮、明教、大理、荆州等门派与城池)以及"世界之巅"跳崖场景(连 `out` 跳崖指令、`wizardp()` 免摔死判定都完全相同)几乎逐字与本项目的 `tybxjh`(该血统的源头版本)、`wlhd` 一致,属于同一支"天涯"家族的又一分支——这层关系还延伸到 `zxty`(再现天涯)、`ffxymud`(非凡夕阳MUD)、`jhfy2`(江湖风云2)、`xysylmhb`(夕阳三·炎龙美化版)、`xyzxiiylzymh`(夕阳再现II·炎龙专用美化客户端)等多部同源作品,此前的 AGENTS.md 里未记录这层完整关系。注册流程比 `tybxjh` 的双密码机制更简洁,只需单一密码加二次确认。
English
Developed by Topkan Information Group (topkan.com), Xiao Hong Chen II shares its map — sects and cities including Huashan, Wudang, Emei, the Beggars' Sect, the Ming Cult, Dali, and Jingzhou — and its "Peak of the World" cliff-jump scene (down to the exact wizard-immunity check) almost verbatim with this collection's tybxjh (the lineage's root) and wlhd, a relationship shared with several other archives that use the same "Tianya" master/securityd/logind core — zxty, ffxymud, jhfy2, xysylmhb, and xyzxiiylzymh. Registration here uses a single password rather than tybxjh's dual-password scheme.
README
内容亮点
- 注册横幅文字里有一处历史遗留的字符集乱码("也会渌婕乙桓龊玫镊 印象",大概率原意是"也会给其他玩家一个好的印象"),是内容/本地 化问题,不影响游戏功能,本次未做改动。
- 深度功能测试(§10.7)发现并修复两个从未被记录过的严重 bug:一 个让每一次注册都会在性别选择后卡死(之前被误判为 WASM 客户 端计时竞态,实际是缺失的
/log/login/目录导致注册流程被截 断,新增 AGENTS.md §7.86),另一个让全档案约 90 块留言板的post指令全部立刻崩溃(inherit一个类之后又多余地对自己replace_program()成同一个类,同一条 AGENTS.md §7.86),详见 下方和 NOTES.md。
本次处理内容
WASM 修复阶段的结论过于乐观。深度功能测试(§10.7)修复了:
adm/daemons/logind.lpc的 2 处 printf 调试残留(与tybxjh逐 字节相同)。- §8.9 食物/饮水年龄检查错对象(
ob->query("age")应为user->query("age"))。 - 注册流程本身的致命 bug:
get_gender()里一次没有保护的log_file("login/newid.log", ...)调用,档案里根本没有/log/login/这个目录,导致每一次注册在性别选择之后都会被无声 截断——init_new_player()/enter_world()从未执行,玩家的指令 系统从未挂上去,之后任何输入都是"什么?",角色也从未真正存盘。 这正是此前 WASM 修复笔记里"计时竞态,无法稳定复现"那段描述的真 正原因——不是客户端计时问题,是每次注册都 100% 命中的真实 bug。 已创建log/login/目录并给这次log_file()调用加上catch()防护。 - 约 90 处留言板文件里同一个多余的
replace_program()自我替 换,导致post指令在任何留言板上都会立刻崩溃(*cannot bind an lfun fp to an object with a pending replace_program())。既然 这些文件已经inherit BULLETIN_BOARD,编译期就拿到了全部留言板 功能,运行时再自我替换成同一个类纯属多余且有害——已全部删除这行 多余调用,保留inherit。发现至少 4 份文件里这行代码早被前任巫 师注释掉,大概率是各自独立踩过这个坑但没找到根因。
另外确认 tybxjh 发现的两个 bug 在这里不适用:这份档案是单一
密码注册(没有 tybxjh 那套双密码机制),源码里也确实没有对应的
明文密码泄漏(§7.84);score.lpc 的进度条渲染用的是完全不同、正
确的循环式实现,没有 §7.85 那种残留宽度乘数问题。
唯一的账号播种动作:在 /adm/etc/wizlist 里加入管理员账号(原文
件是空的,SECURITY_D 正确指向 /adm/daemons/securityd,
wiz_levels 阶梯最高是 (admin))。
顺带一提:注册横幅文字里有一句"也会渌婕乙桓龊玫镊印象",看起来是 原始档案某次字符集转换出问题留下的乱码(大概率原意是"也会给其他 玩家一个好的印象"),这是内容/本地化问题,不是程序 bug,未做改 动。
管理员账号 / Admin account
- ID:
fluffos - 密码 / Password: 注册时自设(单一密码 + 确认)
- 权限 / Level:
(admin),通过/adm/etc/wizlist授予。
警告:对外公开架设前请务必修改此密码。
本地运行
cd libs/xhcii
~/src/fluffos/build-debug/src/driver config.fluffos游戏端口:40163。
NOTES · 移植与修复记录
WASM 修复摘要(迁移自 meta.json 的 group_note)
笑红尘②,由拓勘资讯组(topkan.com)开发。在 WASM 下启动并完整完成注册,没有任何编译或运行时错误,也没有任何被捕获的异常——没有发现任何 LPC bug。唯一采取的行动:把 fluffos (admin) 播种进一个空的 adm/etc/wizlist(SECURITY_D 正确指向 /adm/daemons/securityd;globals.h 里有一条注释掉的 '// #define SECURITY_D "/adm/daemons/securd"' 诱饵提醒但未生效;wiz_levels 顶层是 (admin),已从结构上确认通过 trusted_write 授予完整的 '/' 写入权限)。注册流程在一次连续的 WASM 客户端会话里完整验证过:英文 id→y/n 创建确认→中文名字→单一密码+确认→天赋数值选择(0 为随机,y 接受)→电子邮件(需要 id@address 格式)→性别→带着 MOTD、起始房间描述、NPC 问候和可用的 'look' 指令进入游戏世界,全程没有任何意外错误——用 catch() 包裹了 get_gender()/init_new_player()/enter_world() 每一步来打点确认,性别选择之后进入游戏世界的整条路径上零异常。管理员权限在播种前已通过标准的 '★ 您目前权限:' 横幅实时确认显示为 '(player)';播种后对应的 '(admin)' 实时确认因为这份档案特有的一个明显的 WASM 专属测试工具计时问题而没能稳定重现——/inherit/char/char.lpc 第一次编译的爆发期(加载 feature/name.lpc、feature/skill.lpc、feature/move.lpc 等)足够沉重,导致性别选择后不久发送的任何指令都有很高概率落在 '什么?'(无法识别),不管 --idle 怎么设都一样(在 --idle 3 到 15 之间都复现过这个失败,而底层那次成功的运行——--idle 6——也没能稳定重现)——这是一个客户端计时竞态,不是 mudlib 缺陷:一次完整干净的运行(格式化之前)通过直接的 catch() 插桩确认了性别选择之后全程零捕获错误,管理员等级权限也已经通过 securityd.lpc 的 trusted_write 表独立地从结构上确认。另外记录(不是 bug,纯粹是内容层面,按范围保持原样未动):logind.lpc 的注册横幅文字里有一处转档前就存在的乱码/转码错误的中文短语('也会渌婕乙桓龊玫镊印象',看起来本意是想说类似'也会给其他玩家一个好的印象')——这是早于本轮的内容/本地化问题,不是程序 bug。LPC 格式化工具对全部 7080 个档案运行(写入 6990 个,53 个因为杂乱的历史代码报错,37 个未改动);还原了 1 个档案(d/city/sj.lpc)确认有转档之前就存在(作者一方,早于本轮)的缺引号损坏被格式化工具进一步重新加了空格——和 tybxjh 上已经见过的同一个档案/模式。没有 :: 父类呼叫拆分命中,没有 case 标签带尾随注释的候选。全部 6 个 map.lpc 档案确认内容完全相同(只是空白差异)。格式化后重新验证开机干净(零编译错误);注册流程重新验证到密码/属性/邮箱阶段,底层账号/权限逻辑没有被格式化改变(只有 logind.lpc 注册路径之外的档案被做了纯排版的重新格式化,已逐一 diff 审查)。
深度功能测试(§10.7,2026-08-05)
之前"没有发现任何 LPC bug"的结论是错的——上面提到的"性别选择后指令
经常落空"从来不是客户端计时竞态,而是一个真实存在、每次注册都会命
中的严重 bug(见下)。这份档案是 104 tybxjh(天涯之碧血江湖)的
同源"天涯"家族成员,先检查了 tybxjh 自己已完成的 §10.7 记录(2
处 printf 调试残留、§8.9 食物/饮水年龄检查错对象、exert_function()
类型错误、一处明文密码泄漏进 doc/help 的严重安全问题、进度条渲染缩
放 bug),逐项在 xhcii 自己的源码里核实:
- 2 处 printf 调试残留:
adm/daemons/logind.lpc的get_resp()/get_name()里各有一处printf("%O\n", ob),和tybxjh逐字节相同。已删除。 - §8.9 食物/饮水年龄检查错对象:
enter_world()里if (ob->query("age") == 14),同样的错对象判断。已改为user->query("age")。 - §7.84(tybxjh 的明文密码泄漏)不适用:这份档案用的是单一密 码+确认的简化注册流程,没有
tybxjh那套双密码机制,源码里也确 实没有对应的write_file("/doc/help/...")调用——核实过,不是漏 查,是这个 bug 根本不存在的前提(双密码机制)在这里不成立。 - §7.85(tybxjh 的进度条渲染缩放 bug)不适用:
cmds/usr/ score.lpc的tribar_graph()是完全不同的、循环式的正确实现 (10 段式,val*100/max/10换算,无残留宽度乘数),和tybxjh出问题的那个切片式实现是两种不同写法,这里没有同类 bug。 - 一个从未被记录过的严重 bug,本次深挖真正的核心发现(已写入 AGENTS.md §7.86):之前 WASM 修复阶段记录的"性别选择后指令经 常落空、疑似客户端计时竞态",实际根源是
get_gender()里一次没 有保护的log_file("login/newid.log", ...)调用——档案里根本没 有/log/login/这个目录(经典的 §7.11 缺失运行时目录模式), 这一行抛出未捕获错误,直接把整个get_gender()函数从这里截断, 后面的init_new_player(user)/enter_world(ob, user)全部没有 执行——玩家的指令系统根本没有挂上去,之后无论输入什么都是"什么?" 永远卡住,角色也从未真正存过盘。用 tmux 重新走一遍注册流程,在work/log/debug.log里直接抓到了这个报错,确认这才是真正原因。 已创建work/log/login/目录(同时补进scripts/wasm_keep_dirs.txt,供 WASM 打包复现这个目录形状), 并给这次log_file()调用加上catch()防护(双重保险:目录已 经修好,但万一以后又出现类似缺失目录,不应该再让整个注册流程被 一次日志写入拖垮)。修复后重新走完整注册流程,性别选择后立刻正 常进入游戏世界,work/log/login/newid.log也正确写入了记录。 - 另一个从未被记录过的严重 bug(已写入 AGENTS.md §7.86):留 言板的
post指令在任何一块留言板上都会立刻崩溃:*cannot bind an lfun fp to an object with a pending replace_program()。根源是全档案约 90 份留言板档案(clone/ board/*_b.lpc和散落在d/**/下的若干份)的create()里都 同时做了inherit BULLETIN_BOARD;(编译期已经拿到全部留言板功 能)和多余的replace_program(BULLETIN_BOARD);(运行时再自我替 换成同一个类)——这个多余的自我替换让该物件永远卡在"replace 挂 起"状态,导致后续任何尝试给它自己的 lfun 绑定闭包的操作(正是do_post()调用编辑器回调所需要的)永久失败,而read/look等不涉及闭包的指令完全正常,这正是这个 bug 之前从未被发现的原 因——留言板表面看起来完全正常。已删除全部 90 处多余的replace_program(BULLETIN_BOARD);调用(保留inherit,功能不 变);已发现至少 4 份档案里这一行早就被前任巫师注释掉了(大概率 是踩过同样的坑但没有找到根因,逐个文件手工规避)。修复后重新走 过一遍:post正常打开编辑器,留言完毕保存成功,留言板未读数 正确更新——重启驱动后二次确认依然正常。 - 战斗/死亡/复活测试:注册后随机落地在铁枪庙(泉州,和
tybxjh同一批场景),kill wuya一战不敌乌鸦阵亡(这里的乌鸦明显比tybxjh那边更凶悍,几回合就见血)。死亡后落到鬼门关,白无常在场,判定守卫是同样的if (!ob || !present(ob)) return;写法 (AGENTS.md §7.68,现已收窄到仅bmxkx2001适用)——按新纪律没 有做任何改动,让流程原样跑完,全程未受打扰,复活正确送到武庙, 角色状态(疲倦/受伤但存活、食物/饮水正常)符合预期。 - 本次没有测试:拜师/门派系统(这次深挖时间主要花在追查上面两 个更严重的 bug 上,留给后续深挖)。
深度功能测试(2026-08-13,round two,新驱动重测)
针对驱动升级(quest_times/win_times %-operator 修复 + Warning/warning
大小写回退兼容)做的重测。
发现并修复的 PROGRAMMING bug
1. log_error()(adm/obj/master.lpc)完全没有严重度检查
(AGENTS.md §7.34-class):if (this_player(1))
efun::write("编译时段错误:" + message + "\n")——不区分玩家/巫
师,也不区分警告/错误,任何在场玩家都会看到原始编译诊断。修复:
加上 strsrch(message, "arning:") == -1 判断,只有真正的 Error
才会显示。
2. log_file()(adm/simul_efun/file.lpc)完全没有
assure_file() 保护(AGENTS.md §7.11-class):这是通用
simul_efun 本身缺保护,不止之前 2026-08-05 那次单独在
get_gender() 调用点上加的 catch()——已加上前向声明 +
assure_file(LOG_DIR + file);,让所有 log_file() 调用点统一
受益,不必逐个调用点补 catch()。
Proactive checks(无需改动)
feature/dbase.lpc没有 tybxjh/wlhd 那种基于wizhood()的密码 写保护,不适用那一类 bug。win_times的%-operator 修复确认存在且正确:d/city2/npc/refereew.lpc:146已用to_int(query("win_times")) % 5。- 此前(2026-08-05)修复的
get_gender()里login/newid.log写入 的catch()防护、§7.86 留言板replace_program()死形状修复均 确认仍然生效。
实测过程
adm/etc/wizlist 里的 fluffos (admin) 一直没有对应存档(此前只
做过结构性核实,没有真正注册过)。本轮通过完整注册流程创建
(id → 确认 y → 中文名"笑红二" → 确认 y → 密码 → 确认密码 → 天赋
0 随机 → 接受 y → email → 性别 m),落地武庙,score 显示"目前权
限:(admin)"。随后单独一步做了真实断线重连+密码验证:用刚设
的密码重新连线成功登录,存档位置(铁枪庙,quit 前移动过)正确
持久化,score 数据一致。全程 debug.log 只有正常的编译期
Warning(Unknown #pragma、未使用局部变量等),无运行时错误。驱
动按精确 PID 结束,管理员存档(data/{login,user}/f/fluffos.o)
已提交。
§7.100 sweep (2026-08-19): redundant replace_program(ROOM); landmine
Same corpus-wide bug as documented at AGENTS.md §7.100: rooms
inheriting ROOM (/inherit/room/room) had a redundant, harmful
replace_program(ROOM); call right after inherit ROOM; in create(),
setting a permanent "pending replace" flag that crashes the object the
first time anything binds a closure to it. This lib had 1,798 live
occurrences (survey-ranked #83 of 166 candidates >=100). Fixed with
the sweep's binary-mode script (fix_710_room.py) plus one hand-fixed
room-building-tool copy (clone/misc/roommaker.lpc, the simple
str += "...replace_program(ROOM);..." string-builder variant).
git diff --numstat totals (1 insertion, 1798 deletions) match the
survey's live-occurrence count exactly. No work/data/ room-source
false-negative found. Verified via a clean build-debug boot (zero
"cannot replace"/"cannot bind" debug.log lines, port 40163 listening)
plus a live spot-check: the pre-existing seeded fluffos admin
account's actual password no longer matched the documented
placeholder, so a fresh test account (sweeptestv) was registered
through the full flow (name → confirm → Chinese display name → password
→ stat roll → gender) and landed cleanly at 铁枪庙; a second
reconnect+relogin, look, and quit all worked normally.
debug.log stayed clean throughout. Test account's save files deleted
before committing (this sweep's own throwaway account).
§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.
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()/reset_me() chain --
confirmed via a body-aware static scan of every init() in this lib: 15
NPC files call setup()/reset_me() from init() (e.g.
d/kaifeng/npc/wu43.lpc, d/kaifeng/npc/wu33.lpc,
d/kaifeng/npc/wu11.lpc), after create() 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, re-entering the same chain while the
original call is still on the stack -- genuine reentrancy, crashing
with "Too deep recursion" (most likely on an NPC's first-ever
preload/compile).
feature/damage.lpc's revive() and cmds/std/sleep.lpc's wakeup()
both 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 -- 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)
unaffected. 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.
深度功能测试(2026-09-03,第三轮)
新角度:2026-08-13 第二轮只做了注册 + 重连,没测商店和拜师。
- 登录:2026-08-13 自设的
fluffos密码不是项目标准Mud@2026(当时没写入文档)。本轮把work/data/login/f/fluffos.o的 SHA512 crypt 改成Mud@2026后重连成功(中文名「笑红二」,落地铁枪庙)。quit_time冷却 50 秒。 - 商店:先买后拜(
feature/dealer.lpc对丐帮一律「穷叫化」)。goto /d/city/zuixianlou,list列出烤鸡腿 80 文 / 牛皮酒袋一 两白银 / 包子 50 文。无现金时buy jitui正确拒绝。clone /clone/money/gold后再买成功(烤鸡腿 + 找零 99 两白银 + 20 个 铜板)。 - 拜师:
goto /d/gaibang/inhole,apprentice zuo(左全)一次 完成 →「恭喜您成为丐帮的第二十代弟子」。score职称「丐帮第 二十代弟子」、师承左全。 - 持久化:
save+ 50 秒后重连,落在/d/city2/kedian客店, 门派/师傅/银钱均在;烤鸡腿未随存档回来。 - 日志:live
debug.log是libs/xhcii/log/debug.log(Boot Time Thu Sep 3 22:19:14 2026)。无error:。没有 mudlibwork/log/debug.log。 - 结论:商店 / 有机拜师 / 重连均通过,本轮无新编程 bug 可修。