
简介EVEmu 是面向太空 MMO《EVE Online》的服务端仿真教育项目本压缩包聚焦 Crucible坩埚扩展模拟器包含服务端源码、Docker Compose 快速部署配置以及项目变更信息。适合对游戏服务器模拟、容器化部署和网络同步机制感兴趣的开发者可作为私服仿真学习与二次开发的基础。资源包采用 zip 压缩整体大小约 67.67MB内部结构以源码目录和配置文件为主便于按模块对照查阅其中 docker-compose.yml 支持直接编排运行并提供了源码构建与预构建镜像两种切换方式可降低环境准备门槛。压缩包中还以 TODO 形式列出了舰队、销售点、行星相互作用等尚未实现的系统清晰展示了当前模拟器的功能边界与后续扩展路线。目前已有 198 人浏览学习适合需要入门 EVE 服务端模拟或搭建本地实验环境的开发人员。1. 模拟器入门先搞清楚这个包锁定的版本evemu_Crucible 这个模拟器一句话讲是给 EVE Online 老版本“Crucible”资料片做服务端复现的开源分支。它不是新玩法模拟也不是一键端而是把你自己的机器变成一台能承载账号、角色、星系数据和战斗逻辑的私服服务器让对应版本的客户端绕过官方认证直接登录到本地世界。对研究服务端逻辑、想离线体验老版本内容的人很合适对只想随便玩玩、懒得折腾数据库和编译的人得先有心理准备它需要动手但路径是清晰的。我拆过不少服务端模拟器资源这个包算老少皆宜的一类难度不在编译在版本匹配和静态数据导入。下载后先别急着跑把数据库脚本和客户端构建号对齐后面才会顺。2. 为什么要锁 Crucible版本选型逻辑与目录分工2.1 版本匹配是模拟器能跑的底牌模拟器这类资源第一个要认清的点就是“版本锁”。evemu_Crucible 锁定的版本是 EVE Online 2011 年底发布的 Crucible 资料片。为什么那么多模拟器分支偏偏停在老版本上不是开发者懒而是 EVE 后期的资料片把游戏引擎、资源格式和数据库结构整体换了代社区端的代码跟不上跟上的成本也远高于收益。Crucible 这个时间点非常微妙它已经拥有足够成熟的星系跳转、装配、经济与战斗逻辑但数据规模还控制在一台普通虚拟机或者老机器能扛住的范围内。换句话说选 Crucible 做模拟器等于选了一个“功能完整但数据没膨胀”的平衡点。版本匹配这件事直接决定你能不能登录进去。EVE 客户端每个版本都有一个构建号build number服务端配置里同样维护一个期望构建号两端对不上客户端就会停在登录界面转圈日志里反复报版本不匹配。常见做法是把服务端配置里的 build 参数改成你手头客户端对应的构建号而不是去改客户端。改完以后重启 world 服务再在加载界面看日志比反复试客户端省时间得多。2.2 这个包的目录结构与角色分工拿到 evemu_Crucible 之后先不要急着编译花十分钟把目录结构过一遍你就知道这个包的水有多深。通常一个可用的分支会按这样组织目录evemu_Crucible/ ├── eve-server/ # 世界服务在线玩家里程碑、战斗、装配、跳转逻辑 │ ├── conf/ # 世界服务配置文件 │ └── log/ # 运行日志排查问题的第一现场 ├── eve-login/ # 登录服务账号密码校验返回世界服务地址 │ └── conf/ # 登录服务配置 ├── sql/ # 数据库脚本先导入再启动服务 │ ├── evemu.sql # 基础表结构账号、角色、技能、产业 │ └── static/ # 静态数据星系、物品、空间站、NPC ├── tools/ # 调试与运维工具 └── docs/ # 配置说明与常见问题eve-login 和 eve-server 是两套独立进程职责完全不同。login 只做认证验证账号密码以后把客户端导向世界服务server 才是真正的游戏世界处理你进空间站、开船、打怪、学技能这些所有逻辑。两套服务共用同一个数据库实例但独立读配置。启动顺序上必须先 login 后 server因为 world 启动时会把自身地址注册到 login客户端登录时才能拿到正确的连接目标。下面这个表是我整理配置时常用的参考列一下几个核心参数的作用。参数位置参数名作用常见坑eve-login/conflogin_port客户端认证端口防火墙没放行登录永远超时eve-server/confworld_port世界服务端口必须与 login 配置里的地址一致eve-server/confbuild期望客户端构建号不匹配就登录转圈eve-server/confmysql_user / mysql_pass数据库连接账号权限不足时服务起来又秒退eve-server/confaccess_levelGM 等级阈值太低则 GM 命令全部无效这个包最让我满意的一点是配置项没有散落到十几个文件里绝大多数核心参数集中在 eve-server/conf 和 eve-login/conf 两个目录下。后面动手的时候改的其实就是这两个地方。3. 建库与编译把模拟器从源码变成可执行程序3.1 系统准备与依赖检查这个模拟器分支的年代决定了它对环境的要求和老代码兼容性。大部分 evemu 分支的服务端逻辑以 Python 2 为主少量模块用 C 编译。所以第一件事是检查你的系统环境别在 Python 3 上浪费时间很多新人翻车就翻在这里。我一般会先执行三条命令确认底子python --version mysql --version gcc --version三条命令分别确认 Python、MySQL、C 编译器存在。Python 版本要求 2.7.xMySQL 建议 5.6 到 5.7gcc 只要有 4.x 以上基本都能编译过。如果 python 指向的是 Python 3需要额外安装 python2.7 并确认python2命令可用。老的模拟器代码对数据库编码也很敏感MySQL 这边优先选 utf8避免后面导入中文数据乱码。Python 2 环境下还需要补一个模块MySQLdb。这是老项目连接 MySQL 的标准方式Python 3 里已经换成了 PyMySQL 或 mysql-connector。装上它的方法取决于你的系统# Debian/Ubuntu 环境 apt install python-mysqldb # 或通过 pip 安装 pip install MySQL-python这里说明一下为什么用系统包而不是直接 pip。MySQL-python 在 Python 2 下编译需要 mysql_config 存在系统包管理器会自动处理好这些依赖pip 安装时经常报缺少头文件的编译错误。如果你用 CentOS 系对应包名是 MySQL-python装完以后进入 Python 命令行执行import MySQLdb能直接过就说明依赖这一关过了。3.2 MySQL 建库导入与账号初始化依赖装好以后进入数据库环节。这个包通常自带完整 SQL 脚本但导入顺序有讲究。先建库再导基础结构最后导静态数据。我按下面这个顺序操作mysql -uroot -p -e CREATE DATABASE IF NOT EXISTS evemu DEFAULT CHARACTER SET utf8; mysql -uroot -p evemu sql/evemu.sql mysql -uroot -p evemu sql/static/static_data.sql第一条命令创建数据库指定 utf8 字符集是为了避免导入时中文物品名变问号。第二条导入基础表结构包括账号表、角色表、技能表等。第三条导入静态数据这一步通常耗时最长而且最容易出错。判断静态数据是否导入完整一个比较直接的办法是查表行数SELECT COUNT(*) FROM invTypes; SELECT COUNT(*) FROM mapSolarSystems; SELECT COUNT(*) FROM staStations;这三张表分别对应物品类型、星系、空间站是 EVE 世界最基本的三块底盘。invTypes 一般有几万行mapSolarSystems 几千行staStations 也有上万行。如果你查出来行数明显偏少或者干脆是零说明静态数据导入中断了后面进了游戏会发现空间站进不去、星系跳不了问题全堆在这里。账号初始化也是在这个阶段做的。默认包里一般会带一个管理员账号没有的话你可以自己插入一条记录。重点是把账号的 access_level 设置成足够高的值否则后面 GM 命令全都不生效INSERT INTO chrUsers (account_id, username, password_hash, access_level) VALUES (1, admin, hash_value, 100);这里做一个说明password_hash 的生成方式每个分支不一样不要脑补一个明文密码直接塞进去先看包里有没有账号工具脚本。一般 tools 目录下会提供 mkpasswd 或类似工具用它生成 hash 值再插入。access_level 取值在 1 到 100 之间100 是最高权限。我习惯先设 100跑通以后再降下来。3.3 连接配置与首个世界服务启动数据库就绪后修改 eve-server/conf 和 eve-login/conf 里的连接参数。核心配置长这样[Database] host 127.0.0.1 port 3306 user evemu password evemu dbname evemu [Server] build 12345 login 127.0.0.1:26007 world 127.0.0.1:26017host 和 port 指向你的 MySQLuser 和 password 换成实际数据库账号。注意这个账号需要拥有 evemu 库的全部权限否则服务起来以后读取配置或者写入角色数据时会权限不足表现就是服务进程正常运行一旦登录就立刻报错退出。build 参数是关键中的关键。12345 只是占位示例实际值要改成你手头 EVE 客户端对应的构建号。怎么确认构建号常见做法是查客户端安装目录下的版本文件或者看启动器里的信息不同版本客户端展示位置不同。这一步建议在启动服务之前就确认好避免客户端登录转圈半天最后才发现是版本号问题。login 和 world 两个地址分别表示登录服务和世界服务的监听地址。端口可以自己改但要保证客户端网络能直达这两个端口。都配置好以后按顺序先启动 login 再启动 servercd eve-login ./eve-login cd ../eve-server ./eve-server 如果你看到控制台输出里没有异常堆栈两个进程都存活数据库连接已经建立的日志出现那恭喜服务端这一侧已经站住了。接下来就是客户端接入的问题。4. 客户端接入从本地登录到看见第一个空间站4.1 客户端如何找到私服地址服务端跑起来只是第一步客户端还指向官方服务器需要让它把登录认证发到本地。这个分支的文档里一般会给两种方案修改客户端配置或者改 hosts。我更喜欢用 hosts 方式因为它不碰客户端文件升级覆盖都不受影响。# Windows 下用管理员权限编辑 C:\Windows\System32\drivers\etc\hosts # 添加一行把客户端要访问的认证域名指向本机 127.0.0.1 eveauth.example.com注意 eveauth.example.com 只是一个占位示例实际要劫持的域名必须看包内 docs 目录的说明每个 fork 劫持的域名不一样别直接抄网上的旧教程。确认域名的方法是启动客户端时同时抓日志看它在尝试连接哪个域名然后把这个域名写进 hosts 指向 127.0.0.1。还有一种更直接的方式客户端启动时通过命令行传入登录服务器地址。不同版本客户端支持的参数不一样常见的做法是写一个批处理脚本echo off Eve.exe /server:127.0.0.1 /port:26007如果这个参数格式在你的客户端版本里不被识别客户端会忽略它并且照常尝试官方服务器。遇到这种情况回到 hosts 方案毕竟那是通行的路子。4.2 登录验证与账号创建输入账号密码登录时客户端会把凭据发给 eve-loginlogin 校验通过后返回 world 服务地址客户端再连到 world。如果你在第一步导入的账号还没创建角色登录成功后会进到角色创建界面。此时恰好能验证 GM 权限是否生效创建好角色以后在聊天框输入/gm help看看是否有命令列表返回如果有说明账号权限已经到位了。首次登录最常见的现象是账号密码填完点击登录然后界面一直转圈最后超时。这大概率不是密码问题而是 login 与 world 之间的地址互通出了问题。检查一下 eve-server 启动时日志里有没有把自己注册到 login 成功的记录没有就去核对 eve-login/conf 里配置的 world 地址端口是否和 eve-server/conf 完全一致。这类问题十有八九是配置文件里端口差了一位数字或者写成了 localhost 而服务端监听在 127.0.0.1。4.3 用日志和网络命令确认连接状态服务端模拟器是个黑匣子但日志和网络状态能把它照亮一大半。登录过程中同时开三个窗口观察tail -f eve-login/log/login.log tail -f eve-server/log/server.log netstat -an | grep -E 26007|26017netstat 的作用是确认端口在监听日志的作用是确认连接是否真的进来。login 日志里看到账号查找、密码校验通过、下发 world 地址的记录server 日志里看到 Session opened 这样的字样说明客户端已经连上世界服务。如果 netstat 显示端口监听正常但日志完全没有反应先怀疑防火墙把端口放行再看。用 systemctl 或 firewalld 命令放行端口时注意要同时对 TCP 和 UDP 做放行有些客户端的握手包会走 UDP只放行 TCP 会导致半通状态。5. 避坑排查我踩过的五个真实问题5.1 Python2 模块缺失启动秒退现象执行 ./eve-server 后进程立刻消失没有任何报错或者只输出一行 import 错误就退出。原因老代码依赖 MySQLdb新装系统默认没有这个模块。因为进程退出太快很多新手甚至看不到那行错误。解决回到 3.1 节的环境检查先执行python -c import MySQLdb报错就装依赖。装完以后不要在原来终端里直接重试先which python2确认你的启动脚本有没有写死 python 路径有写死就改成实际路径。5.2 登录后一直转圈日志无任何记录现象客户端输入账号密码后无限加载login 日志里没有新增记录。原因证书或地址劫持不对。最常见的是 hosts 写了错误的域名或者客户端启动参数根本没生效认证请求压根没发到本地。解决先用 tcpdump 或 Wireshark 抓客户端发起的连接看它实际连的目标域名是什么再把这个域名写进 hosts。实际操作中我发现有时候 EVE 客户端会同时尝试多个域名必须全部劫持掉漏一个就转圈。5.3 MySQL 静态数据导入中断空间站进不去现象登录正常角色创建正常但进入游戏后无法停靠空间站或者跳跃后在星系里卡住不动。原因sql/static 里的静态数据没有完整导入staStations 或 mapSolarSystems 表缺行。解决回到 3.2 节查三张核心表的行数。如果确实缺别重新导入整个文件效率太低用 mysql 客户端单独导入缺失的那张表即可。导入时还能加上--force参数让错误行跳过再查一次行数确认。另外要注意静态数据的 SQL 文件可能很大用 mysql 命令行导入时如果中途网络断开表数据是残缺的需要 drop 后重导。5.4 GM 命令无反应现象账号已经用管理员身份登录但输入 /gm 开头的命令没有任何反馈。原因账号的 access_level 值不够或者 GM 命令表里本身没有注册这个命令。很多 fork 的命令表默认只开了一部分命令。解决先用 SQL 查账号当前权限值SELECT access_level FROM chrUsers WHERE username admin;如果值偏低UPDATE 成 100 后重启 world 服务。注意 GM 权限是登录时拉取的改完数据库必须重启 world 才能让权限重新生效当场改数据库不重启是没反应的。命令不存在的情况去 tools 目录下找命令注册表文件看看你用的命令有没有被注释掉。5.5 服务启动时 MySQL 连接失败现象服务启动后日志里出现 “Cant connect to MySQL server” 或者 “Access denied”。原因数据库账号不对、密码错误或者账号没有 evemu 库权限。有时候是因为 MySQL 监听在 socket 上而配置里写的是 TCP 连接。解决先手动执行mysql -uevemu -p evemu -h127.0.0.1确认能连。不能连就把 MySQL 的 bind-address 改成 0.0.0.0 或确保 127.0.0.1 在监听列表里。账号权限用这条确认SHOW GRANTS FOR evemulocalhost;没有全部权限就执行GRANT ALL ON evemu.* TO evemulocalhost;然后再重启服务。6. 进阶技巧用日志索引定位数据问题安全修改装备数据模拟器玩到后面核心诉求就两个验证自己的改动有没有生效以及改坏了怎么恢复。我常用的做法是先建立日志索引再动数据。大部分分支会把角色操作记录在 server 日志里包含时间戳、账号 ID、角色 ID、动作类型。我会先写一条简单的 grep 命令把关注角色的动作过滤出来grep character_id1001 eve-server/log/server.log | tail -100这条命令能快速看到角色最近一百条操作记录定位到它最后一次成功进入空间站的时间点再配合数据库查询基本能判断数据改挂在哪一步。改数据前我先做一次单表备份这个是后悔药mysqldump -uroot -p evemu chrUsers chrUsers_bak.sql只备份一张表十几秒就够了远比改完全库才发现问题要划算。备份完以后再去动装备或者技能数据。比如给角色发一件物品我一般会先查一下物品类型表确认 ID 存在然后执行插入操作INSERT INTO invItems (characterID, typeID, quantity, locationID) VALUES (1001, 635, 1, 60003466);typeID 635 是某个实际物品的示例 IDlocationID 是空间站 ID。插入以后不要立刻上线看效果先在日志里确认物品加载是否成功。我会用这条 SQL 验证数据一致性把角色当前所在空间站和物品列表关联起来SELECT c.characterID, s.stationName, i.typeID FROM chrUsers c LEFT JOIN staStations s ON c.stationID s.stationID LEFT JOIN invItems i ON i.characterID c.characterID WHERE c.characterID 1001;如果 stationName 为 NULL说明角色当前不在任何空间站物品即使插入也取不出来typeID 为 NULL 则说明角色身上没有物品。这种关联查询比进游戏里肉眼验证快得多也是我判断数据改没改对的首选手段。改数据这事最怕的就是改完以后角色上线直接闪崩。遇到这种情况第一反应是看 server 日志最后几十行通常能看到引发崩溃的物品 ID 或者技能 ID。把那条记录删掉或者恢复备份以后再重新启动服务。从那以后我每次动数据库之前不管改动多小都强制先走一遍 mysqldump 备份流程改完再核对一条关联查询确认数据对得上才重启服务。这套流程帮我省了无数个重新导库的夜晚希望帮到你。本文还有配套的精品资源点击获取