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

📄 runsock.~pas

📁 继续更新AFT源代码 现在解决了无法登陆游戏的问题 用0504的dbserver就可以登陆了 去掉了绿字广告 降低内存占用HOO 去掉了大量的验证问题
💻 ~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 DemoRun();
    procedure Execute;
    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.boSendCheckPro  := false;
      Gate.dwSendCheckProTick   := GetTickCount;
      Gate.nSendBlockCount := 0;
      Gate.dwTime544       := 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);
            //   MainOutMessage('if not TPlayObject(GateUser.PlayObject).m_boReconnection then SendHumanLogOutmsg');
              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              //网关连接上后 60秒以后发送一个 消息 给网关,告诉网关,专业版本
          if (not Gate.boSendCheckPro)and (GetTickCount - Gate.dwSendCheckProTick >(random(60)+10)*1000)  then begin
            Gate.boSendCheckPro:=true;
            SendCheck(Gate.Socket,GM_TEST);
          end;
        end;//004E1EBF
      end;
    except
      on e: Exception do begin
        MainOutMessage(sExceptionMsg);
        MainOutMessage(E.Message);  raise;
      end;

    end;
  end;//004E1EEA if boStartReady then begin
  g_nSockCountMin:=GetTickCount - dwRunTick;
  if g_nSockCountMin > g_nSockCountMax then g_nSockCountMax := g_nSockCountMin;
   asm
      NOP; NOP; NOP; NOP; NOP; NOP; NOP; NOP; NOP; NOP;
   end;
end;

procedure TRunSocket.DoClientCertification(GateIdx:Integer;GateUser:pTGateUserInfo;nSocket:Integer;sMsg:String);//004E1028
  function ScanCertification(sAccount:String;sChrName:String;nSessionID,nClientVersion:Integer):Boolean;
  var
    DefMsg:TDefaultMessage;
  //  DES:TDES;                       //  DES有问题
  ResourceString
    sInfoMsg = '%s/%s/%s/%d/%d/%d/%d-%d';
  begin
    Result:=False;
    //**00/88/200000/200000/0
     if (sAccount = '00') and (sChrName = '88') and (nSessionID = 200000) and (nClientVersion = 200000) then begin
 //     DES:=TDES.Create;
      sMsg:=format(sInfoMsg,[g_Config.sServerName,
                                  g_config.sRegKey,
                                  g_config.sRegServerAddr,
                                  g_config.nRegServerPort,
                                  UserEngine.OnlinePlayObject,
                                  g_dwStartTick,
                                  GetTickCount,
                                  VEROWNER]);
  //    sMsg:=DES.EncryptHexString(sMsg,IntToStr(nSessionID xor (nClientVersion div 3)));
  //    DES.Free;
      SendScanMsg(nil,EncodeString(sMsg),GateIdx,nSocket,GateUser.nGSocketIdx);
      Result:=True;
   end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -