www.pudn.com > M2Server.rar > MainForm.pas
////////////////////////////////////////////////////////////////////////////////
// //
// 工程: M2Server //
// 版本: 1.0 //
// 公司: 乐都在线 //
// 网址: http://www.hh8.net //
// 日期: 2005-05-28 //
// //
////////////////////////////////////////////////////////////////////////////////
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, IdThreadMgr, IdThreadMgrDefault, IdTCPServer,
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, INIFiles,
StdCtrls, Buttons, ClassDeclaration, PredefinedData, DataHandler, StrUtils,
ExtCtrls, IdWinSock2, UserInfo, D7ScktComp, ObjectMonster, ObjectNPC;
type
ProcessTCPClientLog = class(TThread)
private
// CB: TCommBlock;
procedure HandleInput;
protected
m_bInHandle: Boolean;
procedure Execute; override;
end;
TFormMain = class(TForm)
TimerConnectServer: TTimer;
ServerSocket1: TServerSocket;
DecodeTimer: TTimer;
ClientSocketDB: TClientSocket;
Timer1: TTimer;
ClientSocketID: TClientSocket;
TimerHum: TTimer;
TimerMon: TTimer;
TimerNpc: TTimer;
Label1: TLabel;
Label2: TLabel;
StatusBar1: TStatusBar;
memLogInfo: TMemo;
procedure FormCreate(Sender: TObject);
procedure BitBtnStopServiceClick(Sender: TObject);
procedure TimerConnectServerTimer(Sender: TObject);
procedure IdTCPServerSocketConnect(AThread: TIdPeerThread);
procedure ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure DecodeTimerTimer(Sender: TObject);
procedure ClientSocketDBRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketDBError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure Timer1Timer(Sender: TObject);
procedure ClientSocketIDRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure TimerHumTimer(Sender: TObject);
procedure TimerMonTimer(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure TimerNpcTimer(Sender: TObject);
procedure ClientSocketDBConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketDBDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
public
// Public Variable decalrations
ThreadTCPClientLog: ProcessTCPClientLog;
// Public Method and Function decalrations
procedure StartServer;
procedure InsertLogMsg(strMessage: string);
function ReadConfig(var iniconfiguration: TIniConfiguration_RCD): Boolean;
function SaveConfig(): Boolean;
function InitializingServer(pMapInfo: MAPINFO_RCD_ARRAY): Integer;
function InitDataInDatabase: MAPINFO_RCD_ARRAY;
procedure ProcessUserPacket(UserData: pTSendUserData);
end;
// Global Function Declarations
procedure InitGlobalVariable;
procedure FreeGlobalVariable;
procedure ProcReceiveBufferDB;
var
FormMain: TFormMain;
g_IniConfiguration: TIniConfiguration_RCD;
HumCOunt: Integer;
mon: TMonsterObject;
nCurrMonGen: Integer;
RunMonGen: Integer;
Busy: Boolean;
MDlgPoints: TList;
SelectMenuStr: string;
MdgStr: string;
RequireAddPoints: Boolean;
Myself: TUserInfo;
MonCount: Integer;
implementation
uses FunctionDeclaration, ObjectPlayer, GlobalDefinition,
ProcessThreads, EDcode, show, MyDebug;
{$R *.dfm}
procedure ProcessTCPClientLog.HandleInput;
begin
// do nothing
end;
procedure ProcessTCPClientLog.Execute;
begin
// while
end;
{解析数据包}
procedure ProcReceiveBufferDB;
var
I,
nPos,
nFirst,
nEnd,
nCount,
nBuffLen,
index,
nCertification: Integer;
w1,
w2: Word;
lValid: Integer;
pszData,
pszDevide,
pszFirst,
pszEnd: string;
GenItemRcd: TGENITEM_RCD;
lptGenItemRcd: PUSERITEM;
DefMsg,
SendDefMsg: TDEFAULTMESSAGE_RCD;
pReadyUserInfo: TReadyUserInfo;
pReadyUserInfo2: TReadyUserInfo2;
pPlayerObject: TPlayerObject;
pUserInfo: TUserInfo;
tClientItem: PTCLIENTITEM;
lpHumanMagicRcd: PTClientMagic;
szVal: string;
szCC: array[1..32] of Char;
szBuff: array[1..8192] of Char;
szEncodeMsg: array[1..256] of Char;
m_THumanRcd: THUMAN_RCD;
begin
g_szRemainBuff := g_szRemainBuff + g_szTempBuffer;
g_szTempBuffer := '';
nBuffLen := Length(g_szRemainBuff);
g_szRemainBuff := ArrestStringEx(g_szRemainBuff, '#', '!', pszData);
while pszData <> '' do
begin
pszData := GetValidStr3(pszData, pszDevide, ['/']);
if pszDevide <> '' then
begin
nCertification := StrToInt(pszDevide);
w1 := nCertification xor $AA;
w2 := Length(pszData);
lValid := MAKELONG(w1, w2);
nPos := Encode6BitBuf(@lValid, @szCC[1], SizeOf(Integer), SizeOf(szCC));
Inc(nPos);
szCC[nPos] := #0;
if Copy(pszData, Length(pszData) - nPos + 2, nPos - 1) = LeftBStr(szCC,
nPos - 1) then
begin
pszData := GetValidStr3(pszData, pszDevide, ['/']);
DefMsg := DecodeMessage(string(pszDevide));
case DefMsg.wIdent of //
DBR_LOADHUMANRCD2:
begin
end;
DBR_LOADHUMANRCD: //获取角色信息
begin
Decode6BitBuf(pszData, @m_THumanRcd, SizeOf(THUMAN_RCD));
if g_xReadyUserInfoList <> nil then
begin
try
with g_xReadyUserInfoList.LockList do
begin
for nCount := 0 to COunt - 1 do
begin
pReadyUserInfo := TReadyUserInfo(items[nCount]);
if (pReadyUserInfo.m_pUserInfo.m_szCharName = //找到相应的用户
m_THumanRcd.szCharName) or
(pReadyUserInfo.m_pUserInfo.m_szUserID = m_THumanRcd.Id)
then
begin
pReadyUserInfo.m_pUserInfo.m_THumanRcd := m_THumanRcd;
if Trim(pReadyUserInfo.m_pUserInfo.m_THumanRcd.szMapName) = ''
then
pReadyUserInfo.m_pUserInfo.m_THumanRcd.szMapName :=
'0';
pReadyUserInfo.m_pUserInfo.m_TakeItemsCount := 0;
for I := 0 to 8 do //获取当前身上装备
begin
if
pReadyUserInfo.m_pUserInfo.m_THumanRcd.szTakeItem[I].Id
> 0 then
begin
index :=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.szTakeItem[I].GoodId - 1;
if (index < 0) or (index > High(g_pStdItemSpecial))
then
Continue;
g_pStdItemSpecial[index].GetStandardItem(@pReadyUserInfo.m_pUserInfo.m_TakeItems[I]);
pReadyUserInfo.m_pUserInfo.m_TakeItems[I].Dura :=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.szTakeItem[I].Stand;
pReadyUserInfo.m_pUserInfo.m_TakeItems[I].DuraMax :=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.szTakeItem[I].MaxStand;
pReadyUserInfo.m_pUserInfo.m_TakeItems[I].MakeIndex
:=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.szTakeItem[I].Id;
Inc(pReadyUserInfo.m_pUserInfo.m_TakeItemsCount);
end
else
pReadyUserInfo.m_pUserInfo.m_TakeItems[I].MakeIndex
:= 0;
end;
pReadyUserInfo.m_pUserInfo.m_BagItems.Clear; //获取物品栏中的物品
for I := 9 to 50 do
begin
if
pReadyUserInfo.m_pUserInfo.m_THumanRcd.szTakeItem[I].Id
> 0 then
begin
index :=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.szTakeItem[I].GoodId - 1;
if (index < 0) or (index > High(g_pStdItemSpecial))
then
Continue;
New(tClientItem);
g_pStdItemSpecial[index].GetStandardItem(tClientItem);
tClientItem^.Dura :=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.szTakeItem[I].Stand;
tClientItem^.DuraMax :=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.szTakeItem[I].MaxStand;
tClientItem^.MakeIndex :=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.szTakeItem[I].Id;
pReadyUserInfo.m_pUserInfo.m_BagItems.Add(tClientItem);
end;
end;
for I := 0 to 3 do //获取四格
begin
if
pReadyUserInfo.m_pUserInfo.m_THumanRcd.KeepGoods[46 + I].Id
> 0 then
begin
index :=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.KeepGoods[46 + i].GoodId - 1;
if (index < 0) or (index > High(g_pStdItemSpecial))
then
Continue;
g_pStdItemSpecial[index].GetStandardItem(@pReadyUserInfo.m_pUserInfo.m_TakeItems[9 + I]);
pReadyUserInfo.m_pUserInfo.m_TakeItems[9 + I].Dura :=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.KeepGoods[46 + I].Stand;
pReadyUserInfo.m_pUserInfo.m_TakeItems[9 + I].DuraMax :=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.KeepGoods[46 + I].MaxStand;
pReadyUserInfo.m_pUserInfo.m_TakeItems[9 + I].MakeIndex
:=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.KeepGoods[46 + I].Id;
Inc(pReadyUserInfo.m_pUserInfo.m_TakeItemsCount);
//
end;
end;
for I := 0 to 19 do //获取魔法
begin
if pReadyUserInfo.m_pUserInfo.m_THumanRcd.Magic12[I].Id
> 0 then
begin
New(lpHumanMagicRcd);
lpHumanMagicRcd^.Level :=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.Magic12[I].code;
lpHumanMagicRcd^.key :=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.Magic12[I].key;
lpHumanMagicRcd^.CurTrain :=
pReadyUserInfo.m_pUserInfo.m_THumanRcd.Magic12[I].no;
lpHumanMagicRcd^.Def :=
g_pMagicInfo[pReadyUserInfo.m_pUserInfo.m_THumanRcd.Magic12[I].Id - 1].Def;
pReadyUserInfo.m_pUserInfo.m_lpTMagicRcd.Add(lpHumanMagicRcd);
end;
end;
if pReadyUserInfo.m_pUserInfo.m_pxPlayerObject <> nil
then
begin
TPlayerObject(pReadyUserInfo.m_pUserInfo.m_pxPlayerObject).AddProcess(TPlayerObject(pReadyUserInfo.m_pUserInfo.m_pxPlayerObject),
RM_SendNotice, 0, 0, 0, 0, '');
TPlayerObject(pReadyUserInfo.m_pUserInfo.m_pxPlayerObject).MakeFeature;
TPlayerObject(pReadyUserInfo.m_pUserInfo.m_pxPlayerObject).Initialize;
TPlayerObject(pReadyUserInfo.m_pUserInfo.m_pxPlayerObject).m_fIsAlive := True;
pReadyUserInfo.m_pUserInfo.m_btCurrentMode :=
USERMODE_PLAYGAME;
Inc(HumCOunt);
end;
Delete(nCount);
Break;
end;
end;
end;
finally
g_xReadyUserInfoList.UnlockList;
end;
end;
end;
DBR_MAKEITEMRCD:
begin
end;
DBR_MAKEITEMRCD2:
begin
end;
end; // case
end;
end;
g_szRemainBuff := ArrestStringEx(g_szRemainBuff, '#', '!', pszData);
end;
{if (pszFirst <> nil) and (nBuffLen > 0) then
begin
CopyMemory(@g_szRemainBuff[1], pszFirst, nBuffLen);
g_nRemainBuffLen := nBuffLen;
end
else
begin
g_nRemainBuffLen := 0;
end; }
end;
{var
I,
nPos,
nFirst,
nEnd,
nBuffLen,
nCertification: Integer;
w1,
w2: Word;
lValid: Integer;
pszData,
pszDevide,
pszFirst,
pszEnd: PChar;
GenItemRcd: TGENITEM_RCD ;
lptGenItemRcd: PGENERALITEM_RCD;
DefMsg,
SendDefMsg: TDEFAULTMESSAGE_RCD;
pReadyUserInfo: TReadyUserInfo;
pReadyUserInfo2: TReadyUserInfo2;
pPlayerObject: TPlayerObject;
pUserInfo: TUserInfo;
tClientItemRcd: TCLIENTITEM_RCD;
lpTItemRcd: PUSERITEM_RCD;
lpHumanMagicRcd: PHUMANMAGIC_RCD;
szVal: String;
szCC: array [1..32] of Char;
szBuff: array [1..8192] of Char;
szEncodeMsg: array [1..256] of Char;
begin
pszData := nil;
pszDevide := nil;
pszFirst := nil;
pszEnd := nil;
g_szRemainBuff := g_szRemainBuff + g_szTempBuffer;
g_szTempBuffer := '';
nBuffLen := Length(g_szRemainBuff);
if nBuffLen > 0 then
begin
CopyMemory(@szBuff[1], @g_szRemainBuff[1], nBuffLen);
end;
pszEnd := @szBuff[1];
while nBuffLen > 0 do
begin
pszFirst := MemChrDelphi(pszEnd, '#', nBuffLen);
pszEnd := MemChrDelphi(pszFirst, '!', nBuffLen);
if (pszFirst <> nil) and (pszEnd <> nil) then
begin
pszEnd[0] := #0;
Inc(pszEnd);
pszDevide := MemChrDelphi(pszFirst, '/', pszEnd - pszFirst);
if pszDevide <> nil then
begin
pszDevide[0] := #0;
Inc(pszDevide);
nCertification := StrToInt(pszFirst + 1);
w1 := nCertification xor $AA;
w2 := StrLen(pszDevide);
lValid := MAKELONG(w1, w2);
nPos := Encode6BitBuf(@lValid, @szCC[1], SizeOf(Integer), SizeOf(szCC));
szCC[nPos] := #0;
end;
end;
end;
if (pszFirst <> nil) and (nBuffLen > 0) then
begin
CopyMemory(@g_szRemainBuff[1], pszFirst, nBuffLen);
g_nRemainBuffLen := nBuffLen;
end
else
begin
g_nRemainBuffLen := 0;
end;
end;
}
{读取配置文件}
function TFormMain.ReadConfig(var iniconfiguration: TIniConfiguration_RCD):
Boolean;
var
inifile: TIniFile;
begin
inifile := TIniFile.Create('.\GameSvr.ini');
iniconfiguration.ServerTitle := inifile.ReadString('Server', 'ServerTitle',
'乐都传奇');
iniconfiguration.Installed := inifile.ReadBool('Server', 'Installed', True);
iniconfiguration.ServerPort := inifile.ReadInteger('Server', 'ServerPort',
5000);
iniconfiguration.ServerNumber := inifile.ReadInteger('Server', 'ServerNumber',
0);
iniconfiguration.GameServerIndex := inifile.ReadInteger('Server',
'GameServerIndex', 0);
iniconfiguration.GameServerNumber := inifile.ReadInteger('Server',
'GameServerNumber', 0);
iniconfiguration.GameServerName := inifile.ReadString('Server',
'GameServerName', 'ServerName');
iniconfiguration.StartLevel := inifile.ReadInteger('Server', 'StartLevel', 1);
iniconfiguration.StartGold := inifile.ReadInteger('Server', 'StartGold', 1);
iniconfiguration.Map := inifile.ReadString('Server', 'Map', 'GameMap');
iniconfiguration.MapFileLoc := inifile.ReadString('Server', 'MapFileLoc',
'D:\mirserver\Map');
iniconfiguration.DBServerIP := inifile.ReadString('Server', 'DatabaseServerIP',
'127.0.0.1');
iniconfiguration.DBServerPort := inifile.ReadInteger('Server',
'DatabaseServerPort', 6000);
iniconfiguration.IDServerIP := inifile.ReadString('Server', 'IDServerIP',
'127.0.0.1');
iniconfiguration.IDServerPort := inifile.ReadInteger('Server', 'IDServerPort',
5600);
iniconfiguration.SQLServerIP := inifile.ReadString('Server', 'SQLServerIP',
'127.0.0.1');
iniconfiguration.SQLServerPort := inifile.ReadInteger('Server',
'SQLServerPort', 5100);
iniconfiguration.SQLServerDatabase := inifile.ReadString('Server',
'SQLServerDatebase', 'sqldatabase');
iniconfiguration.SQLServerID := inifile.ReadString('Server', 'SQLServerID',
'User');
iniconfiguration.SQLServerPassword := inifile.ReadString('Server',
'SQLServerPassword', 'password');
inifile.Free;
inifile := TIniFile.Create('.\!SetUp.txt');
Randomize;
MyMakeIndex := inifile.ReadInteger('setup', 'ItemNumber', 0) + Random(100);
inifile.Free;
end;
{保存配置文件}
function TFormMain.SaveConfig(): Boolean;
var
inifile: TIniFile;
begin
inifile := TIniFile.Create('.\!SetUp.txt');
inifile.WriteInteger('setup', 'ItemNumber', MyMakeIndex);
inifile.Free;
end;
procedure TFormMain.FormCreate(Sender: TObject);
var
I: Integer;
pMapInfo: MAPINFO_RCD_ARRAY;
begin
WOrdList := TStringHash.Create;
for I := 0 to High(Script_Command) do
begin
WOrdList.Add(Script_Command[I], I);
end;
MDlgPoints := TList.Create;
Myself := TUserInfo.Create;
ReadConfig(g_IniConfiguration);
// Myself.ScriptNpc('c:\npc.txt');
Myself.m_THumanRcd.dwGold := 1000000;
InitGlobalVariable;
FormMain.Caption := g_IniConfiguration.ServerTitle;
g_fTerminated := False;
pMapInfo := InitDataInDatabase;
InitializingServer(pMapInfo);
end;
procedure TFormMain.BitBtnStopServiceClick(Sender: TObject);
begin
g_fTerminated := True;
// UnInitAdminCommandList;
end;
{初始化服务器}
function TFormMain.InitializingServer(pMapInfo: MAPINFO_RCD_ARRAY): Integer;
var
I,
hFile: Integer;
szFullPath: string;
btInstalled: Byte;
pMyMapInfo: MAPINFO_RCD_ARRAY;
begin
g_szGoldName := IDS_GOLD;
szFullPath := g_IniConfiguration.MapFileLoc + '\SearchTable.tbl';
hFile := FileOpen(szFullPath, fmOpenRead);
if hFile > 0 then
begin
FileRead(hFile, g_SearchTable, SizeOf(g_SearchTable));
FileClose(hFile);
end;
pMyMapInfo := pMapInfo;
for I := 0 to g_nNumOfMapInfo - 1 do
begin
LoadMap(@pMyMapInfo[I]);
end;
pMyMapInfo := nil;
InitAdminCommandList;
if not g_IniConfiguration.Installed then
begin
ShowMessage('Please Set the parameter first!');
end;
ServerSocket1.Port := g_IniConfiguration.ServerPort;
ClientSocketDB.Host := g_IniConfiguration.DBServerIP;
ClientSocketDB.Port := g_IniConfiguration.DBServerPort;
ClientSocketID.Host := g_IniConfiguration.IDServerIP;
ClientSocketID.Port := g_IniConfiguration.IDServerPort;
TimerConnectServer.Enabled := True;
Result := 0;
end;
{初始化全局变量}
procedure InitGlobalVariable;
begin
g_xAdminCommandList := TStringList.Create;
g_xUserCommandList := TStringList.Create;
g_xEventList := TThreadList.Create;
g_xEventCloseList := TThreadList.Create;
g_xHolySeizeList := TThreadList.Create;
g_xReadyUserInfoList := TThreadList.Create;
g_xReadyUserInfoList2 := TThreadList.Create;
g_xMerchantObjList := TThreadList.Create;
g_fInitMerchant := False;
g_xNPCObjList := TThreadList.Create;
g_xReadyList := TThreadList.Create;
g_xGateList := TThreadList.Create;
// General Standard Data
g_xMirMapList := TThreadList.Create;
g_xScripterList := TThreadList.Create;
// SetLength(g_szRemainBuff, DATA_BUFSIZE);
end;
{释放全局变量}
procedure FreeGlobalVariable;
begin
if g_xAdminCommandList <> nil then
begin
FreeAndNil(g_xAdminCommandList);
end;
if g_xUserCommandList <> nil then
begin
FreeAndNil(g_xUserCommandList);
end;
if g_xEventList <> nil then
begin
FreeAndNil(g_xEventList);
end;
if g_xEventCloseList <> nil then
begin
FreeAndNil(g_xEventCloseList);
end;
if g_xHolySeizeList <> nil then
begin
FreeAndNil(g_xHolySeizeList);
end;
if g_xReadyUserInfoList <> nil then
begin
FreeAndNil(g_xReadyUserInfoList);
end;
if g_xReadyUserInfoList2 <> nil then
begin
FreeAndNil(g_xReadyUserInfoList2);
end;
if g_xMerchantObjList <> nil then
begin
FreeAndNil(g_xMerchantObjList);
end;
if g_xNPCObjList <> nil then
begin
FreeAndNil(g_xNPCObjList);
end;
if g_xReadyList <> nil then
begin
FreeAndNil(g_xReadyList);
end;
if g_xGateList <> nil then
begin
FreeAndNil(g_xGateList);
end;
// General Standard Data
if g_xMirMapList <> nil then
begin
FreeAndNil(g_xMirMapList);
end;
if g_xScripterList <> nil then
begin
FreeAndNil(g_xScripterList);
end;
end;
{初始化数据库信息}
function TFormMain.InitDataInDatabase: MAPINFO_RCD_ARRAY;
var
cu: PTCLIENTITEM;
begin
InitMagicInfo; //初始化魔法
InsertLogMsg('初始化魔法');
InitMonRaceInfo;
InsertLogMsg('加载怪物数据库');
InitMonsterGenInfo; //初始化刷怪文件
InsertLogMsg('初始化刷怪文件');
InitStdItemSpecial;
InsertLogMsg('加载物品数据库');
InitMerchantInfo;
InsertLogMsg('初始化NPC');
InitMoveMapEventInfo;
InsertLogMsg('初始化地图移动');
Result := InitMapInfo(g_IniConfiguration.ServerNumber);
InsertLogMsg('加载地图文件');
New(cu);
g_pStdItemSpecial[225].GetStandardItem(cu);
cu.MakeIndex := GetMakeIndex;
Myself.m_BagItems.Add(cu);
end;
{校正DBServer服务器}
procedure TFormMain.TimerConnectServerTimer(Sender: TObject);
begin
StartServer;
if not ClientSocketDB.Active then
ClientSocketDB.Active := True;
if not ClientSocketID.Active then
ClientSocketID.Active := True;
TimerMon.Enabled := True;
TimerNpc.Enabled := True;
{ if not IdTCPClient.Connected then
begin
try
IdTCPClient.Connect(1000);
except
end;
if not IdTCPClient.Connected then
begin
InsertLogMsg('无法连接到数据库服务器');
end
else
begin
InsertLogMsg('登陆数据库服务器成功');
g_cSocket := IdTCPClient.Socket.Binding.Handle;
ConnectToServer;
StartServer;
end;
end;
if not IdTCPClientLog.Connected then
begin
try
IdTCPClientLog.Connect(1000);
except
end;
if not IdTCPClientLog.Connected then
begin
InsertLogMsg('无法连接到日志服务器');
end
else
begin
InsertLogMsg('登陆日志服务器成功');
g_clSocket := IdTCPClient.Socket.Binding.Handle;
end;
end;
}
// if IdTCPClient.Connected and IdTCPClientLog.Connected then
begin
TimerConnectServer.Enabled := False;
end;
end;
procedure TFormMain.StartServer;
begin
try
if Not ServerSocket1.Active then
ServerSocket1.Active := True;
// InsertLogMsg('服务端');
except
end;
end;
{添加日志信息}
procedure TFormMain.InsertLogMsg(strMessage: string);
var
CurrentTime: TSystemTime;
ItemString: string;
NewItem: TListItem;
begin
memLogInfo.Lines.Add(strMessage);
end;
procedure TFormMain.IdTCPServerSocketConnect(AThread: TIdPeerThread);
var
pGateInfo: TGateInfo;
SessionIndex: Integer;
begin
end;
procedure TFormMain.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
var
I: Integer;
begin
Socket.nIndex := -1;
for I := 0 to 49 do
begin
if GateInfo[I].Socket = nil then
begin
GateInfo[I].Socket := Socket;
GateInfo[I].m_Socket := Socket.Handle;
GateInfo[I].sSocData := '';
GateInfo[I].PeerIP := Socket.RemoteAddress;
GateInfo[I].m_nIndex := I;
Socket.nIndex := I;
InsertLogMsg('Gate' + IntToStr(I) + '打开');
Exit;
end;
end;
end;
procedure TFormMain.ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
ErrorCode := 0;
end;
procedure TFormMain.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
nSocketIndex: Integer;
UserData: pTSendUserData;
sReviceMsg: string;
nReviceLen: Integer;
begin
nSocketIndex := Socket.nIndex;
sReviceMsg := Socket.ReceiveText; //接收到的数据
nReviceLen := Length(sReviceMsg);
if (nSocketIndex >= 0) and (nSocketIndex < 50) and (sReviceMsg <> '') then
begin
New(UserData);
UserData.nSocketIndx := nSocketIndex; //把接收的数据添加到UserData对象中
UserData.nSocketHandle := Socket.SocketHandle;
UserData.sMsg := sReviceMsg;
ReviceMsgList.Add(UserData);
end;
end;
{处理用户数据包}
procedure TFormMain.ProcessUserPacket(UserData: pTSendUserData);
var
sMsg, Str: string;
pMsg: PMSGHEADER_RCD;
nLen: Integer;
MsgBuff: PChar;
nIndex: Integer;
pUserInfo: TUserInfo;
I: Integer;
begin
try
if (UserData.nSocketIndx >= 0) and (UserData.nSocketIndx < 50) then
begin
nIndex := UserData.nSocketIndx;
sMsg := GateInfo[UserData.nSocketIndx].sSocData + UserData.sMsg;
nLen := Length(sMsg);
GetMem(MsgBuff, nLen);
MsgBuff := PChar(sMsg);
while nLen > 19 do
begin
pMsg := PMSGHEADER_RCD(MsgBuff);
if pMsg.nCode <> $AA55AA55 then
begin
Inc(MsgBuff);
Dec(nLen);
end
else
begin
case pMsg^.wIdent of //
GM_OPEN:
begin
GateInfo[nIndex].OpenNewUser((MsgBuff));
end;
GM_CLOSE: //玩家退出
begin
pUserInfo := g_xUserInfoArr[pMsg^.wUserListIndex];
Dec(HumCOunt);
if pUserInfo <> nil then
begin
if pMsg.nSocket <> pUserInfo.m_Socket then
begin
pUserInfo := nil;
for I := 0 to 4999 do
begin
if g_xUserInfoArr[I] <> nil then
if g_xUserInfoArr[I].m_Socket = pMsg.nSocket then
begin
pUserInfo := g_xUserInfoArr[I];
Break;
end;
end;
end;
end;
if pUserInfo = nil then
Break;
if pUserInfo <> nil then
begin
if pUserInfo.m_bEmpty then
Break;
pUserInfo.CloseUserHuman(26);
pUserInfo.CloseAccount(pUserInfo.m_szUserID,
pUserInfo.m_nCertification);
for I := 0 to pUserInfo.m_BagItems.COunt - 1 do
Dispose(pUserInfo.m_BagItems.items[I]);
pUserInfo.m_BagItems.Clear;
pUserInfo.m_lpTMagicRcd.Clear;
pUserInfo.m_TakeItemsCount := 0;
g_xPlayerObjectArr[TPlayerObject(pUserInfo.m_pxPlayerObject).m_nArrIndex].m_bEmpty := True;
g_xUserInfoArr[pMsg^.wUserListIndex].m_bEmpty := True;
end;
end;
GM_CHECKCLIENT:
begin
GateInfo[nIndex].SendGateCheck;
end;
GM_RECEIVE_OK:
begin
// do nothing Now
end;
GM_Data:
begin
pUserInfo := g_xUserInfoArr[pMsg^.wUserListIndex];
if pUserInfo <> nil then
begin
if pMsg.nSocket <> pUserInfo.m_Socket then
begin
pUserInfo := nil;
for I := 0 to 4999 do
begin
if g_xUserInfoArr[I] <> nil then
if g_xUserInfoArr[I].m_Socket = pMsg.nSocket then
begin
pUserInfo := g_xUserInfoArr[I];
Break;
end;
end;
end;
if pUserInfo = nil then
Break;
if pUserInfo.m_btCurrentMode = USERMODE_PLAYGAME then
begin
if pMsg.nSocket = pUserInfo.m_Socket then
pUserInfo.ProcessUserMessage((MsgBuff +
SizeOf(TMSGHEADER_RCD)), pMsg^.nLength);
end
else
begin
pUserInfo.DoClientCertification(string(MsgBuff +
SizeOf(TMSGHEADER_RCD)));
end;
end;
end;
end;
end;
MsgBuff := MsgBuff + abs(pMsg.nLength) + 20;
nLen := nLen - (abs(pMsg.nLength) + 20);
end;
GateInfo[UserData.nSocketIndx].sSocData := string(MsgBuff);
end;
except
end;
end;
procedure TFormMain.DecodeTimerTimer(Sender: TObject);
var
dwLoopProcessTime, dwProcessReviceMsgLimiTick: LongWord;
UserData: pTSendUserData;
I: Integer;
tUserData: TSendUserData;
begin
try
dwProcessReviceMsgLimiTick := GetTickCount();
while (True) do
begin
if ReviceMsgList.COunt <= 0 then
Break;
UserData := ReviceMsgList.items[0];
ReviceMsgList.Delete(0);
ProcessUserPacket(UserData); //处理用户数据
Dispose(UserData);
if (GetTickCount - dwProcessReviceMsgLimiTick) > 80 then
Break;
end;
except
on E: Exception do
begin
end;
end;
end;
procedure TFormMain.ClientSocketDBRead(Sender: TObject;
Socket: TCustomWinSocket);
var
s: string;
begin
s := Socket.ReceiveText;
g_szTempBuffer := g_szTempBuffer + s;
ProcReceiveBufferDB;
end;
procedure TFormMain.ClientSocketDBError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
ErrorCode := 0;
StatusBar1.Panels[1].text:='DB Error';
end;
procedure TFormMain.Timer1Timer(Sender: TObject);
const
LoginBuf: array[0..17] of Byte = ($28, $31, $30, $33, $2F, $C0, $D6, $B6, $BC,
$B4, $AB, $C6, $E6, $2F, $30, $2F, $30, $29);
begin
LoginBuf[16] := $30 + HumCOunt;
if ClientSocketID.Active then
ClientSocketID.Socket.SendBuf(LoginBuf, 18);
StatusBar1.Panels[0].Text:=Format('网关数:%d',[ServerSocket1.Socket.ActiveConnections]);
end;
procedure TFormMain.ClientSocketIDRead(Sender: TObject;
Socket: TCustomWinSocket);
var
s: string;
begin
s := Socket.ReceiveText;
InsertLogMsg(s);
end;
procedure TFormMain.TimerHumTimer(Sender: TObject);
var
I: Integer;
pUserInfo: TUserInfo;
begin
for I := 0 to 4999 do //Iterate
begin
pUserInfo := g_xUserInfoArr[I];
if pUserInfo <> nil then
begin
if (pUserInfo.m_btCurrentMode = USERMODE_PLAYGAME) and (not
pUserInfo.m_bEmpty) then
begin
pUserInfo.Operate;
end;
end;
//Delete(I);
end;
end;
{处理怪物操作}
procedure TFormMain.TimerMonTimer(Sender: TObject);
{begin
if mon<>nil then
Begin
mon.SearchViewRange;
mon.Operate;
End;
end;
}
var
I,
N,
dwCurrentTick,
dwLastGenTick: LongWord;
pMonGenInfo: PMONSTERGENINFO_RCD;
pMonsterObject: TMonsterObject;
nCount: Integer;
begin
// if Busy then exit;
Busy := True;
begin
//Generate Monster
if (GetTickCount - dwLastGenTick) > 1000 then
begin
if nCurrMonGen < (g_nNumOfMonGenInfo - 2) then
begin
Inc(nCurrMonGen);
end
else
begin
nCurrMonGen := 0;
end;
if nCurrMonGen < 0 then
nCurrMonGen := 0;
pMonGenInfo := @g_pMonGenInfo[nCurrMonGen];
if pMonGenInfo <> nil then
begin
if (pMonGenInfo^.dwStartTime = 0) or ((dwLastGenTick -
pMonGenInfo^.dwStartTime) > GetZenTime(pMonGenInfo^.dwZenTime)) then
begin
nCount := pMonGenInfo^.xMonsterObjList.LockList.COunt;
if pMonGenInfo^.nCount > nCount then
begin
if RegenMonster(pMonGenInfo, pMonGenInfo^.nCount - nCount) then
begin
// InsertLogMsg('刷怪 '+pMonGenInfo^.szMonName+' '+inttostr(pMonGenInfo^.nCount - nCOunt));
Label1.Caption := IntToStr(MonCount) + ' ' +
pMonGenInfo^.szMonName + ' ' + IntToStr(pMonGenInfo^.nCount -
nCount);
pMonGenInfo^.dwStartTime := GetTickCount;
end;
end;
pMonGenInfo^.xMonsterObjList.UnlockList;
end;
end;
end;
// Execute Monster A.I g_nNumOfMonGenInfo
dwCurrentTick := GetTickCount;
dwLastGenTick := GetTickCount;
//Label2.Caption:=Inttostr(RunMongen);
for I := 0 {RunMonGen} to g_nNumOfMonGenInfo - 1 do
begin
// if (GetTickCount -dwLastGenTick)>30 then Break;
//Inc(RunMonGen);
//if RunMonGen>(g_nNumOfMonGenInfo-1) then RunMonGen:=0;
{if i > 2680 then
MyDebugFile.AddMyDebugFile(IntToStr(i)); }
pMonGenInfo := @g_pMonGenInfo[I];
if pMonGenInfo <> nil then
begin
with pMonGenInfo^.xMonsterObjList.LockList do
begin
if COunt = 0 then
Continue;
for N := COunt - 1 downto 0 do //Iterate
begin
pMonsterObject := items[N];
if pMonsterObject <> nil then
begin
{if (pMonsterObject.m_szName = '半兽人') and (n = 51) then
Sleep(10);}
if TMirMap(pMonsterObject.m_pMap).m_HumCount = 0 then //当前地图人物数量
Break;
dwCurrentTick := GetTickCount;
if not pMonsterObject.m_fIsGhost then
begin
if (dwCurrentTick - pMonsterObject.m_dwRunTime) >=
pMonsterObject.m_dwRunNextTick then
begin
pMonsterObject.m_dwRunTime := dwCurrentTick;
if (dwCurrentTick - pMonsterObject.m_dwSearchTime) >=
pMonsterObject.m_dwSearchTick then
begin
pMonsterObject.m_dwSearchTime := dwCurrentTick;
pMonsterObject.SearchViewRange;
end;
pMonsterObject.Operate;
end;
end
else
begin
if (GetTickCount - pMonsterObject.m_dwGhostTime) > 3 * 60 * 1000
then
begin
FreeAndNil(pMonsterObject);
Delete(N);
Continue;
end;
end;
end;
end; //for
end; // with
pMonGenInfo^.xMonsterObjList.UnlockList;
//Label2.Caption:=Inttostr(RunMongen);
end; // if (pMonGenInfo)
end;
end;
Busy := False;
end;
procedure TFormMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SaveConfig;
end;
procedure TFormMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if MessageDlg('是否确认退出服务器?', mtConfirmation, [mbYes, mbNo], 0) = mrYes
then
SaveConfig
else
CanClose := False;
end;
{处理NPC}
procedure TFormMain.TimerNpcTimer(Sender: TObject);
var
I: Integer;
dwCurrentTick: LongWord;
pMap: TMirMap;
pMerchantObject: TMerchantObject;
begin
dwCurrentTick := GetTickCount;
if not g_fInitMerchant then
begin
for I := 0 to g_nNumOfMerchantInfo - 1 do
begin
pMap := GetMap(g_pMerchantInfo[I].szMapName);
if pMap <> nil then
begin
pMerchantObject := TMerchantObject.Create;
pMerchantObject.m_wObjectType := _OBJECT_NPC;
pMerchantObject.m_nIndex := I;
// pMerchantObject.m_tFeature.btGender := 2;
// pMerchantObject.m_tFeature.btWear := Byte(g_pMerchantInfo[I].sBody);
pMerchantObject.m_nCurrX := g_pMerchantInfo[I].nPosX;
pMerchantObject.m_nCurrY := g_pMerchantInfo[I].nPosY;
pMerchantObject.m_nDirection := g_pMerchantInfo[I].sFace;
pMerchantObject.m_pMap := pMap;
pMerchantObject.m_tFeature.btGender := 50;
pMerchantObject.m_tFeature.btHair := g_pMerchantInfo[I].sBody;
pMerchantObject.m_szName := g_pMerchantInfo[I].szNPCName;
pMerchantObject.ScriptNpc('.\Envir\Market_Def\' +
g_pMerchantInfo[I].idStr + '-' + g_pMerchantInfo[I].szMapName + '.txt');
TMirMap(pMerchantObject.m_pMap).AddNewObject(pMerchantObject.m_nCurrX,
pMerchantObject.m_nCurrY, OS_MOVINGOBJECT, pMerchantObject);
g_xMerchantObjList.Add(pMerchantObject);
end;
end;
g_fInitMerchant := True;
end;
with g_xMerchantObjList.LockList do
begin
for I := 0 to COunt - 1 do // Iterate
begin
pMerchantObject := items[I];
if (dwCurrentTick - pMerchantObject.m_dwRunTime) >=
pMerchantObject.m_dwRunNextTick then
begin
pMerchantObject.m_dwRunTime := dwCurrentTick;
if (dwCurrentTick - pMerchantObject.m_dwSearchTime) >=
pMerchantObject.m_dwSearchTick then
begin
pMerchantObject.m_dwSearchTime := dwCurrentTick;
pMerchantObject.SearchViewRange;
end;
pMerchantObject.RunRace;
end;
end; // for
end; // with
g_xMerchantObjList.UnlockList;
TimerNpc.Enabled := False;
end;
procedure TFormMain.ClientSocketDBConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
StatusBar1.Panels[1].Text:='DB OK';
end;
procedure TFormMain.ClientSocketDBDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
StatusBar1.Panels[1].text:='DB DisConnect';
end;
end.