Legend of the Chivalrous Hero II/III (Happy Land)

✅ 可玩

侠客英雄传III

xkyxciii

🔑 fluffos(密码见 README) 更新 7a2d490 2026-09-01 源码 下载 ZIP

▶ 开始游玩 · Play Now

侠客英雄传 II/III「欢乐天地」(别名"武艺:无尽豪情"),是一个把金庸武侠、日本奇幻小说《罗德岛战记》和漫画元素熔于一炉的世界观:门派场景沿用华山、武当、峨嵋、昆仑、丐帮、少林等传统武侠格局,但 `d/lodoss/` 区域原样搬入了《罗德岛战记》里阿拉尼亚(Alania)、弗雷姆(Frame)等异国王国的地理设定,是这批档案里最跳脱传统武侠框架的一个;角色创建除了选性别,还要在 0-5 号种族里挑一个,而不是直接加入单一汉人门派体系,呼应这种跨文化混搭的世界观。

English

Legend of the Chivalrous Hero II/III, subtitled "Happy Land" and also styled "Wuyi: Boundless Heroism." The sect map is standard Jin Yong wuxia (Huashan, Wudang, Emei, Kunlun, the Beggars' Sect, Shaolin, and more), but one zone, d/lodoss/, drops in the geography of the Japanese fantasy novel Record of Lodoss War almost verbatim -- the kingdoms of Alania and Frame -- making this one of the more genre-blending archives in the collection. Character creation reflects the mashup: after gender, players also pick a race (0-5) rather than joining a single Han-Chinese sect hierarchy from the start.

README

内容亮点

本次修复的关键 bug

§8.1 GBK 字节区间 is_chinese() bug,出现在两个地方

1. adm/daemons/chinesed.lpcis_chinese()CHINESE_D 真正 的实现,logind.lpc 委托它做判断)只检查 str[0] 的原始字节区 间,还要求总长度是偶数,在这个驱动按 UTF8 码点索引字符串的情况 下永远判定失败。 2. adm/daemons/logind.lpc 自己的 check_legal_name() 也有一样的 i%2 奇偶门槛,长度上限是字节数写法(2-12,原意是提示文字里说 的"1 到 6 个中文字")。

已把 chinesed.lpcis_chinese() 改成逐码点 0x4e00-0x9fff 区 间检查,check_legal_name() 改成逐字符呼叫 CHINESE_D->is_chinese(name[i..i]),长度上限改成字符数 1-6。

测试注意事项

性别/种族选择紧跟在 /std/char.lpc 首次编译(带出 feature/damage.lpc/feature/skill.lpc 等一大堆编译警告)之后, 和 xhcii 记录过的情况一样,会有测试客户端的计时竞态——"m"偶尔 会被当成无法识别的指令,不管 --idle 设多长。多送一次"m"/"0"就 能稳定通过;已经用一次完全干净、注册过程零异常的成功运行确认过这 纯粹是测试工具的计时问题,不是 mudlib 本身的缺陷。

管理员账号 / Admin account

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

本地运行

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

游戏端口:40118

NOTES · 移植与修复记录

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

侠客英雄传 II/III("欢乐天地",五邑无尽豪情),一个金庸小说/欧洲中世纪/漫画风混搭的世界观设定。WASM 修复了两处经典的 §8.1 GBK 字节区间 is_chinese() bug:adm/daemons/chinesed.lpc 的 is_chinese()(CHINESE_D 委托的真正实现——只检查 str[0] 的原始字节区间,还要求总长度是偶数,在 UTF8 码点索引下永远失败)和 adm/daemons/logind.lpc 自己的 check_legal_name()(i%2 奇偶门槛,加上按字节数算的长度界限 2-12,本意是按用户提示"1 到 6 个中文字"应为 1-6 个字符)。已把 chinesed.lpc 的 is_chinese() 重写成逐码点 0x4e00-0x9fff 区间循环,check_legal_name() 改成通过 CHINESE_D->is_chinese(name[i..i]) 逐字符检查,长度界限修正为 1-6。管理员账号播种:fluffos (admin) 加入 adm/etc/wizlist(已通过源码确认 SECURITY_D 真的会在开机时读取 WIZLIST;wiz_levels 顶层是 (admin))。注册流程在多次连续的 WASM 客户端会话里完整验证过:英文 id→y/n 确认创建→中文名字→密码+确认→性别(m/f)→种族选择(0-5)→带着完整角色属性表和可用的 score/look 指令进入游戏世界,全程没有任何意外错误。测试笔记:性别/种族选择正好接在 /std/char.lpc 首次编译的大量负荷之后(加载 feature/damage.lpc、feature/skill.lpc 等),引发了和 xhcii 上记载过的同一类测试工具时序竞争——不论 --idle 设多少,'m' 有时会被当作无法识别的输入吞掉;补发一次重复的 'm'/'0' 能可靠绕过,这是客户端时序上的假象,不是 mudlib 本身的缺陷(一次完全干净的运行在注册流程里没有捕获到任何异常,可以证实这一点)。管理员权限已直接通过 'wizlist' 指令输出确认"目前权限:(admin)",fluffos 出现在最高阶层里。LPC 格式化工具对全部 3178 个档案运行(写入 3145 个,12 个报错,21 个未改动)。没有 :: 父类呼叫拆分命中,没有 CJK 重新加空格命中,没有 case 标签带尾随注释的候选,这份快照里没有 map.lpc 档案。格式化后用同样的完整注册流程重新验证过——干净,管理员权限依然是 (admin)。

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

