Zhengzhou Storm 3

✅ 可玩

郑州风云3

zzfy

🔑 fluffos / Mud@2026 更新 85d6a35 2026-09-02 源码 下载 ZIP

▶ 开始游玩 · Play Now

游戏登录后自报家门为"天下无敌"(压缩包标题"郑州风云3"是收藏者对这个具体服务器实例的称呼),属于风云(Fengyun)引擎系列,与本项目里的 `fy2`/`fy2005`/`fengyun434`/`moniHuafu` 同属一个大家族,并且和本项目另一份同样叫"郑州风云3"的档案 `zzfy3` 是近乎重复的副本——两边工作目录各有 10345 个档案,只有 163 个内容不同;两者又都和 `wqfy`(无情风云,同样打着"天下无敌"横幅)共享同一套"郑州风云"地图与结婚系统(`d/marry/hongniang-zhang.lpc` 说媒 NPC 逐字节相同)。游戏自称"一个以古龙小说为背景的泥巴游戏",不同于本项目里常见的金庸题材武侠,走的是古龙风格潇洒不羁的江湖路线;角色创建可选择汉族/苗族/满族/蒙古族四种民族背景,死后要经历判官在鬼门关前推动的阴间轮回仪式,与 `zzfy3` 相同。

English

Introduces itself in-game as 'Invincible Under Heaven' (the collector-assigned title 'Zhengzhou Storm 3' names this particular server instance). Part of the Fengyun ('Storm') engine family, alongside this collection's fy2/fy2005/fengyun434/moniHuafu, and — a relationship neither archive previously documented — a near-duplicate of this collection's other 'Zhengzhou Storm 3' entry, zzfy3: the two work trees are 10,345 files each and only 163 differ, and both in turn share the same 'Zhengzhou Storm' map and marriage system (confirmed via a byte-identical d/marry/hongniang-zhang.lpc matchmaker NPC) with this collection's wqfy ('Heartless Storm', same 'Invincible Under Heaven' banner). The game bills itself as 'a MUD set in the world of Gu Long's novels' — rather than the Jin Yong-flavored wuxia common elsewhere in this collection, it leans into Gu Long's brisk, devil-may-care style of jianghu storytelling. Character creation lets players choose an ethnicity (Han, Miao, Manchu, or Mongol), and the same underworld death/revival ritual found in zzfy3 — a five-stage dialogue with Judge Cui Jue at the gates of the underworld, with ghosts free to wander rather than being locked in place — is present here too.

README

内容亮点

在线试玩

https://mudlibs.fluffos.info/zzfy/

管理员账号 / Admin account

警告:这是一个公开的默认密码,仅供本地/浏览器试玩。正式对外开服前
请务必修改此密码。

本地运行

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

游戏端口:40025

NOTES · 移植与修复记录

zzfy — 郑州风云3 (Zhengzhou Fengyun 3)

Archive: zzfy (full).rar. Port: 40025. Status: done (boots clean, full registration flow verified end-to-end including a real Chinese name).

What this is

