当前位置 : 145z游戏站 | 热血传奇 | 技术教程 | 

VC++6.0传奇2.0源码架构拆解:服务端网关分层客户端WindHorn编译调试全实录

热度:
传奇2.0(LegendofMir2)VC++6.0源码是一套典型的多进程分布式MMORPG服务端+Win32/DirectDraw客户端架构,核心思想是“连接层网关化、逻辑层集中化、数据层持久化”。整套源码在VC6里以.dsw工作区组织,包含LoginGate、SelGate、GameGate、LoginSrv、DBSvr、GameSvr(M2Server)、AdminCmd等服务端工程,以及WindHorn、Mir2Ex等客户端工程。下面按“整体架构→服务端模块→客户端模块→协议与数据结构→编译环境→启动联调→调试实战→常见编译错误”顺序直拆。

一、整体MMORPG架构分层
数据层:HeroDB(BDE/DBC)、SQLServer(.mdf/.ldf)、Access(.mdb),存账号、角色、物品、技能、行会
服务层:LoginSrv(账号校验)、DBSvr(角色读写持久化)、GameSvr/M2Server(地图、战斗、AI、脚本、广播)
网关层:LoginGate(7000客户端鉴权入口)、SelGate(7100角色选择转发)、GameGate(游戏会话代理与消息路由)
客户端层:WindHorn(窗口/DX渲染/音效)、Mir2Ex(登录/选角/游戏逻辑状态机),通过TCP连LoginGate→SelGate→GameGate

消息前缀约定(Def/Protocol.h):
CM_*客户端→服务端(CM_LOGIN、CM_WALK、CM_HIT、CM_SPELL、CM_SAY)
SM_*服务端→客户端(SM_WALK、SM_HIT、SM_ABILITY)
GM_*网关内部(GM_OPEN、GM_CLOSE、GM_DATA)
DB_/DBR_数据库层(DB_LOADHUMANRCD、DB_SAVEHUMANRCD)
RM_*内部广播引用(RM_WALK、RM_HIT)

二、服务端核心模块源码解析
1.LoginGate(登录网关)
入口LoginGate.cpp→WinMain→CheckAvailableIOCP(检测NT/2000IOCP)→InitInstance(WSAStartup)→MainWndProc
本地监听7000收客户端,远端连LoginSrv5000;用WSAAsyncSelect+窗口消息_IDM_CLIENTSOCK_MSG处理FD_CONNECT/FD_READ/FD_CLOSE,线程里用IOCP把LoginSrv回包转发客户端
只做中转,不验密码,不落数据。

2.SelGate(角色选择网关)
结构与LoginGate同构,端口7100,下游连DBSvr;负责建角、删角、角色列表、进服授权,转发CM_QUERYCHR/CM_NEWCHR

3.GameGate(游戏网关)
会话代理,维持客户端Socket与GameSvr内部UserInfo映射;收到客户端CM_WALK/CM_HIT直接转发GameSvr,收到GameSvr的SM_/RM_压进对应用户发送缓冲,在IOCP工作线程发回客户端;GM_DATA类网关本地处理,不分发

4.LoginSrv(账号服务)
等价AccountServer:验号、瑶、建号、防多登;配置Logsrv.ini(监听端口、DB连接串、允许GameSrvIP列表)

5.DBSvr(数据库持久化)
核心文件ProcessDBMsg.cpp、ServerCommSockMsg.cpp、GateCommSockMsg.cpp
处理DB_LOADHUMANRCD/DB_SAVEHUMANRCD/DB_ADDUSER等;_THUMANRCD(角色存档结构)、_TUSERITEMRCD(物品升级属性)、_THUMANMAGICRCD(技能数据)序列化进库
配置DBSvr.ini(SQL/Access连接串、Gate通信端口)

6.GameSvr/M2Server(逻辑主程)
核心类:CPlayerObject(移动/战斗/背包/魔法)、CUserInfo(会话与持久化中间层)、CCharObject(怪物/NPC基类)
目录Mir200\Envir:MapInfo.txt、MonGen.txt、QuestDiary、Market_Def、Npc_Def、ItemDB、MagicDB、Guild等全部热读
主循环Operate()处理CM_WALK→SM_WALK→RM_WALK附近广播;战斗结算、爆率、脚本引擎、行会、攻城、交易均在次进程

7.AdminCmd
M2控制台GM工具,发GM指令、踢人、改属性、重载脚本

三、客户端模块源码解析(WindHorn+Mir2Ex)
全局对象:
CWHDXGraphicWindowg_xMainWnd(主窗口+DX初始化)
CLoginProcessg_xLoginProc/CCharacterProcessg_xChrSelProc/CGameProcessg_xGameProc(三态机)
继承链:CWHApp→CWHWindow→CWHDXGraphicWindow;CWHDefProcess→CLoginProcess/CCharacterProcess/CGameProcess
WinMain流程:注册窗口→DirectDrawEnumerateEx枚举设备→CreateDXG()建DirectDraw对象、独占全屏、设显示模式→CSound.InitMirSound→消息循环按g_bProcState分发到对应Process的DefMainWndProc
玩家点地图移动:CGameProcess::OnLButtonDown→寻路→g_xClientSocket.SendPacket(CM_WALK)→等SM_WALK/RM_WALK回包→本地插值渲染
资源读取:.wil/.wzx(精灵)、.map(地图)、.wav(音效)、Data\补丁,客户端Mir2.ini配LoginIP/LoginPort

