UoDemo.exe《网络创世纪》是由 Origin Systems Inc. 于 1997 年开发的一款大型多人在线角色扮演游戏MMORPG是最早取得商业成功的 MMORPG 之一。该游戏客户端运行在 Windows 系统上每个服务器即“分片”运行在多台 Solaris 机器上地图按区域划分。1998 年 10 月发布的《网络创世纪第二纪元》Ultima Online: The Second Age资料片首次发行时附带独立的《网络创世纪》演示程序UoDemo.exe 和 UoDemo.dat包含客户端以及完整服务器代码和数据的 Windows 版本。UoDemo.exe 日期是 1998 年 9 月 2 日服务器数据从 1998 年 6 月 2 日的生产服务器中提取。为演示部分功能简化可玩地图缩小到奥克洛岛Ocllo位于不列颠尼亚南部海岸外的一个小型 NPC 城镇其余部分是 1998 年年中在《网络创世纪》正式服上运行的实际生产服务器代码。该演示包含在奥克洛岛上杀死一只龙的简单任务展示了游戏基本机制如对话、交易、战斗等。许多《网络创世纪》服务器模拟器复用了其中部分代码但此前没人对其进行完整逆向工程。UoDemo.exe 用 Microsoft Visual C 5.0Visual Studio 97编译目标是 C98 之前的 C 方言。断断续续进行这个项目长达 10 年直到最近大语言模型LLMs发展才完成这个看似永无止境的任务。方法- 使用 [radare2](https://rada.re/) 进行反汇编。- 从《网络创世纪》客户端 1.25.37 的实验性 Linux 版本中推断符号名称该版本附带了 C 符号。- 手动将每个函数转换为 C99 代码保持与二进制文件相同的控制流、结构体布局和分支。若有不同要么修复演示中的实际 bug要么进行平台适配并在源代码中标记出来。- 为验证在 r2 下重新反汇编 C 代码构建的程序并与原始二进制文件对比。只有两者匹配时才将该函数标记为完成。- 仅在处理重复的内联模式时使用辅助函数且只有当辅助函数展开后的代码与内联版本相同时才使用。早期正确处理类层次结构至关重要CEntity (0x10) - CResourceEntity (0x1C) - CItem (0x50) - CContainer (0x5C) - CMobile (0x37C) - CPlayer (0x458)通过虚表插槽进行虚函数调用vtable[0x18] 是 IsPlayer[0xD0] 是 IsMobile[0xE4] 是 IsNPC 等。确定这些布局后大部分二进制代码的转换变得直接。最终结果几乎是 1998 年《网络创世纪》服务器的完美复制品但仍存在一些差异。发现与原始代码相比修复了稳定性问题如崩溃、溢出、未初始化变量等和游戏玩法问题如技能提升、声望/恶名方向、怪物生成密度等。每个修复都在源代码中标记以便与 UoDemo.exe 对比的人能清楚看到改变之处及原因。有些功能出现问题如怪物生成系统和物品腐烂系统可能因这些功能在演示版本中被部分禁用或简化代码本身完整但无实际调用点。单独反编译这些功能并重新连接调用路径可让它们正常工作。此外部分数据缺失如游戏地图只覆盖奥克洛岛。编写了一套完整工具处理服务器数据格式并为世界其他地区完全重建了门、标志、装饰品、传送器、陷阱、宝箱和怪物生成点。令人惊讶的是著名的已停用的[生态系统](https://www.youtube.com/watch?vKFNxJVTJleE)在代码中仍存在尽管这些函数不再被调用。重新连接了捕食者/猎物/食腐者系统效果很酷现在能看到狼追逐兔子或乌鸦吃物品的场景。不过由于缺乏精确数据这个系统未实现完整的资源/生产系统。可参考 Raph Koster 关于《网络创世纪》[生态系统](https://www.raphkoster.com/games/snippets/did-players-destroy-the-uo-ecology/)和资源系统的博客文章[1](https://www.raphkoster.com/2006/06/03/uos-resource-system/)、[2](https://www.raphkoster.com/2006/06/04/uos-resource-system-part-2/) 和 [3](https://www.raphkoster.com/2006/06/05/uos-resource-system-part-3/)。还添加了一些简单新功能如冥想、潜行和拆除陷阱技能这些技能是 OSI 在 1999 年 2 月添加的不过代码中已有一些早期痕迹。大多数新功能可在启动时使用 -features 参数启用或禁用。由于演示服务器中完全没有账户系统通过猜测原开发者的实现方式重新实现了该系统并进行了一些现代化改进。演示服务器原本只支持 1.25.33 版本的客户端添加了对从 1.25.30 到 5.0.9.12007 年 3 月 27 日所有[客户端](https://github.com/draxinar/uoclients)的支持包括加密和未加密的版本。由于多年来有五种完全不同的加密机制不得不对客户端二进制文件中的每种加密机制进行逆向工程。原始二进制文件是 32 位的但现在默认构建目标是 64 位。类层次结构使用 C 结构体嵌套来重现原始 C 的继承关系因此 CMobile* 仍可传递给需要 CContainer* 的地方。在 64 位系统上指针扩展可能使继承的字段位置发生偏移所以一些结构体被故意填充以确保在两种模式下继承和虚表布局都与二进制文件匹配。链接- 代码- 数据基于 UoDemo.dat包含修复、完整数据和新功能- 测试中心。这不是真正的服务器分片而是测试环境。欢迎加入体验 1998 年《网络创世纪》服务器的高度还原版本。- 灵感来源Batlin 和 Derrick 的 [UO:98](https://uo98.org/) 项目它在 2016 年引领踏上逆向工程之路。强烈建议阅读代码和数据其中包含许多关于《网络创世纪》内部机制的鲜为人知的细节有助于深入了解该游戏的历史和设计。OUO 仍处于早期阶段可能存在许多问题。若遇到任何[问题](https://github.com/draxinar/ouo/issues)请及时报告。欢迎大家贡献代码。祝你玩得愉快。向《网络创世纪》社区发出的请求如果有人拥有大约 1997 - 2003 年原始《网络创世纪》服务器的 dynamic0.mul 或 dynamic0.bkp服务器存档、regions.txt怪物生成定义或 resbank.mul资源定义文件希望能发给我将不胜感激。原始的 dynamic0.mul 或 dynamic0.bkp 文件不太可能真正丢失因为它们肯定在多个安全的地方进行了备份。有所有必要的工具可在分发 dynamic0.mul 文件之前去除其中的玩家数据以保护隐私。这些文件对于高度精确地重现《网络创世纪》的世界内容将具有极其重要的价值。[返回索引](/)