Same 风云 (Fengyun) lineage as fy2/fy2005/fengyun434 (archives #14, #16, #17) — adm/obj/master.lpc/adm/obj/simul_efun.lpc layout, same adm/daemons/chinesed.lpc + adm/simul_efun/chinese.lpc shape. Mudlib root at zzfy/fy3/, config at zzfy/config.fy3. readme.txt says this build ("郑州风云3") is provided by "长孙无情", described as one of the more stable/established 风云-family sites, admin access via ID xgchen. ~10,293 raw files.

Registration flow here is architecturally simpler than the TMI-2/nitan family processed earlier: there's no separate new keyword branch in get_id() — every English id typed goes straight through check_legal_id(), and if no save file exists for it, straight to the "create new character?" confirmation. "new" is itself in the banned_id list (line 20 of logind.lpc), so typing literal new is correctly rejected as an illegal id, not a special command — don't mistake this for a bug when retesting.

Fixes applied

AGENTS.md §15h (GBK byte-range Chinese detection), applied proactively before first boot, same shape as the other fengyun-family libs:

§4 (lazy security-daemon load): not needed — master.lpc's valid_write/valid_read already gate load_object(SECURITY_D) behind find_object() in this build.

Interactive test result — full registration flow

Verified the complete registration path in one continuous connection:

1. Connect → banner → English-id prompt. 2. zzfytest → passes check_legal_id, reaches "使用 zzfytest 这个名字将会创造一个新的人物,您确定吗(y/n)?". 3. y → reaches the Chinese-name prompt. 4. Real Chinese name 萧峰 → accepted by the fixed check_legal_name (no rejection message), proceeds straight to "请设定您的密码:" — the actual proof the §15h fix works, not just that the prompt renders.

Noted, not a bug: get_name() has a pre-existing printf("%O\n", ob); debug line (prints the login object's default toString, e.g. /obj/login#0) that fires right before the password prompt on a successful name — leftover debug output from the original author, harmless, left as-is (out of scope for a UTF-8 compatibility pass).

lpcc sweep

9223 files, 8251 pass / 972 fail (89.5%). Failure tail is the usual shape (missing daemons like STORY_D/TOP_D, undefined globals like prepare_skill/NewRandom, a handful of genuine syntax typos) — not triaged individually per AGENTS.md §6b/§13, boot + full interactive registration test is the verification gate. Memory stayed healthy throughout the sweep (~17-18GB free the whole time, no pressure).

Re-verification pass: driver rebuild + formatter + WASM (2026-07)

WASM-enablement pass (2026-07): loopback gates + admin seeding

Standard pass per AGENTS.md §1.3b/§1.3e/§1.5:

- logon(): iplimit > 15 per-IP multi-login cap — loopback exempt. - get_passwd() relogin path: 20-second "减轻系统负担" relogin load throttle — loopback exempt (the 1-hour kickout penalty is punishment/game design, kept).

WASM long-sit boot-watch pass (2026-07)

200s scripts/wasm_boot_watch.sh sit: no new findings beyond the already-documented sockets-absent preload compile errors (ftpd.lpc, adm/daemons/network/dns_master.lpc — caught by master.lpc's preload catch(), cosmetic). Proactively fixed adm/simul_efun/object.lpc's file_owner() (return namereturn dir) as part of a repo-wide port of a bug found live on sibling zhonghua2 (misattributes 3-level-deep /u/<wiz>/<subdir>/<file> log_error writes to a bogus path); didn't fire in this lib's own sit, fixed proactively since it's the identical shared file. Retest: fresh registration (id zzfsanty) through look/score/quit, clean.

深度功能测试 / Deep functional test (2026-07-24)

First real *playthrough* pass on this lib (all prior passes verified only registration + look/score/quit + admin login, or watched boot output). Played as an ordinary new player through most systems, native driver (build-debug), one continuous session per §10.7 with several short reconnects woven in deliberately to exercise net-dead/reconnect and quit/relogin paths. Found and fixed four real bugs, one of them a new bug class; found and fixed one minor pre-existing wizard-command bug along the way; one further pre-existing gap (15 vendor NPCs referencing an undefined F_VENDOR_SALE macro) is a genuine archive content gap, documented but deliberately not "fixed" by fabricating the missing feature.

Test characters (kept, not cleaned up)

What was tested and confirmed working

Bugs found and fixed

1. d/death/npc/panguan.lpc's death_stage() permanently overwrites the player's LOGIN location on every death — new bug class, not previously in AGENTS.md.

``lpc ob->move(revive_loc[random(sizeof(revive_loc))]); ob->set("startroom", base_name(environment(ob))); ` where revive_loc = ({ "/d/fy/church", "/u/guanwai/tower" }). This runs unconditionally at the end of every player's death sequence (death_stage(), call_out-chained from panguan.lpc's init(), which fires whenever a dying player enters 鬼门关). query("startroom") is the SAME field adm/daemons/logind.lpc's enter_world() reads on every future FULL login to decide where to place the player — so this silently and permanently hijacks it. Neither /d/fy/church nor /u/guanwai/tower carries the valid_startroom flag that cmds/usr/save.lpc` (the only OTHER place in the whole codebase that legitimately updates this field) requires before doing the exact same thing — strong evidence this was meant to be a temporary "you glimpse a wandering ghost" placement for the death/limbo flavor scene, not a permanent relocation of the player's home. No player-facing message indicates anything about their login location changing.

2. feature/vendor.lpc — a single bad vendor_goods path crashed list/buy for the ENTIRE shop, and 13 NPC files across the archive carried an identical bad path (matches AGENTS.md §7.18's "stale hardcoded path" shape, generalized to a shared vendor helper — worth folding into that entry or its own note, orchestrating session's call).

``lpc // BEFORE (do_vendor_list, same shape in buy_object/compelete_trade): for (i = 0; i < sizeof(name); i++) list += sprintf("%-10s %-20s :%s\n", name[i]->name(), name[i]->query("id"), price_string(name[i]->query("value"))); // AFTER: for (i = 0; i < sizeof(name); i++) { if (catch(load_object(name[i]))) continue; list += sprintf("%-10s %-20s :%s\n", ...); } ` Used catch(load_object(...)), NOT file_size(...) — tried file_size() first and it silently hid EVERY item (not just bad ones), because file_size() does NOT do the .lpc/.c extension fallback that load_object()/call_other() do (AGENTS.md §4.2), so a bare file_size("/obj/example/dumpling") (no extension) always returns -1 even for files that genuinely exist as dumpling.lpc`. Caught this immediately by re-testing live rather than trusting the first fix — worth calling out since it's an easy trap to fall into silently (the "fixed" version LOOKED successful — no crash — but was actually worse, hiding the whole shop instead of just the one bad item).

3. std/room.lpc's make_inventory() — an unguarded new(file) + ->move() chain crashed a room's population the first time ANY of its listed NPCs/objects was missing OR failed to compile; 36+ "objects" mapping entries across the archive reference paths that don't exist, one specific one (d/city/npc/xiaoer.lpc) exists but fails to compile. Matches AGENTS.md §7.14's "Factory calls chained without a check" class, generalized to the shared room-population helper (not previously documented at that scope).

``lpc // BEFORE: object make_inventory(string file) { object ob; ob = new(file); ob->move(this_object()); ob->set("startroom", base_name(this_object())); return ob; } // AFTER: object make_inventory(string file) { object ob; if (catch(ob = new(file)) || !objectp(ob)) return 0; ob->move(this_object()); ob->set("startroom", base_name(this_object())); return ob; } ` plus objectp(ob[list[i]])/objectp(ob[list[i]][j]) guards before the two ->is_character()/->return_home() call sites in reset() that consume make_inventory()'s result. Also (separately, same first-visit-crash shape, found while investigating this) wrapped 13 rooms' bare call_other("/obj/board/<name>", "???") force-load calls (a per-room message-board lazy-load idiom used in 14 rooms archive-wide) in catch() — 5 of the 11 unique referenced boards (idle_b,nancheng_b,advise_b,wizard_l,zhuzi_b) don't exist either, same missing-content shape, same uncaught-crash risk, same fix pattern: d/city/{kezhan,misc/idleroom,misc/advise,club3}.lpc, d/wiz/workroom.lpc`.

4. cmds/wiz/summon.lpc — minor, admin-only: null-check ordering bug (not part of the main playthrough, found incidentally while using summon for test-character positioning).

Lineage note

zzfy shares its std/, feature/, and adm/daemons/logind.lpc architecture with fy3xd/fy3dz (same 风云3 engine, AGENTS.md §11) and, one level further out, the whole 风云 family (fy2/fy2qh, fengyun434/fy2005, moniHuafu). Bugs #2 and #3 above live in shared engine files (feature/vendor.lpc, std/room.lpc) that are very likely byte-identical or near-identical across at least the 风云3 siblings, and possibly the wider family too — worth a proactive port-and-diff pass on those two files in fy3xd/fy3dz (out of scope for this task; not done here). Bug #1 (d/death/npc/panguan.lpc) and bug #4 (cmds/wiz/summon.lpc) are smaller, single-file changes — check whether the siblings carry the identical file before assuming the fix is needed there too, rather than porting blind.

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

针对驱动升级(quest_times/win_times %-operator 修复 + Warning/warning 大小写回退兼容)做的重测。上面记录的四个修复逐项核对代码仍然生 效;log_error()(实际生效的 adm/obj/master.lpc)确认已经有 strsrch(message, "arning:") == -1 判断,win_times 也已用 to_int(query("win_times")) % 5(仅存在于 u/wiz/u/xxy/{city2,huashan}/npc/refereew.lpc 这份巫师个人工作目 录副本里,已确认修复覆盖到位)。

本轮新发现并修复的 PROGRAMMING bug

1. 管理员账号播种从未真正生效——securityd.lpcwiz_statusnosave,每次开机只硬编码授予 xgchen(AGENTS.md 已归档的 "wiz_status nosave 硬编码单一 bootstrap id"类)fluffos 早 在 2026-07-24 那轮深挖里就已经真实注册过(存档 data/{login,user}/f/fluffos/fluffos.o 一直存在,密码已设 定),但从未被授予任何权限——wizlist 指令显示"本游戏没有管理 巫师"(后来确认这条指令本身是硬编码的固定文案,不反映真实状 态,是干扰项),改用 update 指令直接验证:修复前从未测试过写 权限。已在 restore_list()set("wiz_status/xgchen", "(admin)") 后面加一行 set("wiz_status/fluffos", "(admin)"), 不改动既有的 xgchen 硬编码。Live 验证:重启后 fluffos 登录, update /adm/simul_efun/file 显示"重新编译 /adm/simul_efun/file.lpc:成功!",确认拥有 (admin) 级写权 限。 2. log_file()adm/simul_efun/file.lpc)本身缺少 assure_file() 保护:已加上前向声明 + assure_file(LOG_DIR + file);。 3. cat()(同一文件)对不存在文件的空指针式崩溃,主动加固: 未在本档案现场触发,属主动加固,改成 write(read_file(file) || "");。 4. get_resp()/get_name()adm/daemons/logind.lpc)各有一处 调试残留 printf("%O\n", ob)(AGENTS.md §7.34-class):紧跟 在中文名字确认之后,把连线桩物件的原始引用直接回显给正在注册 的新玩家。已删除两处。

Proactive checks(无需改动)

实测过程

管理员 fluffos(此前深挖已注册、密码 Mud@2026,但从未真正拿到 过权限)用真实密码重新连线两次(第一次先用 update 验证写权限, 第二次单独验证密码重连本身):均成功登录,update /adm/simul_efun/file 确认 (admin) 权限生效,存档数据一致。全程 debug.log 无运行时错误。驱动按精确 PID 结束;测试期间产生的存档 时间戳增量已 git checkout -- 还原。

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

风云III 引擎基础版(郑州风云3)。

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

§7.100 房间基类 replace_program() 扫尾修复(2026-08-19)

ROOM 宏(/std/room)在本档案 1,967 处房间文件的 create() 里 紧跟 inherit ROOM; 之后又多余调用了一次 replace_program(ROOM); ——AGENTS.md §7.100 记录的同一个休眠 bug。用 fix_710_room.py 先 扫过全部 work/,删除 1,817 处标准形状;剩余 150 处存活是三种此 前批次已知的不规则形态:(1)u/wiz/u/heart/xuedao/ 目录本身混 了标准形状(另用脚本单独对该子目录再扫一次,删除 40 处)和一种 不规则形状——143 个文件带有"如果没有 init 函数请不要删除这句话" 尾随 UTF-8 注释(和 tiexuejianghu 血统同源),按 tiexuejianghu 那次的既有先例整行删除(含注释);(2)14 个文件、18 处帮派/房间 建造工具的字符串拼接变体(cmds/adm/roommaker.lpc 一份文件里就 有 3 处不同写法、d/wiz/xgchen/roommaker.lpcobj/wall.lpcu/wiz/u/panguan/{room,rmmaker}.lpc),手工改成 str += "... setup();\n}\n";room_code += "...setup();\n}\n";。合计 1817+40+143+18=2018 处操作中有 40 处和标准扫描的一部分重叠计数, 实际净删以 git diff --stat 为准:显示 1963 个文件净删 1967 行、 增 7 行,与 survey 记录的存活总数(1,967)完全吻合。work/data/ 下没有真实 .lpc 源码命中。

驱动干净启动(零新增编译错误、端口 40025 正常监听、debug.log 无任何"cannot replace"/"cannot bind"行)。管理员 fluffos/ Mud@2026 实机登录成功,look/score/quit 均正常。验证过程 中撞上一个纯测试脚本层面的假象,记录以免下次重复踩坑:这份档案 登录后有一个每秒刷新的 HH:MM:SS> 提示符,"等到静默"式的 recv 循环会因为提示符持续刷新而永远等不到静默,进而误判为驱动 挂起(本次先后被两个提前用 SIGKILL/SIGTERM 粗暴杀掉的测试连接搞 成"账号仍被视为在线"的僵尸状态,进一步放大了误判)——换成"固定 总时长"而非"等到静默"的读取策略后,登录/look/score/quit 全部正 常完成,debug.log 全程干净,确认不是本次改动引入的回归,也不 是真实的驱动 bug。管理员存档的时间戳漂移已用 git checkout HEAD -- 还原,未提交。驱动按精确 PID 结束。

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