Myth of the Three Realms: Complete Edition (Quanzhou)

✅ 可玩

三界神话完整版「泉州师院」

sjshwzb

🔑 fluffos / AdminPass123 更新 8c2ad95 2026-09-01 源码 下载 ZIP

▶ 开始游玩 · Play Now

"三界神话"系列第四个档案(另见 `sjsh` 宝鸡站原始版、`sjshv150` 紫藤分站、`sjshv2578bb` 测试二区),泉州师范专科学院站点的完整版内容,是家族里内容最扩充的一份:除共享的武当/古墓/蜀山/雪山门派场景和开封解谜任务区外,独有整套"阿修罗"(`d/axiuluo/`)、"魔界"(`d/Mojie/`)、"天空界"(`d/tiankongjie/`)等佛教/神话场景,以及少林、峨嵋、昆仑等前三份同系档案都没有的门派;其核心系统档案(`master.lpc`/`securityd.lpc`/`logind.lpc`)和前三份并非同源,是家族内部代码分叉较大的一支。注册流程也更完整,多了管理密码+普通密码的双密码机制、个人主页/ICQ 字段和天赋点分配画面。同一批档案里的 `sjshwzjqb`(增强版)与这份档案的地图、门派名单和核心系统档案几乎逐字节一致(99% 以上相同路径完全相同),是在此基础上小幅增强的姊妹版本。

English

The fourth build in the "Myth of the Three Realms" series (see also sjsh, sjshv150, and sjshv2578bb) — the complete edition run by the Quanzhou Normal College site. Unlike its three siblings, its core system files (master.lpc, securityd.lpc, logind.lpc) represent a genuine code fork rather than a mere content variant, and it's the most content-rich entry in the family: alongside the shared Wudang/Ancient-Tomb/Shu-Mountain/Snow-Mountain sect geography and Kaifeng puzzle-quest zone, it adds whole extra sects (Shaolin, Emei, Kunlun) and exclusive Buddhist/mythological zones — Asura (d/axiuluo/), the Demon Realm (d/Mojie/), the Sky Realm (d/tiankongjie/) — found nowhere else in the family. Registration adds a dual admin/regular-password mechanism, a homepage/ICQ profile field, and a talent-point allocation screen not present in sjsh. Emei's Huayanding peak is enterable as well, rounding out the family's most expansive sect roster.

README

本次修复的关键 bug

1. 损坏的 convertd.lpc 字节:和 sjsh/sjshv150 完全相同 的损坏模式——转换表里混入了非 UTF8 的杂散字节,紧贴在闭合引号 前面,最后一个字节(0x5C)把引号转义掉,导致编译失败("Illegal character 0xce/0xb2/0xee/0x96/0xa3",出现在第 258 行附近)。用 同样的字节级 Python 脚本修复了 45 处。 2. 经典 §8.1 check_legal_name()i%2 奇偶假设adm/daemons/logind.lpc 的合法中文名字检查假设每个中文字占两 个字节,用 i%2==0 隔一个字节检查一次;这个驱动是按 UTF8 码点 索引字符串的,所以奇数字数的中文名字会被误判为不合法。已改成 逐字符检查(is_chinese(name[i..i]),去掉奇偶门槛),并把长度 限制从字节数 2-12 改成字符数 1-6(对应提示文字"一到六个中文 字")。adm/simul_efun/chinese.lpc 里的 is_chinese() 本身已 经是正确的码点区间判断(0x4e00-0x9fff),不用改。 这份档案没有 emoted.lpc/message.lpc/channeld.lpc 相关的 已知 bug(都逐一检查过,均不存在或不需要修)。 3. §10.7 深度测试新发现:logind.lpc 的 §7.34 debug printf 泄漏get_name() 里裸 printf("%O\n", ob),把登录对象内部路径打 印在中文名字确认和密码提示之间)、file.lpc 的 §7.11 缺 assure_file() 防护(已补),以及obj/board/EMEI_B.C 漏网 的 §7.86 留言板崩溃(跨库扫描按 *.lpc glob 找的,这份档案唯 一一个全大写 .C 扩展名的留言板漏网了)——均已修。修 EMEI_B.C 时进一步发现峨嵋"华严顶"房间还有两层更深的运行时崩溃:set( "objects", ...) 里引用的 NPC 文件 d/emei/NPC/YINGKE.C(目录 和文件名都是大写)、以及该 NPC 自己 carry_object() 一件从未存 在于 work/ 里的 /d/shaolin/obj/cloth.c(整个 d/SHAOLIN/ 大写目录从未被转档流程处理过)。这三处只在真正进入房间(或 update 强制重编译)时才炸,编译期检查和之前两轮 WASM 验证完全 看不出来——详见 AGENTS.md 新增的 §8.15、NOTES.md 的深度测试记 录。已修:两个大写文件改名成小写 .lpcgit mv)+ 更新引用, std/char/npc.lpc 的共享 carry_object() 加了 file_size() 前 置检查防止不存在的路径把整条 NPC create() 链炸掉。d/SHAOLIN/ 目录本身(102 个档案)全量转档,超出本轮范围。

管理员账号 / Admin account

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

注册流程提示

注册顺序是:选择内码(GB/BIG5)→ 是否中小学生(回答 no)→ 输入 new → 英文 ID → 中文名字 → 管理密码 + 确认 → 普通密码(必须与 管理密码不同)+ 确认 → email(需要 [email protected] 格式)→ 个人主页 /ICQ(可留空)→ 性别 → 天赋点分配(get_gender()confirm_gift() 是硬编码 "n" 自动呼叫的,不会真的弹出"是否接受赠礼"的互动提示, §10.7 深度测试确认过)。

