📄 runsock.pas
字号:
unit RunSock;
interface
uses
Windows, Classes, SysUtils, StrUtils, SyncObjs, JSocket, ObjBase, Grobal2, SDK, FrnEngn, UsrEngn;
type
TRunSocket = class //Size: 0xCD0
m_RunSocketSection: TRTLCriticalSection;
m_RunAddrList: TStringList; //0x4
n8: Integer; //0x8
m_IPaddrArr: array[0..19] of TIPaddr;
n4F8: Integer; //0x4F8
dwSendTestMsgTick: LongWord; //0x4FC
private
procedure LoadRunAddr;
procedure ExecGateBuffers(nGateIndex: Integer; Gate: pTGateInfo; Buffer: PChar; nMsgLen: Integer);
procedure DoClientCertification(GateIdx: Integer; GateUser: pTGateUserInfo; nSocket: Integer; sMsg: string);
procedure ExecGateMsg(GateIdx: Integer; Gate: pTGateInfo; MsgHeader: pTMsgHeader; MsgBuff: PChar; nMsgLen: Integer);
procedure SendCheck(Socket: TCustomWinSocket; nIdent: Integer);
function OpenNewUser(nSocket: Integer; nGSocketIdx: Integer; sIPaddr: string; UserList: TList): Integer;
procedure SendNewUserMsg(Socket: TCustomWinSocket; nSocket: Integer; nSocketIndex, nUserIdex: Integer);
procedure SendGateTestMsg(nIndex: Integer);
function SendGateBuffers(GateIdx: Integer; Gate: pTGateInfo; MsgList: TList): Boolean;
function GetGateAddr(sIPaddr: string): string;
procedure SendScanMsg(DefMsg: pTDefaultMessage; sMsg: string; nGateIdx, nSocket, nGsIdx: Integer);
public
constructor Create();
destructor Destroy; override;
procedure AddGate(Socket: TCustomWinSocket);
procedure SocketRead(Socket: TCustomWinSocket);
procedure CloseGate(Socket: TCustomWinSocket);
procedure CloseErrGate(Socket: TCustomWinSocket; var ErrorCode: Integer);
procedure CloseAllGate();
procedure Run();
procedure CloseUser(GateIdx, nSocket: Integer);
function AddGateBuffer(GateIdx: Integer; Buffer: PChar): Boolean;
procedure SendOutConnectMsg(nGateIdx, nSocket, nGsIdx: Integer);
procedure SetGateUserList(nGateIdx, nSocket: Integer; PlayObject: TPlayObject);
procedure KickUser(sAccount: string; nSessionID: Integer);
end;
var
g_GateArr: array[0..19] of TGateInfo;
g_nGateRecvMsgLenMin: Integer;
g_nGateRecvMsgLenMax: Integer;
implementation
uses M2Share, IdSrvClient, HUtil32, EDcode, EncryptUnit;
var
nRunSocketRun: Integer = -1;
{ TRunSocket }
procedure TRunSocket.AddGate(Socket: TCustomWinSocket);
var
i: Integer;
sIPaddr: string;
Gate: pTGateInfo;
resourcestring
sGateOpen = '游戏网关[%d](%s:%d) 已打开...';
sKickGate = '服务器未就绪: %s';
begin
sIPaddr := Socket.RemoteAddress;
if boStartReady then
begin
for i := Low(g_GateArr) to High(g_GateArr) do
begin
Gate := @g_GateArr[i];
if Gate.boUsed then Continue;
Gate.boUsed := True;
Gate.Socket := Socket;
Gate.sAddr := GetGateAddr(sIPaddr);
Gate.nPort := Socket.RemotePort;
Gate.n520 := 1;
Gate.UserList := TList.Create;
Gate.nUserCount := 0;
Gate.Buffer := nil;
Gate.nBuffLen := 0;
Gate.BufferList := TList.Create;
Gate.boSendKeepAlive := False;
Gate.nSendChecked := 0;
Gate.nSendBlockCount := 0;
Gate.dwStartTime := GetTickCount;
MainOutMessage(Format(sGateOpen, [i, Socket.RemoteAddress, Socket.RemotePort]));
Break;
end;
end else
begin
MainOutMessage(Format(sKickGate, [sIPaddr]));
Socket.Close;
end;
end;
procedure TRunSocket.CloseAllGate; //004E0068
var
GateIdx: Integer;
Gate: pTGateInfo;
begin
for GateIdx := Low(g_GateArr) to High(g_GateArr) do
begin
Gate := @g_GateArr[GateIdx];
if Gate.Socket <> nil then
begin
Gate.Socket.Close;
end;
end;
end;
procedure TRunSocket.CloseErrGate(Socket: TCustomWinSocket;
var ErrorCode: Integer); //004DFF58
begin
if Socket.Connected then Socket.Close;
ErrorCode := 0;
end;
procedure TRunSocket.CloseGate(Socket: TCustomWinSocket); //004E00B4
var
i, GateIdx: Integer;
GateUser: pTGateUserInfo;
UserList: TList;
Gate: pTGateInfo;
resourcestring
sGateClose = '游戏网关[%d](%s:%d) 已关闭...';
begin
EnterCriticalSection(m_RunSocketSection);
try
for GateIdx := Low(g_GateArr) to High(g_GateArr) do
begin
Gate := @g_GateArr[GateIdx];
if Gate.Socket = Socket then
begin
UserList := Gate.UserList;
for i := 0 to UserList.Count - 1 do
begin
GateUser := UserList.Items[i];
if GateUser <> nil then
begin
if GateUser.PlayObject <> nil then
begin
TPlayObject(GateUser.PlayObject).m_boEmergencyClose := True;
if not TPlayObject(GateUser.PlayObject).m_boReconnection then
begin
FrmIDSoc.SendHumanLogOutMsg(GateUser.sAccount, GateUser.nSessionID);
end;
end;
Dispose(GateUser);
UserList.Items[i] := nil;
end;
end;
Gate.UserList.Free;
Gate.UserList := nil;
//004E01BF
if Gate.Buffer <> nil then
FreeMem(Gate.Buffer);
Gate.Buffer := nil;
Gate.nBuffLen := 0;
for i := 0 to Gate.BufferList.Count - 1 do
begin
FreeMem(Gate.BufferList.Items[i]);
end;
Gate.BufferList.Free;
Gate.BufferList := nil;
Gate.boUsed := False;
Gate.Socket := nil;
MainOutMessage(Format(sGateClose, [GateIdx, Socket.RemoteAddress, Socket.RemotePort]));
Break;
end;
end; //004E02F1
finally
LeaveCriticalSection(m_RunSocketSection);
end;
end;
//004E16E4
procedure TRunSocket.ExecGateBuffers(nGateIndex: Integer; Gate: pTGateInfo; Buffer: PChar; nMsgLen: Integer);
var
nLen: Integer;
Buff: PChar;
MsgBuff: PChar;
MsgHeader: pTMsgHeader; //0x20
nCheckMsgLen: Integer;
TempBuff: PChar;
resourcestring
sExceptionMsg1 = '[Exception] TRunSocket::ExecGateBuffers -> pBuffer';
sExceptionMsg2 = '[Exception] TRunSocket::ExecGateBuffers -> @pwork,ExecGateMsg ';
sExceptionMsg3 = '[Exception] TRunSocket::ExecGateBuffers -> FreeMem';
begin
nLen := 0;
Buff := nil;
try
if Buffer <> nil then
begin
ReAllocMem(Gate.Buffer, Gate.nBuffLen + nMsgLen);
Move(Buffer^, Gate.Buffer[Gate.nBuffLen], nMsgLen);
end;
except
MainOutMessage(sExceptionMsg1);
end;
try
nLen := Gate.nBuffLen + nMsgLen;
Buff := Gate.Buffer;
if nLen >= SizeOf(TMsgHeader) then
begin
while (True) do
begin
{
pMsg:=pTMsgHeader(Buff);
if pMsg.dwCode = RUNGATECODE then begin
if nLen < (pMsg.nLength + SizeOf(TMsgHeader)) then break;
MsgBuff:=@Buff[SizeOf(TMsgHeader)];
}
MsgHeader := pTMsgHeader(Buff);
nCheckMsgLen := abs(MsgHeader.nLength) + SizeOf(TMsgHeader);
if (MsgHeader.dwCode = RUNGATECODE) and (nCheckMsgLen < $8000) then
begin
if nLen < nCheckMsgLen then Break;
MsgBuff := Buff + SizeOf(TMsgHeader); //Jacky 1009 换上
//MsgBuff:=@Buff[SizeOf(TMsgHeader)];
ExecGateMsg(nGateIndex, Gate, MsgHeader, MsgBuff, MsgHeader.nLength);
Buff := Buff + SizeOf(TMsgHeader) + MsgHeader.nLength; //Jacky 1009 换上
//Buff:=@Buff[SizeOf(TMsgHeader) + pMsg.nLength];
nLen := nLen - (MsgHeader.nLength + SizeOf(TMsgHeader));
end else
begin
Inc(Buff);
Dec(nLen);
end;
if nLen < SizeOf(TMsgHeader) then Break;
end;
end;
except
MainOutMessage(sExceptionMsg2);
end;
try
if nLen > 0 then
begin
GetMem(TempBuff, nLen);
Move(Buff^, TempBuff^, nLen);
FreeMem(Gate.Buffer);
Gate.Buffer := TempBuff;
Gate.nBuffLen := nLen;
end else
begin
FreeMem(Gate.Buffer);
Gate.Buffer := nil;
Gate.nBuffLen := 0;
end;
except
MainOutMessage(sExceptionMsg3);
end;
end;
procedure TRunSocket.SocketRead(Socket: TCustomWinSocket); //004DFF84
var
nMsgLen, GateIdx: Integer;
Gate: pTGateInfo;
RecvBuffer: array[0..DATA_BUFSIZE * 2 - 1] of Char;
nLoopCheck: Integer;
resourcestring
sExceptionMsg1 = '[Exception] TRunSocket::SocketRead';
begin
for GateIdx := Low(g_GateArr) to High(g_GateArr) do
begin
Gate := @g_GateArr[GateIdx];
if Gate.Socket = Socket then
begin
try
//nLoopCheck:=0;
while (True) do
begin //Jacky 1009 换上
nMsgLen := Socket.ReceiveBuf(RecvBuffer, SizeOf(RecvBuffer));
if nMsgLen <= 0 then Break;
ExecGateBuffers(GateIdx, Gate, @RecvBuffer, nMsgLen);
// Inc(nLoopCheck);
// if nLoopCheck > g_Config.nRunSocketDieLoopLimit then begin
// MainOutMessage('[Exception] TRunSocket.SocketRead DieLoop');
// break;
// end;
end;
Break;
except
MainOutMessage(sExceptionMsg1);
end;
end;
end;
end;
procedure TRunSocket.Run; //004E1CD0
var
dwRunTick: LongWord;
i, nG: Integer;
Gate: pTGateInfo;
resourcestring
sExceptionMsg = '[Exception] TRunSocket::Run ';
begin
dwRunTick := GetTickCount();
if boStartReady then
begin
try
if g_Config.nGateLoad > 0 then
begin
if (GetTickCount - dwSendTestMsgTick) >= 100 then
begin
dwSendTestMsgTick := GetTickCount();
for i := Low(g_GateArr) to High(g_GateArr) do
begin
Gate := @g_GateArr[i];
if Gate.BufferList <> nil then
begin
for nG := 0 to g_Config.nGateLoad - 1 do
begin
SendGateTestMsg(i);
end; //004E1D7D
end;
end;
end; //if (GetTickCount() - dwTime4FC) >= 100 then begin
end; //004E1D86 if nGateLoad > 0 then begin
for i := Low(g_GateArr) to High(g_GateArr) do
begin
Gate := @g_GateArr[i];
if Gate.BufferList <> nil then
begin
{
EnterCriticalSection(RunSocketSection);
try
TempList:=SendMsgList;
SendMsgList:=Gate.BufferList;
Gate.BufferList:=TempList;
finally
LeaveCriticalSection(RunSocketSection);
end;
Gate.nSendMsgCount:=SendMsgList.Count;
ThreadSendGateBuffers(i,Gate,SendMsgList);
Gate.nSendRemainCount:=SendMsgList.Count;
SendMsgList.Clear;
}
EnterCriticalSection(m_RunSocketSection);
try
Gate.nSendMsgCount := Gate.BufferList.Count;
if SendGateBuffers(i, Gate, Gate.BufferList) then
begin
Gate.nSendRemainCount := Gate.BufferList.Count;
end else
begin //004E1DE3
Gate.nSendRemainCount := Gate.BufferList.Count;
end;
finally
LeaveCriticalSection(m_RunSocketSection);
end;
end; //004E1DF2
end; //004E1DFB
for i := Low(g_GateArr) to High(g_GateArr) do
begin
if g_GateArr[i].Socket <> nil then
begin
Gate := @g_GateArr[i];
if (GetTickCount - Gate.dwSendTick) >= 1000 then
begin
Gate.dwSendTick := GetTickCount();
Gate.nSendMsgBytes := Gate.nSendBytesCount;
Gate.nSendedMsgCount := Gate.nSendCount;
Gate.nSendBytesCount := 0;
Gate.nSendCount := 0;
end; //004E1E75
if Gate.boSendKeepAlive then
begin
Gate.boSendKeepAlive := False;
SendCheck(Gate.Socket, GM_CHECKSERVER);
end; //004E1EBF
end; //004E1EBF
end;
except
on E: Exception do
begin
MainOutMessage(sExceptionMsg);
MainOutMessage(E.Message);
end;
end;
end; //004E1EEA if boStartReady then begin
g_nSockCountMin := GetTickCount - dwRunTick;
if g_nSockCountMin > g_nSockCountMax then g_nSockCountMax := g_nSockCountMin;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -