source: tags/1.3.0/Network/UNetworkClient.pas

Last change on this file was 382, checked in by chronos, 3 years ago
  • Fixed: Removed some build hints on Windows.
File size: 4.5 KB
Line 
1unit UNetworkClient;
2
3{$mode delphi}
4
5interface
6
7uses
8 Classes, SysUtils{$IFDEF LINUX}, fpAsync, fpsock{$ENDIF}, Protocol;
9
10{$IFDEF LINUX}
11type
12 { TTCPClientThread }
13
14 TTCPClientThread = class(TThread)
15 TCPClient: TTCPClient;
16 procedure Execute; override;
17 end;
18
19 { TNetworkClient }
20
21 TNetworkClient = class
22 private
23 DataAvailableHandle: Pointer;
24 TCPClientThread: TTCPClientThread;
25 ReceiveBuffer: TMemoryStream;
26 procedure DataAvailableExecute(Sender: TObject);
27 procedure ConnectionStateChangeExecute(Sender: TClientConnectionSocket;
28 OldState, NewState: TConnectionState);
29 procedure DataAvailableSync;
30 public
31 AuxServer: TServerCall;
32 LocalClient: TClientCall;
33 TCPClient: TTCPClient;
34 ClientEventLoop: TEventLoop;
35 function Server(Command: TCommand; Player, Subject: Integer; var Data): Integer;
36 constructor Create;
37 destructor Destroy; override;
38 end;
39
40var
41 NetworkClient: TNetworkClient;
42{$ENDIF}
43
44procedure Client(Command, Player: Integer; var Data); stdcall;
45
46
47implementation
48
49uses
50 LocalPlayer{$IFDEF LINUX}, Global, UNetworkCommon{$ENDIF};
51
52procedure Client(Command, Player: Integer; var Data);
53{$IFDEF LINUX}
54var
55 Cmd: TCommand;
56{$ENDIF}
57begin
58 {$IFDEF LINUX}
59 Cmd := TCommand(Command);
60 case Cmd of
61 cmInitModule: begin
62 if not Assigned(NetworkClient) then
63 NetworkClient := TNetworkClient.Create;
64 NetworkClient.AuxServer := TInitModuleData(Data).Server;
65 TInitModuleData(Data).Flags := aiThreaded;
66 NetworkClient.LocalClient := LocalPlayer.Client;
67 end;
68 cmReleaseModule: begin
69 FreeAndNil(NetworkClient);
70 end;
71 end;
72 {$ENDIF}
73end;
74
75{$IFDEF LINUX}
76function LocalServer(Command, Player, Subject: Integer; var Data): Integer; stdcall;
77begin
78 if Assigned(NetworkClient) then
79 Result := NetworkClient.Server(TCommand(Command), Player, Subject, Data);
80end;
81
82{ TTCPClientThread }
83
84procedure TTCPClientThread.Execute;
85begin
86 TCPClient.EventLoop.Run;
87end;
88
89{ TNetworkClient }
90
91procedure TNetworkClient.DataAvailableExecute(Sender: TObject);
92begin
93 TCPClientThread.Synchronize(TCPClientThread, DataAvailableSync);
94
95 ClientEventLoop.ClearDataAvailableNotify(DataAvailableHandle);
96 DataAvailableHandle := ClientEventLoop.SetDataAvailableNotify(TCPClient.Stream.Handle, DataAvailableExecute, nil);
97end;
98
99procedure TNetworkClient.ConnectionStateChangeExecute(
100 Sender: TClientConnectionSocket; OldState, NewState: TConnectionState);
101begin
102 if NewState = connConnected then
103 DataAvailableHandle := ClientEventLoop.SetDataAvailableNotify(TCPClient.Stream.Handle, DataAvailableExecute, nil);
104end;
105
106procedure TNetworkClient.DataAvailableSync;
107var
108 Command: Integer;
109 ReadCount: Integer;
110 Player: Integer;
111 Data: array of Byte;
112begin
113 StreamAppend(ReceiveBuffer, TCPClient.Stream);
114 while ReceiveBuffer.Size >= 2 * SizeOf(Integer) do begin
115 ReceiveBuffer.Position := 0;
116 Command := Integer(ReceiveBuffer.ReadDWord);
117 Player := Integer(ReceiveBuffer.ReadDWord);
118 SetLength(Data, GetCommandDataSize(TCommand(Command)));
119 if Length(Data) > 0 then begin
120 ReadCount := ReceiveBuffer.Read(Data[0], Length(Data));
121 SetLength(Data, ReadCount);
122 end;
123
124 // Rewrite server address received from network by local handler
125 if Command = cInitModule then begin
126 PInitModuleData(@Data[0])^.Server := LocalServer;
127 end;
128
129 if Length(Data) > 0 then
130 LocalClient(Command, Player, Data[0])
131 else LocalClient(Command, Player, nil^);
132
133 StreamRemoveRead(ReceiveBuffer);
134 end;
135end;
136
137function TNetworkClient.Server(Command: TCommand; Player, Subject: Integer;
138 var Data): Integer;
139begin
140 with TCPClient.Stream do begin
141 WriteDWord(DWord(Command));
142 WriteDWord(Player);
143 WriteDWord(Subject);
144 if GetCommandDataSize(Command) > 0 then
145 Write(Data, GetCommandDataSize(Command));
146 Result := ReadDWord;
147 end;
148end;
149
150constructor TNetworkClient.Create;
151begin
152 ReceiveBuffer := TMemoryStream.Create;
153 ClientEventLoop := TEventLoop.Create;
154 TCPClient := TTCPClient.Create(nil);
155 with TCPClient do begin
156 EventLoop := ClientEventLoop;
157 Host := '127.0.0.1';
158 Port := CevoNetworkPort;
159 OnConnectionStateChange := ConnectionStateChangeExecute;
160 Active := True;
161 end;
162 TCPClientThread := TTCPClientThread.Create(True);
163 TCPClientThread.TCPClient := TCPClient;
164 TCPClientThread.Start;
165end;
166
167destructor TNetworkClient.Destroy;
168begin
169 ClientEventLoop.Break;
170 FreeAndNil(TCPClientThread);
171 FreeAndNil(TCPClient);
172 FreeAndNil(ClientEventLoop);
173 FreeAndNil(ReceiveBuffer);
174 inherited;
175end;
176{$ENDIF}
177
178end.
179
Note: See TracBrowser for help on using the repository browser.