深度功能测试(2026-08-17,round one)——严重 bug:AGENTS.md §7.11 类,新角色永久没有出生房间

第一次对这份档案做完整 §10.7 深度游玩测试,发现并修复一个严重的、 每个新角色都会撞上的 bug——不计其数(这份档案没有任何存活的角色曾 经真正进入过一个房间)。

深度功能测试(2026-08-17,round two)——补完死亡/复活、留言板,另发现并修复两个新问题

补完上一轮留下的死亡/复活循环和留言板发帖测试,过程中额外发现并 修复两个此前未覆盖到的问题。

深度功能测试(2026-08-18,round three)——发现并修复:信箱系统全域失效

本轮目标是比 round two 更深入地补完经济、拜师(宗门)、通信(邮 件)等此前未覆盖的子系统。重开全新驱动进程,用管理员账号 fluffos/Mud@2026(round two 留下的旧号密码未知/未追踪,已删 除重新注册)和一个全新普通玩家账号 qintestv/秦测试三 (纯字母 id——注意这份档案的 check_legal_id() 不允许数字,试 过带数字的 id 会被直接拒绝,这是设计限制不是 bug)分别验证。

- 修复:删掉 enter_world() 里那行多余的 destruct(mail_box);,保留前面创建/取得信箱并 move() 进 玩家身上的逻辑不变(这正是触发 init() 挂载指令、显示未读 信件数的必要步骤)。 - 现场验证:重启全新驱动进程,修复前先复现(check/ from/mail qintestz 均"什麼?",i 里没有信箱),应用修 复后重新登录,check/from 都能正常报告"你的信箱中目前没 有任何信件",i 里出现"巫侠的信箱 (mailbox)"物件;完整走了 一次 mail fluffos(给自己写信)→标题→正文→.结束→y 保留副本→check(正确显示信件列表)→read 1(正确显示标 题/寄信人/正文)→discard 1(正确丢弃,check 数量正确减 一)。全程 debug.log 零错误。(给自己写信且选择"保留副 本"会看到 2 封相同的信——这是 confirm_copy() 自留一份加 send_mail() 内部再存一份到同一个信箱的自然结果,只在"自己 寄给自己"这种边角用法下出现,不影响正常的"寄给别人"流程,未 作为 bug 处理。) - 跨库排查:对全仓库 227 个档案的 logind.lpc 做了 grep -rl "destruct(mail_box)" 全库扫描,命中且仅命中两份 档案:本档案 xkyxciii 和它的姊妹档案 xkyx3b(round two 笔记里已经记录过这两份档案同源,共享同一段 goto.lpc 自救 失效 bug)。xkyx3b 尚未验证过是否真的触发(未启动它的驱动 测试),但源码里那一行 destruct(mail_box); 与本档案修复前 完全一致,逻辑上必然有同样的问题。因为全库范围只找到这两个 实例(低于跨库批量扫描立项的门槛),本轮只修复了 xkyxciii,未touch xkyx3b,留给下次测到 xkyx3b 时参考 本条记录直接验证/修复。

§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 (/std/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,452 live occurrences (survey-ranked #89 of 166 candidates >=100, tied with sibling lib xkyx3b). Fixed with the sweep's binary-mode script (fix_710_room.py); git diff --numstat totals (0 insertions, 1452 deletions) match the survey's live-occurrence count exactly. This lib has no in-game room-building tool at all (roommaker.lpc or equivalent doesn't exist), so there was no factory-bug variant to fix. No work/data/ room-source false-negative found. Verified via a clean build-debug boot (zero "cannot replace"/"cannot bind" debug.log lines, port 40118 listening) plus a live spot-check: no player save data exists yet in data/login/ at all (a genuinely fresh, never- registered state despite the seeded fluffos/lywin wizlist entries), so a fresh test account was registered through the full flow (id → confirm → Chinese name → password → email → gender → race) and landed at the new-player training room; look/quit both worked, debug.log stayed clean throughout (only harmless first-compile-burst Warning noise, matching this lib's own documented pattern). Test account's save directory deleted before committing; an accidental rm -rf of the ADJACENT data/login/s/ directory's tracked .donotdelete placeholder file was caught via git status and restored with git restore before committing.

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