本地运行

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

游戏端口:40113

NOTES · 移植与修复记录

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

三界神话「泉州师院」,5 档案 sjsh 家族集群的第四个。和 sjsh/sjshv150/sjshv2578bb 同一血统,但这份快照的 master.lpc/securityd.lpc/logind.lpc 和前三份不是逐字节相同——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 相同的"闭合引号前有杂散非 UTF8 字节,最后一个字节是 0x5C 转义了引号"模式,同样在第 258 行附近的 0xce/0xb2/0xee/0x96/0xa3 非法字符签名)——用标准的字节级 Python 脚本修复。(2)adm/daemons/logind.lpc 里 §8.1 类的 check_legal_name():i%2 奇偶门槛假设每个中文字占 2 字节 GBK,加上按字节数算的长度界限(2-12);在这个驱动的 UTF8 码点索引下会误判奇数字数的中文名字——已改成逐字符呼叫 is_chinese(name[i..i]) 检查,不设奇偶门槛,长度界限改成按字符数(1-6,匹配提示文字"一到六个中文字")。adm/simul_efun/chinese.lpc 的 is_chinese() 本来就是正确的码点区间检查(0x4e00-0x9fff)——不用修。这份快照里没有发现 emoted.lpc/message.lpc/channeld.lpc 的 bug(直接检查过,都不存在/不需要)。管理员账号播种:fluffos (admin) 加入 adm/etc/wizlist(这份档案的 wiz_levels 顶层就是 (admin),和 sjsh 的等级上限一样)。注册流程在一次连续的 WASM 客户端会话里完整验证过:GB/BIG5 编码选择→非学生关卡→"new"关键字→英文 id→中文名字→管理密码+确认→普通密码(必须和管理密码不同)+确认→电子邮件(需要 [email protected] 格式)→个人主页/ICQ(可选,留空也行)→性别→拒绝赠礼→角色属性分配画面,全程没有任何意外错误。管理员权限已直接通过登录后的横幅文字"您的系统权限目前是:(admin)"确认。LPC 格式化工具对全部 11658 个档案运行(写入 11364 个,83 个因为杂乱的历史代码报错,211 个未改动);还原了 2 个档案(panshi_dan.lpc、npc/mm.lpc)确认有转档之前就存在的损坏被重新加了空格——这两个源档案在格式化之前就已经完全缺少字符串引号(作者一方的损坏,早于本轮),符合已记载的"转档前引号不配对"盲点;格式化工具在已经缺引号的内容上做的重新加空格已经还原,而不是手工修补。没有 :: 父类呼叫拆分命中。逐一比对了唯一一个 case 密集的格式化档案(d/calvin/esman.lpc)——干净,没有任何 case 标签之后的语句被吞掉。通过去空白差异比对了全部 4 个 map.lpc 档案——所有差异都只是大括号排版风格(K&R 合并),内容零变化。格式化后用同样的完整注册流程重新验证过——干净,管理员权限依然是 (admin)。

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

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

用原生驱动(build-debug/src/driver,端口 40113)通过 scripts/tmux_mud.shscripts/mudclient.py 走完整轮,对照同家族已深挖的 sjsh(宝鸡站)/sjshv150(紫藤分站)/sjshv2578bb(测试二区)NOTES.md 逐条核对候选 bug。

管理员账号(fluffos/普通密码 Mud@2026/管理密码 AdminPass123)本次通过正常注册流程首次真正落地——adm/etc/wizlist 顶层就是 (admin),注册完成后立即显示"您的系统权限目前是:(admin)";update 反复验证写权限正常。README 的既有"管理员账号"记录已同步更新为具体密码(此前写的是"注册时自设")。

补充修复(随 sjshwzjqb §10.7 深挖回填,2026-08-08)

§7.100 扫描修复(ROOM 基类多余 replace_program()

#define ROOM "/std/room":删除 662 处多余的、独立成行的 replace_program(ROOM);(保留 inherit ROOM;),654 处脚本自动 删除;另有 6 份房间建造工具副本手动修正——obj/roommaker.lpcu/leox/obj/roommaker.lpcu/ziyie/obj/roommaker.lpcu/calvin/obj/roommaker.lpc 是标准的"两套模板"简单变体(heredoc 本来干净,字符串拼接模板第 138/139 行把多余调用烤进克隆出的房 间);u/qkl/roommaker.lpcu/koker/obj/teshu/roommaker.lpcshenmo/sjsh 家族已知的"3 处出现"room_code/str 变体(一处 room_code += 拼接 + do_saveroom() 里两条分支各一处),三处均 手动删除。work/data/room/*.lpc(4 个文件)确认无此调用,无需处 理。修复后全库仅剩 26 处历史遗留的 //-注释掉实例,均确认无害、 未改动。已用 build-debug 驱动干净启动验证(0 个新增编译错误,端 口 40113 正常监听,debug.log 无新增 "cannot replace"/"cannot bind" 行;启动时出现的 /log/dlog/money 权限报错为既有、与本次 改动无关的缺目录问题,未处理,超出本次范围);未做完整 §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 深挖账号)通过原生驱动(端口 40113)+ scripts/tmux_mud.sh 逐条核实 2026-08-08 那轮记录的四个未覆盖点。

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.