⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 runsock.pas

📁 原版翎风(LF)引擎(M2)源码(Delphi)
💻 PAS
📖 第 1 页 / 共 3 页
字号:
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 + -