四、关键数据结构与协议
Def/Protocol.h:全部CM/SM/GM/DB/RM宏与包体结构
_THUMANRCD:charname[14]、level、exp、hp/mp、map、x/y、背包指针、技能数组
_TUSERITEMRCD:makeidx、dura、count、attr[](攻魔道、幸运、孔位、镶嵌)
_ENCODE/EnDecode.cpp:早期简单异或/移位加解密客户端↔网关包

五、VC++6.0编译环境准备
系统:Win2000/XP/Win732位最稳;Win10/11需关内核隔离、兼容模式管理员跑VC6
必备库:
•PlatformSDK/OldWindowsSDK(含winsock2、winmm)

•DirectXSDK(June2010或更早DX8/9SDK,含ddraw.h/ddraw.lib/dinput.lib)

•BDEAdministrator+DBC2000(HeroDB用)

VC6目录配置:Tools→Options→Directories加SDKInclude/Lib置顶

六、编译顺序与工程依赖
打开LegendOfMir2_Server.dsw
Project→Dependencies顺序:
公共库(Def/DynamicArray/List/Queue/EnDecode)→DBSvr→LoginSrv→GameSvr(M2Server)→Gate(Login/Sel/Game)→AdminCmd
客户端工作区:先编WindHorn(生成图形/输入/音效库)→Mir2Ex(主程序)
配置改点:
•LoginSrv.ini/Logsrv.ini:DB连接串、监听端口、允许GameSvrIP

•GameSvr启动参数:ServerID、地图路径Mir200\Map、Envir路径、DBSvrIP:Port

•单机多GameSvr需独立目录+不同ServerID+不同端口

七、启动联调顺序
1.起数据库(SQLServer/Access引擎/HeroDBBDE)
2.DBSvr.exe(看“DBConnected”)
3.LoginSrv.exe(账号服务就绪)
4.LoginGate.exe(7000)、SelGate.exe(7100)、GameGate.exe(游戏网关)
5.M2Server.exe/GameSvr.exe(加载MapInfo/MonGen/QuestDiary,日志“启动成功在线0”)
6.客户端改Mir2.ini→LoginIP=127.0.0.1LoginPort=7000→进游戏建角

八、调试实战(VC6原生调试器)
ProjectSettings→C/C++→DebugInfo=ProgramDatabase(/Zi);Link→Debug=Generatedebuginfo
断点落点:
•网络层:GameGateMainWndProc、OnClientSockMsg

•逻辑层:CPlayerObject::Operate、ObjectPlayer.cpp战斗结算

-数据层:DBSvrProcessDBMsg.cppDB_LOADHUMANRCD
Watch看g_xMainWnd、g_bProcState、CUserInfo指针;Memory窗口看_THUMANRCD原始字节
崩溃无提示:WinMain外包__try/__except(EXCEPTION_EXECUTE_HANDLER)写minidump;Entry-point设WinMainCRTStartup
协议联调:客户端发CM_WALK,VC6断GameSvrOperate(),看SM_WALK是否广播给同屏RM_*玩家

九、高频编译错误速查
LNK2001_DirectDrawCreate@12未解析→Link→Object/librarymodules加ddraw.lib;或源码#pragmacomment(lib"ddraw.lib")
LNK2001_WSAStartup/recv未解析→加ws2_32.lib
C2065'LPDIRECTDRAWSURFACE7'未声明→缺ddraw.h,SDKInclude路径未挂
结构体对齐告警/读包错位→Project→C/C++→CodeGeneration→Structmemberalignment=1Byte;或头文件#pragmapack(1)
C4786模板名截断→C/C++→Advanced→DisableLanguageExtensions
COleDispatchDriver/MFC类找不到→工程未开MFC支持或没链mfcs42/lib;纯SDK工程别混用MFC头
C2440long→HANDLE→显式HANDLEh=NULL初始化
/GX异常开启导致recv崩溃→关/GX,VC6SEH在旧系统不稳

十、源码研读入口推荐
服务端:Def/Protocol.h(协议全貌)→DBSvr/ProcessDBMsg.cpp(持久化)→GameSvr/ObjectPlayer.cpp(角色逻辑)→LoginGate/MainWndProc.cpp(网关IOCP)
客户端:LoginGate.cppWinMain→CWHDXGraphicWindow::CreateDXG→CGameProcess::OnLButtonDown→g_xClientSocket发包链

整套源码本质是“前端DX渲染+多网关分流+中心逻辑服+独立DB代理”的经典老派MMO实现,VC6编译关键不在代码而在SDK路径/库链接/结构体对齐/IOCP模型四件事同时对齐,调试主线跟住CM_/SM_/DB_*三段消息流即可贯通全栈。
[顶部]