1-4是大概把GAMECENTER过了一遍,终于把消息机制入了一点门,接下来是服务端第一个服务的学习--DBServer.是一个数据库服务器,在学习这个单元的时候,发现了这个端的大概由来,不知道是哪个大牛反编译后重写的,看来之前我理解的是错误的,代码杂乱的原因不是没有考虑到正题设计,这是由DEDEDARK反编译的端,根据自己的经验补写的实现代码,不知道我这辈子能不能达到这样的水平,那得需要对汇编多熟悉才行啊.
function TFrmNewChr.sub_49BD60(var sChrName: string): Boolean;//反编译的函数
//0x0049BD60
begin
Result := False;
EdName.Text := '';
Self.ShowModal;
sChrName := Trim(EdName.Text);
if sChrName <> '' then
Result := True;
end;
//这个函数是增加新角色,能看到汇编代码痕迹,单元里边还有DEDEDARK的注释说明
4 DBServer
4.1 DBSMain.pas
先说主单元,这是整个传奇服务端的数据库服务器,这个单元结构还是比较清晰的,代码1500行左右,接口部分声明的新对象也不多,主要是VCL声明和过程,但是这个服务调用的其他模块较多,主要用于数据库(人物,物品,技能等)的处理.
unit DBSMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, JSocket, Buttons, IniFiles, Menus, Grobal2, HumDB, DBShare,
ComCtrls, ActnList, AppEvnts, DB, DBTables, Common;
type
{定义服务器信息}
TServerInfo = record
nSckHandle: Integer;//socket句柄
RecvBuff: PChar; //接收数据缓冲区
BuffLeng: Integer; //缓冲区大小
Socket: TCustomWinSocket;//这里直接继承的TCustomWinSocket,现在应该不用这样了
end;
pTServerInfo = ^TServerInfo;//定义为指针
TFrmDBSrv = class(TForm)
ServerSocket: TServerSocket;
Timer1: TTimer;
{.......中间的省略,都是VLC的声明}
procedure X1Click(Sender: TObject);
procedure N3Click(Sender: TObject);
procedure F1Click(Sender: TObject);
procedure T2Click(Sender: TObject);
procedure MENU_MANAGE_TOOLClick(Sender: TObject);
private
n344: Integer;//这两个暂时还不知道
n348: Integer;
ServerList: TList; //服务器列表信息
m_boRemoteClose: Boolean; //连接标志
procedure ProcessServerPacket(ServerInfo: pTServerInfo);//数据包处理过程
{发送数据}
procedure SendSocket(Socket: TCustomWinSocket; SendBuff: PChar; BuffLen: Integer);
{这是读取角色数据的过程,带有非法连接处理}
procedure LoadHumanRcd(RecvBuff: PChar; BuffLen, QueryID: Integer; Socket: TCustomWinSocket);
{角色退出时保存角色数据}
procedure SaveHumanRcd(nRecog, QueryID: Integer; RecvBuff: PChar; BuffLen: Integer; Socket: TCustomWinSocket);
{清理}
procedure ClearSocket(Socket: TCustomWinSocket);
{获取端口列表}
procedure ShowModule();
{加载物品数据库}
function LoadItemsDB(): Integer;
{加载技能数据库}
function LoadMagicDB(): Integer;
public
{复制人物数据}
function CopyHumData(sSrcChrName, sDestChrName, sUserId: string): Boolean;
{删除人物数据}
procedure DelHum(sChrName: string);
{服务器消息处理函数,用于和其他进程通信}
procedure MyMessage(var MsgData: TWmCopyData); message WM_COPYDATA;
end;
var
FrmDBSrv: TFrmDBSrv;
大部分的处理过程是针对SOCKET的编程和数据库的读写,开始我还觉得为什么不用大型数据库,看完之后,大概了解到传奇服务端数据本来就不多,这个服务端是为多机架设而写的,一般数据库,网关服务都在单独的服务器上,所以单个服务端最大在线一般不超过2000人,所以用小型的DBC2000还是足够的,大型数据库除非是专门的数据库服务器,那样会提高并发操作的效率,可是对于这套架构来说,无异于所有代码都需要重构了,先学习基本的数据处理方式,学到经验还可以用到多层数据库开发中,这也算一个捷径吧.
4.2 DBShare.pas
对于数据库服务器的共享数据单元倒没有什么特别的,主单元的数据处理函数一部分放在了这里,其他的大部分都是变量.
unit DBShare;
interface
uses
Windows, Messages, Classes, SysUtils, StrUtils, JSocket, WinSock, IniFiles,
Grobal2, MudUtil, Common;
const
g_sUpDateTime = '修改日期: 2015/12/09