Ignore:
Timestamp:
Apr 13, 2021, 9:57:36 PM (3 years ago)
Author:
chronos
Message:
  • Modified: Improved unfinished network client data handling.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Network/UNetworkClient.pas

    r364 r365  
    88  Classes, SysUtils, fpsock, fpAsync, Protocol;
    99
    10 
    11 procedure Client(Command, Player: Integer; var Data); stdcall;
    12 
    13 
    14 implementation
    15 
    16 uses
    17   LocalPlayer, Global;
    18 
    1910type
    20 
    2111  { TTCPClientThread }
    2212
     
    3323    TCPClientThread: TTCPClientThread;
    3424    ReceiveBuffer: TMemoryStream;
    35     procedure AppendStream(Stream: TStream; SourceStream: TStream);
    3625    procedure DataAvailableExecute(Sender: TObject);
    3726    procedure ConnectionStateChangeExecute(Sender: TClientConnectionSocket;
    3827      OldState, NewState: TConnectionState);
     28    procedure DataAvailableSync;
    3929  public
    4030    AuxServer: TServerCall;
     
    4939var
    5040  NetworkClient: TNetworkClient;
     41
     42procedure Client(Command, Player: Integer; var Data); stdcall;
     43
     44
     45implementation
     46
     47uses
     48  LocalPlayer, Global, UNetworkCommon;
     49
     50function LocalServer(Command, Player, Subject: Integer; var Data): Integer; stdcall;
     51begin
     52  if Assigned(NetworkClient) then
     53    Result := NetworkClient.Server(TCommand(Command), Player, Subject, Data);
     54end;
    5155
    5256procedure Client(Command, Player: Integer; var Data);
     
    7882{ TNetworkClient }
    7983
    80 procedure TNetworkClient.AppendStream(Stream: TStream; SourceStream: TStream);
    81 var
    82   Buffer: array of Byte;
    83   ReadCount: Integer;
    84   Base: Integer;
    85 const
    86   ChunkSize = 4096;
     84procedure TNetworkClient.DataAvailableExecute(Sender: TObject);
    8785begin
    88   SetLength(Buffer, 0);
    89   Base := 0;
    90   repeat
    91     SetLength(Buffer, Length(Buffer) + ChunkSize);
    92     ReadCount := SourceStream.Read(Buffer[Base], ChunkSize);
    93     Inc(Base, ReadCount);
    94     SetLength(Buffer, Base);
    95   until ReadCount < ChunkSize;
    96 
    97   if Length(Buffer) > 0 then begin
    98     Stream.Position := Stream.Size;
    99     Stream.Write(Buffer[0], Length(Buffer));
    100   end;
    101 end;
    102 
    103 procedure TNetworkClient.DataAvailableExecute(Sender: TObject);
    104 var
    105   Command: Integer;
    106   Player: Integer;
    107   Data: array of Byte;
    108 begin
    109   AppendStream(ReceiveBuffer, TCPClient.Stream);
    110   ReceiveBuffer.Position := 0;
    111   Command := Integer(ReceiveBuffer.ReadDWord);
    112   Player := Integer(ReceiveBuffer.ReadDWord);
    113   SetLength(Data, GetCommandDataSize(TCommand(Command)));
    114   if Length(Data) > 0 then
    115     LocalClient(Command, Player, Data[0])
    116     else LocalClient(Command, Player, nil^);
    117 
    118   // Remove already read data from start of memory stream
    119   Move(PByte(ReceiveBuffer.Memory + ReceiveBuffer.Position)^, ReceiveBuffer.Memory^, ReceiveBuffer.Size - ReceiveBuffer.Position);
    120   ReceiveBuffer.SetSize(ReceiveBuffer.Size - ReceiveBuffer.Position);
     86  TCPClientThread.Synchronize(TCPClientThread, DataAvailableSync);
    12187
    12288  ClientEventLoop.ClearDataAvailableNotify(DataAvailableHandle);
     
    12995  if NewState = connConnected then
    13096    DataAvailableHandle := ClientEventLoop.SetDataAvailableNotify(TCPClient.Stream.Handle, DataAvailableExecute, nil);
     97end;
     98
     99procedure TNetworkClient.DataAvailableSync;
     100var
     101  Command: Integer;
     102  ReadCount: Integer;
     103  Player: Integer;
     104  Data: array of Byte;
     105begin
     106  StreamAppend(ReceiveBuffer, TCPClient.Stream);
     107  while ReceiveBuffer.Size >= 2 * SizeOf(Integer) do begin
     108    ReceiveBuffer.Position := 0;
     109    Command := Integer(ReceiveBuffer.ReadDWord);
     110    Player := Integer(ReceiveBuffer.ReadDWord);
     111    SetLength(Data, GetCommandDataSize(TCommand(Command)));
     112    if Length(Data) > 0 then begin
     113      ReadCount := ReceiveBuffer.Read(Data[0], Length(Data));
     114      SetLength(Data, ReadCount);
     115    end;
     116
     117    // Rewrite server address received from network by local handler
     118    if Command = cInitModule then begin
     119      PInitModuleData(@Data[0])^.Server := LocalServer;
     120    end;
     121
     122    if Length(Data) > 0 then
     123      LocalClient(Command, Player, Data[0])
     124      else LocalClient(Command, Player, nil^);
     125
     126    StreamRemoveRead(ReceiveBuffer);
     127  end;
    131128end;
    132129
Note: See TracChangeset for help on using the changeset viewer.