资讯详情 冒险岛055一树端源码架设教程:从数据库配置到GM命令全解析
📅 2026/10/9 14:11:28
简介这份冒险岛055一树端源码是早期端游服务端的完整服务器源码包面向游戏开发爱好者、端游逆向研究者和私服技术学习者目标是为部署、调试与学习经典端游服务端逻辑提供可用起点。描述中称修复程度接近98%说明核心功能与常见问题处置相对完善具备较高的参考与收藏价值。资源以zip压缩包发布整体约10.14MB平台暂未提供具体文件总数与文件类型明细下载后建议先核对目录结构与源码清单。截至目前已有363人学习浏览属于偏冷门但针对性较强的技术资源。对想了解冒险岛类端游服务端架构、登录流程、数据库脚本或模块间调用关系的开发者来说这份源码能提供一条较为完整的实机切入路径比零散补丁更适合用作基础研究素材。1. 冒险岛055一树端源码是个什么东西一句话说透冒险岛055一树端源码是很多怀旧服老玩家口中“枫叶和蜗牛”那版服务端程序的完整构建源码。这个端拿到手能干三件事一是自己架一台单机或局域网可玩的复古冒险岛服务器二是按源码里脚本逻辑改爆率、改怪物、改商城、改地图把它变成自己风格的“变态服”或“微变服”三是当一套活的教学素材——从登录认证、角色数据、地图装载到物品掉落全都能翻出来学。它是源码不是一键启动的成品服务器这就决定了它最不友好的一层你必须会装MySQL、会配Java环境、知道怎么导数据库才能真正把它跑起来。本文把这套东西从头到尾拆成可以直接抄作业的流程新手按步骤能搭出可登录的服务器熟手也能直接跳到自己关心的配置和踩坑部分。2. 服务端大体框架与源码目录先把“骨架”认全2.1 三进程分离登录服、世界服、频道服各管什么055服务端最大的技术特征就是进程分离。它不是一个大进程包揽所有功能而是拆成三个独立进程分别承担不同网络端口和逻辑职责这在当年的游戏服务端里算比较规整的结构了。比较常见的一树端版本会拆成LoginServer登录认证、WorldServer世界数据、组队、公会、角色全局管理、ChannelServer地图加载、怪物计算、掉落和玩家交互。登录服监听8484端口负责客户端连接认证认证通过后把玩家转给世界服协调出的频道服频道服在7575端口周边若干个端口上开真正的游戏逻辑。频道服可以有多个每个频道独立跑一张张地图和怪物有点像广播里的“不同频道同一套节目”的并发和服务隔离。我一般会先把端口和进程对应关系死记住因为后面排查连线不上、断线、掉线问题第一步要看的不是代码而是进程起来了没有、端口占用对不对、日志里监听是否成功。netstat -nlp | grep java看输出里是否有0.0.0.0:8484、0.0.0.0:7575这样的监听结果。如果 8484 有监听但 7575 起不来多半是频道服配置里的channel端口被别的进程占用了或者被系统防火墙策略挡住。这个阶段判断逻辑很简单客户端连不上不一定全怪登录服先分清是“披着登录服外衣的全球验证失败”还是“频道服根本不可达”。很多新手一遇见“无法连接服务器”就重开所有程序其实日志里清清楚楚写着World server is not online之类只是没人愿意逐行看。2.2 源码目录结构lib、src、scripts、sql 一眼对齐解压源码包后第一眼看到的应该是一堆文件夹。正常一树端的目录结构大致是这几类srcJava源码文件、lib依赖 jar 包、scriptsNPC 对话、事件脚本、sql数据库初始化脚本和变更脚本、conf连接参数与端口配置、dist编译好的成品 jar 或者启动脚本。有些端把 sql 脚本叫dump或者db命名没那么统一不过套路一致。我把最有用的几个文件抓出来讲见过太多人一上来乱翻源码最后半小时过去了连数据库脚本在哪都没弄清sql/dump.sql全量数据库初始化脚本包含所有表结构和初始数据sql/updates/*.sql后续版本迭代的增量变更老库升级要用conf/db.propertiesMySQL连接地址、账号、密码、库名conf/world.properties频道数、端口号、经验值倍率之类scripts/*.js/scripts/*.txtNPC对话脚本和事件脚本start.bat/start.sh启动进程的封装脚本不少一树端里还带一个npc目录里面是一堆.sql文件——每个文件对应某张地图或某类 NPC 的数据比如各个村庄的商店、传送点、怪物刷新点。导入的时候要特别小心这些是“地图/副本专属数据”漏一个某个地图就可能刷不出 NPC 或怪物。-- 示例某任务脚本往NPC表中插入一条数据 INSERT INTO npc (id, name, hide_name, func, shop_id, trainer_id, store_id) VALUES (9901000, 图鉴管理员, 0, npc_9901000, -1, 0, -1);这段 SQL 的意思是给编号9901000的 NPC 挂一个函数npc_9901000要保证 server 脚本目录里有同名函数文件存在否则游戏里点了这个 NPC 会无响应。参数里的shop_id填-1表示不关联商店trainer_id填0表示不是技能教官这种字段在商城里尤其容易配错后面会详细讲。2.3 技术选型JDK、MySQL、数据库连接池边界一树端这类老源码技术栈基本是固定的。服务端主体是 JavaJDK 版本早期多为 1.6我拆过的这个版本测下来用 1.8 编也能跑但某些校验逻辑很古老装太高版本比如 JDK 17反倒会因为反射权限或被移除的内置类直接崩溃跑出UnsupportedClassVersionError这种最无语的报错。数据库普遍是 MySQL 5.7 或 MariDB 10.x数据库驱动是mysql-connector-java-5.1.x连接池几乎用自带实现不依赖 HikariCP 这种东西。为什么不建议一上来就换新版 JDK 和最新 MySQL因为这个端的源码和 SQL 语句都是按老规范的方言写的。MySQL 8 对group by的严格模式、字符集校验、默认密码插件都改了老 SQL 经常会因sql_mode太严格直接扔出this is incompatible with sql_modeonly_full_group_by的错。mysql -u root -p -e SET GLOBAL sql_modeSTRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION;如果你已经在 MySQL 8 上踩了only_full_group_by的坑上面这个命令能临时缓解但根治办法是别用 MySQL 8或者手动把老查询里的group by字段补全。想省事的话我建议直接装 MySQL 5.7一个库一个端不折腾。2.4 数据库初始化的顺序与库表关系初始化这个端之前先要弄清楚一个基本概念这套源码的逻辑是“数据库是唯一真相”。服务端启动时大量的配置数据不是放在硬盘文件里而是从数据库表里加载到内存和缓存。所以数据库没初始化好服务端就只是起来个空壳。库表里的核心表包括表名作用关键字段accounts玩家账号id,name,password,loggedincharacters角色数据id,accountid,name,level,mapmonsterdrops怪物掉落配置mobid,itemid,chanceshopitems商店售卖物品shopid,itemid,priceshops商店基础信息shopid,npcidwzdata客户端资源索引itemid,name,desc一树端的数据库 dump 脚本已经把这些表建齐了导入时只要注意先建库、再导表、再导数据顺序别反。有些脚本里有外键如果一张表导失败后面因为它有外键约束就跟着失败一堆。3. 把服务器真正跑起来配置、导入、启动、验证一条线3.1 数据库初始化从零开始建库导入安装完 MySQL 后第一步是建库库名通常叫dbMaple或v055具体看 SQL 脚本头部的CREATE DATABASE语句。一树端这套我不建议手动去建直接执行脚本头里的建库语句比自己打 SQL 靠谱。打开 dump.sql 看一眼前三行通常长这样CREATE DATABASE IF NOT EXISTS v055 DEFAULT CHARSET utf8mb4; USE v055;若脚本用了utf8mb4那 MySQL 5.7 以上版本没问题如果脚本里写的是老式的utf8也建议改成utf8mb4否则后面往仓库里塞生僻字、表情符号之类的物品描述可能存不进去。导入的推荐命令是mysql -u root -p dump.sql导入过程如果中途输出大段ERROR别立刻重导先排查是“角色集不对”还是“外键失败”。角色集的问题通常发生在 Windows 下直接复制脚本内容到 mysql 命令行执行时转码乱掉所以更稳妥的是用source命令带本地路径执行。mysql source C:/v055/sql/dump.sql;这里要注意一个很多人在 Windows 上第一次导库就翻车的点MySQL 命令行的source和\\.是不同的方向不对会报Failed to open file。直接写绝对路径最省事别用相对路径。3.2 修改数据库连接配置账号库名端口逐一对齐数据库导好之后要去看conf/db.properties把里面的连接参数改成你本地实际的值。别看它字段少改错一个字符启动时第一个异常就是Access denied for user rootlocalhost。常见的一树端 db.properties 描述大概是这样的db.ip127.0.0.1 db.port3306 db.userroot db.password123456 db.databasev055 db.drivercom.mysql.jdbc.Driver我这边建议密码尽量别带、#、这种在 properties 文件里有特殊含义的字符如果非要带要用\转义否则substring解析会断在符号那导致最终连不上。参数说明如下db.ip填127.0.0.1就行不用填localhost因为 JDBC 连 localhost 有时候会解析成 IPv6 的::1而失败db.portMySQL 如果没改过默认 3306这个不用动db.password确认 MySQL 版本的同时要确认 root 密码认证方式MySQL 5.7 默认mysql_native_password新版本如果默认caching_sha2_password老驱动会连不上。改完配置建议先在命令行手测一次数据库连接别直接启动服务端节省排查时间。mysql -u root -p -h 127.0.0.1 -P 3306 v055 -e SELECT COUNT(*) FROM accounts;能返回数字说明连接层没问题再回过去启动服务端。3.3 启动顺序谁先开谁后开不能乱一树端在启动上有严格的顺序依赖。先开登录服再开世界服最后开频道服。顺序乱了频道服启动时会因为找不到“上级世界服”而反复重试连接日志里刷满Retry connection world server但游戏服务器本身不一定崩。启动时我最常用的命令# 先启动登录服等待日志出现 Listening on port 8484 java -cp .;lib/*;dist/* com.maplestory.server.LoginServer # 再启动世界服等日志出现 World is ready java -cp .;lib/*;dist/* com.maplestory.server.WorldServer # 最后启动频道服等日志出现 Channel 1 is up java -cp .;lib/*;dist/* com.maplestory.server.ChannelServer注意Windows 的类路径分隔符是分号;Linux/macOS 是冒号:。如果复制命令直接到了 Linux 上跑会直接报Error: Could not find or load main class这个极其常见。因为三个进程相互依赖又不互斥锁网上也有很多人做成一个总启动脚本依次启动三个进程。但我不推荐一键全开宁可分成三个脚本分别看日志输出出了问题好定位是哪一个环节挂了。3.4 客户端登录IP、端口、版本号对齐服务端起了不代表客户端能进。这套端对应的客户端是当年 055 版本的冒险岛客户端配的登录器会把 IP 和版本信息写到一个解密文件里。改动 IP 时不能用记事本直接改那个现成的客户端文件常见手法是重新生成“登入器”或者用专门的工具改 IP 后重新封包。改完 IP还要确认客户端version的字符串和服务端源码里的版本校验一致。服务端通常在ServerConstants类里定义一个标识版本名的常量055 端的版本名一般是0.55登录器同步传入二进制协议。// 服务端版本校验示例 public static final String PATCH_VERSION 0.55; public static final short CLIENT_VERSION 55;这里的PATCH_VERSION是展示给玩家看的CLIENT_VERSION是参与加密握手的短整型。登录器里如果不小心把版本传成0.56客户端到服务端就会卡在“初始化中”然后掉线。这种版本不对引起的现象很迷惑数据库连接正常、服务端无异常日志、客户端却一直卡在进线前的进度条转圈我看过很多人在那里反复重装客户端实际只是登录器版本号和CLIENT_VERSION不匹配。3.5 服务端关键参数表经验倍率、爆率、最大玩家数在服务端的全局配置里有一套直接影响游戏体验的参数。一树端的配置不像是后来那种独立config.txt它还保留着老式的 Java 常量字段。我列一份自己整理过的常用调整项配置项位置典型值作用经验倍率constants/GameConstants800打怪获得经验值倍数掉宝率constants/GameConstants2影响怪物掉宝概率的全局系数金币掉落倍率constants/GameConstants50打怪掉落金币数量倍数最大角色等级constants/GameConstants200角色可升最高等级最大连接数config/WorldConfig500单频道最大在线玩家数频道数量config/WorldConfig3服务端开的频道总数端口constants/ServerConstants7575频道服起始端口经验倍率这项一树端设计成整型常量我一般会把它看成“全局乘数”下面不同地图或活动任务里还有自己的附加倍率最终实际经验是两者相乘。见过有人只改了全局倍率却发现某个“任务活动图”经验还是低的就是因为那张图自己又设了0.5倍率的局部参数实际数值是800 * 0.5 400看起来就像没生效——这不是 bug是参数层级设计。4. 登录协议与核心玩法从连接到打怪掉装备的完整链路4.1 客户端和服务端的第一次握手登录流程拆解玩家启动客户端后第一件事是向登录服发起 TCP 连接。这个连接请求里带的是客户端版本、游戏账号和密码的摘要信息。登录服收到请求后不走 HTTP直接走自定义二进制协议协议包要解密后按字段顺序读出来。类似这样剥一层皮才能看到有效数据public MapleLoginStatus processLogin(byte[] packet) { String username readStringWithLength(packet, 12); String password readStringWithLength(packet, 76); int clientVersion readShort(packet, 88); // 先校验版本版本不对直接返回错误码 7 if (clientVersion ! ServerConstants.CLIENT_VERSION) { return MapleLoginStatus.VERSION_MISMATCH; } // 然后再到数据库里比账号密码 Account account accountDao.findByUsernameAndPassword(username, password); return account ! null ? MapleLoginStatus.OK : MapleLoginStatus.INVALID_PASSWORD; }逻辑说明这段代码先读客户端发来的用户名、密码和版本号然后立刻比较版本号不一致就直接拒绝不再查库。这样做一是为了挡旧版本客户端二是为了少一次无意义的数据库查询。参数说明里要重点看readShort(packet, 88)这个偏移量它不是随意定的——协议包的第 88 字节以后才是版本号如果你尝试自己写登录器或者改包偏移对不上后面所有字段全部错位。这个实现其实埋着一个隐患把版本校验放到了账号密码校验之前。如果服务端更新了版本号老玩家第一次连上来就会直接收到一条“版本错误”的提示这个提示在客户端里往往表现为“无法连接服务器”不会精确翻译成“版本号不对”所以排查时容易误判为网络问题。4.2 商城物品导入与鉴权数据表两兄弟开服第一件事基本都是传商城数据。很多一树端里的商城是“代码写死数据库配置”双层结构——代码定义页面分类数据库定义具体上架物品。最常见的坑是商城里面空空如也一根毛都不显示。那多半是shopitems表里没有为对应商城 NPC 的shopid插入数据。物品上架逻辑简化后大概是INSERT INTO shopitems (shopid, itemid, price, position, refresh) VALUES (9201001, 1002140, 2000, 1, 0);其中shopid要对应shops表里某个npcid绑定的商店itemid是物品数据库里的物品唯一编号price是售卖价格position是商品列位置refresh表示上架方式0是固定存在、1是定时刷新。如果refresh为 1 却没有对应的刷新时间表配置玩家会看到商品时有时无。商城鉴权上端里分两类物品点券购买品和金币购买品。点券充值是另一个独立系统通常通过后台命令或数据库账户余额nx字段来实现。这个nx字段不在accounts表里而在characters或专门的cash表里不同端缝合的路径不一样别改错地方。你只想给某个账号加点券先翻一翻表结构别直接满库 UPDATE。4.3 GM命令实测常用命令与参数格式一树端源码里GM命令是通过聊天框输入特定符号开头的文本实现的。命令分为两大等级普通管理员等级3和超级管理员等级6。不同命令还有自己二级权限配置我曾经见过一个服的普通 GM 能用封号命令但改不了等级就是因为命令注册表把权限等级设得比命令本身等级更低。我这边拆的时候整理过一批高频命令命令格式作用最小权限!levelup!levelup 角色名 等级把指定角色升级到目标等级3!item!item 物品ID 数量给自己发指定物品3!meso!meso 数字给自己加金币3!job!job 职业代码切换角色职业4!warp!warp 地图ID把自己传送到指定地图3!ban!ban 角色名封禁目标角色5!exprate!exprate 倍数动态修改经验倍率6!droprate!droprate 倍数动态修改掉宝倍率6特别提醒这些命令不是直接在服务端命令行敲的是让玩家角色登录后在游戏聊天框里输入然后回车发送。发送时命令前的感叹号其实是一个标识代码里用playerCommand来拦截聊天消息并解析以感叹号开头的文本。public boolean handlePlayerCommand(String message, MapleCharacter player) { if (!message.startsWith(!)) { return false; } String[] parts message.substring(1).split( ); String cmd parts[0].toLowerCase(); // 根据命令名分发到对应处理逻辑 if (cmd.equals(item) player.getGmLevel() 3) { int itemId Integer.parseInt(parts[1]); int quantity parts.length 3 ? 1 : Integer.parseInt(parts[2]); player.gainItem(itemId, quantity); return true; } return false; }这段代码的逻辑是从聊天文本里去掉开头感叹号再按空格切出命令段和参数段。参数说明parts[1]是物品 IDparts[2]是数量缺省时默认给 1 个。切数组前没有做整体长度保护玩家只输入!item不跟物品ID 时程序会抛ArrayIndexOutOfBoundsException反应到游戏里就是客户端闪断。这属于源码本身不健壮的地方如果拿它二次开发建议先给所有命令补上参数校验。4.4 怪物掉落配置monsterdrops 与爆率算法掉宝是这类游戏最敏感的数值之一。一树端的掉落配置基本全在monsterdrops表里由怪物 ID 物品 ID 概率chance三元组构成。chance 字段的单位不是百分比而是“分之一”比如chance 10000表示一万分之一掉率。很多新手把chance填成 100 以为必掉了结果刷很久不掉就是单位搞错了。我给一个正确示例-- 让某怪物必掉某个指定装备掉率设为1表示1/1100% UPDATE monsterdrops SET chance 1 WHERE mobid 9300001 AND itemid 1402005;这段 SQL 的意思是把怪物9300001我虚构的某巨人怪掉落物品1402005某双手剑的权重改成 1。掉落系统计算时用随机数跟这个chance做比较随机数为 0 则满足条件也就是必掉。如果你想让这个怪物改掉另一件物品而不是这把剑需要先DELETE旧的掉落记录再INSERT新的否则同mobid下会有多条记录同时参加计算。冒泡点在于怪物本身还可能绑定“全局爆率倍率”。也就是最终概率 表里 chance / 全局掉宝倍率。全局倍率默认是 2 的话表里填 10000实际概率是 5000 分之一。很多攻略不会讲这层关系导致个人调出来的概率和实际体感不一致。5. 避坑与常见故障排查启动和运营中最糙的几块石头5.1 数据库连不上版本、密码、端口和驱动四层原因现象启动服务端时日志抛出Communications link failure或Access denied for user rootlocalhost。原因第一类MySQL 8 的默认认证插件是caching_sha2_password而老驱动 5.1.x 不认识这个插件第二类MySQL 没启动第三类db.properties 里密码写错第四类端口被占用或没写活。解决如果是 MySQL 8把 root 用户认证改回老模式SQL 如下ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密码;如果不想改全局用户也可以在连接 URL 后面加参数?allowPublicKeyRetrievaltrueuseSSLfalse但老驱动对这两个参数支持不完整治标不治本。换 MySQL 5.7 可以一步到位这是这个源码场景下最省心的解法没有之一。5.2 服务端起来却进不去端口没通与防火墙拦截现象服务端日志显示监听成功客户端点击频道服务器却提示“无法连接服务器”或卡在正在连接频道服务的进度条。原因本地服务端开放端口与客户端实际访问端口不一致或防火墙拦截了 Java 进程的入站连接。常见于安装了安全软件的 Windows默认策略里对“未知程序”联网会弹窗但没被注意到。解决先看WorldConfig中频道端口配置再确认客户端登录器内锁定的频道服 IP 和端口。我把端口这一段做成一个自查命令开了几次服务端之后基本能秒定位netstat -an | findstr 7575如果netstat没输出进程没监听如果监听地址是127.0.0.1而客户端连的是局域网/公网 IP只能本机访问那也要在配置里把绑定地址改0.0.0.0。改完重启频道服再用telnet 你的IP 7575验证一次是否能通。5.3 商城空了或乱码字符集、缓存和 shopid 对不上现象商城 NPC 打开后是空白或商品名称全是倒问号。原因字符集不对导致物品名称读取成乱码客户端直接不渲染或者服务端内商城缓存没能在启动时加载完全数据库读到了空列表。解决确认db.properties里的连接 URL 附加了characterEncodingUTF-8如果还乱把 MySQL 服务端my.cnf里的character-set-server统一成utf8mb4。清缓存方面一树端某些商城数据是加载进内存缓存的修改数据库表后必须重启频道服让它重新加载只跑登录服和世界服不会刷新商城缓存。我曾经在一次改动后只重启了登录服没重启频道服商城空了一下午不是数据问题是没重启到位。5.4 GM命令无效或闪断权限等级与参数缺失现象!item 1002140发出去没反应或者直接把号闪没了。原因账号的 GM 等级不够命令处理器在检查权限阶段就返回了另一种是命令解析时数组越界导致通信线程异常断开。解决确认账号的角色等级。055 一树端在accounts表中新增了gm字段默认值为 0要手动改成 3 以上才具备使用 GM 命令的资格。改完数据库要重启登录服重启后重新登录账号才生效。闪断的问题属于源码健壮性不足建议自己对命令参数做代码保护防止只输入半截命令就触发异常。5.5 地图进不去与 NPC 诡异的沉默数据缺失与同步现象使用!warp 地图ID传送时提示无法进入或者进入了某个地图发现 NPC 站在那但点了没反应。原因地图数据在map.dump类文件里没导入或者 NPC 绑定的事件脚本没有同步复制到脚本目录。一树端在文件版本上有个特例部分地图的刷怪点和 NPC 数据不是放在数据库表里而是独立成.sql文件很多人在导入大备份时漏掉了这些零碎文件。解决把源码包里scripts或sql/npc目录下的零散 SQL 全部导入一次——尤其是对应你地图编号的那几个文件。脚本方面npc序号要和游戏实际调用的脚本文件名一致。比如 NPC 的func是npc_9901000那scripts/npc目录里要有npc_9901000.js或对应 Java 类缺少时客户端只显示人物但不触发对话这个点排查特别耗时因为不报错、不留日志非常像没写 NPC 脚本。5.6 启动内存溢出与类冲突把启动参数和依赖写稳现象启动频道服到一半出现java.lang.OutOfMemoryError: Java heap space或者一堆ClassNotFoundException。原因老服务端默认 JVM 堆很小不加参数跑 512MB 都可能满类冲突主要是lib下同时放了多个版本的 mysql 驱动或公共库。解决启动时显式加内存参数。java -Xms512m -Xmx1024m -cp .;lib/*;dist/* com.maplestory.server.ChannelServer-Xms是初始堆大小-Xmx是最大堆大小。一树端这种老结构跑一个频道给 1GB 足够了给太大反而会因 GC 停顿引发频道卡顿。如果 1GB 还是 OOM优先怀疑某个地图的刷怪事件脚本写成了死循环而不是单纯增加内存。6. 自己改个“能玩得舒服”的端从改经验到挂机点最后一把收口这个端最大的乐趣在改。我后面多开服时做过一套自己的改动这里挑三个最关键的经验点都是在原版基础上微调不影响整体平衡。第一经验倍率的局部控制。全局倍率改 800 以后前期升级很快但 120 级往后明显变慢所以我会额外调整“高级地图”里怪物掉落经验的基础值而不是一味地拉高全局倍率。具体做法是修改monsters表里对应mobid的exp字段让它在新手图保持低经验、在后期练级图给高经验。这样玩家不会因为全局 800 倍而在新手村十几分钟满级丧失怀旧节奏。第二调出“有掉落感”的装备爆率。直接把monsterdrops表里的毕业武器爆率设置成2000即1/2000再除以全局掉宝倍率后约等于千分之一每个 BOSS 单独一条记录。这个数值我试下来既不会刷半小时不出货让人弃游也不会人手一把变成“屠龙宝刀点击就送”。这里有一个血泪教训全局掉宝倍率如果调成 10那张表里写 2000 实际爆率变成了 1/200相当于人人可刷完全不值钱。第三给挂机党做“安全练级区”。在脚本里做一个定时经验奖励的 NPC时间段内在线玩家每 30 秒拿到一点经验值。这个功能用一树端自带的 NPC 定时任务就能实现不用改服务端主线程直接在 NPC 脚本里维护一个schedule任务。public class AFK_EXP_NPC extends AbstractNpcScript { Override public void onSpawn(MapleNPC npc) { npc.scheduleRepeating(30 * 1000, () - { for (MapleCharacter player : npc.getMap().getCharacters()) { player.gainExp(1000, false); } }); } }逻辑说明这个脚本让 NPC 每 30 秒遍历一次当前地图所有在线的玩家给每人结算 1000 经验值。gainExp的第二个参数传false表示不触发升级时的全服公告。如果你想让挂机经验也能享受公会加成之类的需要改成走正式经验结算接口而不是直接调用gainExp。第四备份与回滚的习惯。改表之前先备份。这个端和现代游戏端不一样没有自动迁移工具一张嘴就改错是常态。我最后一次改掉落时忘记备份刷了一个多小时才发现某BOSS掉落表全没了只能靠前一天的手动导出的文件恢复。从那以后每次改数据库表结构或爆率前我都会先执行一次mysqldump -u root -p v055 backup_$(date %Y%m%d_%H%M%S).sql给源库留一份后悔药改崩了恢复也就是一分钟的事。这套流程走了这么多遍最想对你说的其实就一句拿到源码别急着开服先把数据库、配置、命令这三层跑透再去想改玩法的事。希望帮到你。本文还有配套的精品资源点击获取