1 | unit USunriseChatCore;
|
---|
2 |
|
---|
3 | interface
|
---|
4 |
|
---|
5 | uses
|
---|
6 | SysUtils, Classes, ExtCtrls, cWindows, cSockets, cSocketsUDP, cTCPClient,
|
---|
7 | cTCPServer, Forms, Dialogs, cWinSock, cSocketHostLookup, WinSock, Graphics,
|
---|
8 | Windows, Registry, cUtils, typinfo, UEthernetAddress;
|
---|
9 |
|
---|
10 | const
|
---|
11 | ProtocolVersion = 2;
|
---|
12 | CoreVersion = '2.7';
|
---|
13 | RemoveTimeout = 33/24/3600; // 33 seconds
|
---|
14 |
|
---|
15 | clSysMessage = $7fffffff;
|
---|
16 | riAll = -1;
|
---|
17 |
|
---|
18 | // User status modes
|
---|
19 | usAway = 'Away';
|
---|
20 | usOnline = 'Online';
|
---|
21 | usWritting = 'Writting';
|
---|
22 | usInvisible = 'Invisible';
|
---|
23 | usOffline = 'Offline';
|
---|
24 |
|
---|
25 | type
|
---|
26 | TAppEventType = (aeCommonMessage, aeOneUserMessage, aeUserConnect,
|
---|
27 | aeUserDisconnect, aeUserRestore, aeUserTimeout, aeUserGoAway, aeUserGoBack,
|
---|
28 | aeSendCallUp, aeReceiveCallUp, aeSendPing, aePingResponse, aeUserChangeNick,
|
---|
29 | aeUserChangeNickConflict, aeCreateRoom, aeLeaveRoom, aeUserAutoGoAway,
|
---|
30 | aeUserAutoGoBack, aeShowHours, aeStart);
|
---|
31 |
|
---|
32 | TMessageEvent = procedure (Text: string; Color: Integer) of object;
|
---|
33 | TClassMethod = procedure of object;
|
---|
34 | TArrayOfString = array of string;
|
---|
35 |
|
---|
36 | TRoomType = (rtPublic, rtPrivate);
|
---|
37 | TLine = record
|
---|
38 | Text: string;
|
---|
39 | Font: TFont;
|
---|
40 | Time: TDateTime;
|
---|
41 | Nick: string;
|
---|
42 | EventType: TAppEventType;
|
---|
43 | end;
|
---|
44 |
|
---|
45 | TRoom = record
|
---|
46 | Name: string;
|
---|
47 | Typ: TRoomType;
|
---|
48 | StartLine: Integer;
|
---|
49 | Count: Integer;
|
---|
50 | Lines: array of TLine;
|
---|
51 | end;
|
---|
52 |
|
---|
53 | TUser = record
|
---|
54 | Nick: string;
|
---|
55 | HostName: string;
|
---|
56 | IP: string;
|
---|
57 | Female: Boolean;
|
---|
58 | Color: Integer;
|
---|
59 | Client: string;
|
---|
60 | ClientVersion: string;
|
---|
61 | CoreVersion: string;
|
---|
62 | OSVersion: string;
|
---|
63 | OSUser: string;
|
---|
64 | Status: string;
|
---|
65 | LastTime: TDateTime;
|
---|
66 | UpTime: TDateTime;
|
---|
67 | LocalSystemTime: TDateTime;
|
---|
68 | UserInfoTime: TDateTime;
|
---|
69 | ID: Integer;
|
---|
70 | NickTime: TDateTime;
|
---|
71 | Reason: string;
|
---|
72 | Sequence: Integer;
|
---|
73 | ErrorCount: Integer;
|
---|
74 | BlockMessages: Boolean;
|
---|
75 | Delay: TDateTime;
|
---|
76 | RoomName: string;
|
---|
77 | RoomType: TRoomType;
|
---|
78 | DetailInfo: string;
|
---|
79 | IdleTime: Integer;
|
---|
80 | end;
|
---|
81 |
|
---|
82 | TAddMessageMethod = procedure(RoomIndex: Integer; const Args: array of const; EventType: TAppEventType; TextColor: TColor = clSysMessage; Nick: string = '') of object;
|
---|
83 |
|
---|
84 | TBroadcastType = (btLocal, btGlobal);
|
---|
85 |
|
---|
86 | TSunriseChatCore = class(TDataModule)
|
---|
87 | fndTCPServer1: TfndTCPServer;
|
---|
88 | fndTCPClient1: TfndTCPClient;
|
---|
89 | fndUDPClientSocket1: TfndUDPClientSocket;
|
---|
90 | Timer1: TTimer;
|
---|
91 | Timer2: TTimer;
|
---|
92 | Timer3: TTimer;
|
---|
93 | procedure fndTCPServer1DataAvailable(Sender: TTCPServerClient);
|
---|
94 | procedure fndTCPClient1ConnectFailed(Sender: ATCPClient);
|
---|
95 | procedure fndTCPClient1DataAvailable(Sender: ATCPClient);
|
---|
96 | procedure fndUDPClientSocket1DataAvailable(Sender: AUDPSocket);
|
---|
97 | procedure fndTCPClient1Close(Sender: ATCPClient);
|
---|
98 | procedure Timer1Timer(Sender: TObject);
|
---|
99 | procedure Timer2Timer(Sender: TObject);
|
---|
100 | procedure DataModuleCreate(Sender: TObject);
|
---|
101 | procedure fndUDPClientSocket1Error(Sender: ASocket);
|
---|
102 | procedure Timer3Timer(Sender: TObject);
|
---|
103 | private
|
---|
104 | FOnAddMessage: TAddMessageMethod;
|
---|
105 | FOnChangeNetworkState: TClassMethod;
|
---|
106 | FOnUserListChange: TClassMethod;
|
---|
107 | // FOnPingResponse: TClassMethod;
|
---|
108 | // FOnCallUp: TClassMethod;
|
---|
109 | FOnCommand: TClassMethod;
|
---|
110 | // FOnNickChange: TClassMethod;
|
---|
111 | FConnected: Boolean;
|
---|
112 | FOnRoomListChanged: TClassMethod;
|
---|
113 | FMaxRoomLines: Integer;
|
---|
114 | LibHandle: HInst; //dll handle
|
---|
115 | LastHour: Word;
|
---|
116 | InputBuffer: string;
|
---|
117 | procedure ExecuteCommand(Text: string);
|
---|
118 | function GetWindowsVersionStr: string;
|
---|
119 | procedure SetMaxRoomLines(Number: Integer);
|
---|
120 | function SecondsIdle: DWord;
|
---|
121 | function Explode(Separator: Char; Data: string): TArrayOfString;
|
---|
122 | public
|
---|
123 | BroadcastType: TBroadcastType;
|
---|
124 | NetworkInterfaces: TNetworkInterfaceList;
|
---|
125 | UDPPort: Integer;
|
---|
126 | NetworkInterfaceIPAddress: string;
|
---|
127 | LocalUser: TUser;
|
---|
128 | UserList: array of TUser;
|
---|
129 | ActiveRoomIndex: Integer;
|
---|
130 | RoomList: array of TRoom;
|
---|
131 | LastMessage: string;
|
---|
132 | LastFont: TFont;
|
---|
133 | LastUserIndex: Integer;
|
---|
134 | LastEventType: TAppEventType;
|
---|
135 | AutoAwayIdleTime: Integer;
|
---|
136 | NetworkBridge: Boolean;
|
---|
137 | NetworkInterfaceIndex: Integer;
|
---|
138 | procedure ChangeNick(NewNick: string; SendCmd: Boolean = True);
|
---|
139 | procedure Init;
|
---|
140 | procedure DeleteRoom(RoomIndex: Integer);
|
---|
141 | procedure AddMessage(RoomIndex: Integer; const Args: array of const; EventType: TAppEventType; TextColor: TColor = clSysMessage; Nick: string = '');
|
---|
142 | procedure DeleteOfflineUsers;
|
---|
143 | procedure UpdateUser(User: TUser);
|
---|
144 | constructor Create(AOwner: TComponent); override;
|
---|
145 | procedure SendCommand(Command, Text: string; DestinationIP: string = ''; DestinationID: Integer = 0);
|
---|
146 | procedure StartNetwork;
|
---|
147 | destructor Done;
|
---|
148 | property Connected: Boolean read FConnected;
|
---|
149 | procedure LoadNetworkInterfaceList;
|
---|
150 | procedure SelectNetworkInterface(SelectedGUID: string);
|
---|
151 | published
|
---|
152 | property MaxRoomLines: Integer read FMaxRoomLines write SetMaxRoomLines;
|
---|
153 | property LocalIPAddress: string read LocalUser.IP write LocalUser.IP;
|
---|
154 | // property OnNickChange: TClassMethod read FOnNickChange write FOnNickChange;
|
---|
155 | property OnUserListChange: TClassMethod read FOnUserListChange write FOnUserListChange;
|
---|
156 | property OnAddMessage: TAddMessageMethod read FOnAddMessage write FOnAddMessage;
|
---|
157 | property OnChangeNetworkState: TClassMethod read FOnChangeNetworkState write FOnChangeNetworkState;
|
---|
158 | // property OnPingResponse: TClassMethod read FOnPingResponse write FOnPingResponse;
|
---|
159 | // property OnCallUp: TClassMethod read FOnCallUp write FOnCallUp;
|
---|
160 | property OnCommand: TClassMethod read FOnCommand write FOnCommand;
|
---|
161 | property OnRoomListChanged: TClassMethod read FOnRoomListChanged write FOnRoomListChanged;
|
---|
162 | end;
|
---|
163 |
|
---|
164 | var
|
---|
165 | SunriseChatCore: TSunriseChatCore;
|
---|
166 | GetLastInputInfo2: function(var plii: TLastInputInfo): BOOL; stdcall;
|
---|
167 |
|
---|
168 | implementation
|
---|
169 |
|
---|
170 | uses DateUtils, UMainWindow, StrUtils, IpHlpApi, IpTypes;
|
---|
171 |
|
---|
172 | {$R *.dfm}
|
---|
173 |
|
---|
174 | { TSunriseChatCore }
|
---|
175 |
|
---|
176 | function TSunriseChatCore.SecondsIdle: DWord;
|
---|
177 | var
|
---|
178 | liInfo: TLastInputInfo;
|
---|
179 | begin
|
---|
180 | // Only WinNT+
|
---|
181 | if Assigned(GetLastInputInfo2) then begin
|
---|
182 | liInfo.cbSize := SizeOf(TLastInputInfo) ;
|
---|
183 | GetLastInputInfo2(liInfo) ;
|
---|
184 | Result := (GetTickCount - liInfo.dwTime) DIV 1000;
|
---|
185 | end else Result:= 0;
|
---|
186 | // MainWindow.RichEdit1.Lines.Add(IntToStr(Result));
|
---|
187 | // SysUtils.Beep;
|
---|
188 | // Result:= IdleTrackerGetLastTickCount div 1000;
|
---|
189 | // Button1.Caption:= IntToStr(Result);
|
---|
190 | // Result:= 0;
|
---|
191 | end;
|
---|
192 |
|
---|
193 | constructor TSunriseChatCore.Create(AOwner: TComponent);
|
---|
194 | begin
|
---|
195 | inherited;
|
---|
196 |
|
---|
197 | // Try to load indirectly function GetLastInputInfo for compatibility with Win9x
|
---|
198 | LibHandle:= LoadLibrary('user32.dll');
|
---|
199 | if LibHandle = 0 then begin
|
---|
200 | GetLastInputInfo2:= nil;
|
---|
201 | end else begin
|
---|
202 | @GetLastInputInfo2:= GetProcAddress(LibHandle,'GetLastInputInfo');
|
---|
203 | if (@GetLastInputInfo2 = nil) then FreeLibrary(LibHandle);
|
---|
204 | end;
|
---|
205 |
|
---|
206 | with LocalUser do begin
|
---|
207 | OSVersion:= GetWindowsVersionStr;
|
---|
208 | OSUser:= cWindows.GetUserName;
|
---|
209 | Status:= usOnline;
|
---|
210 | HostName:= LocalHostName;
|
---|
211 | Uptime:= Now;
|
---|
212 | IP:= LocalIPAddress;
|
---|
213 | ID:= Application.Handle;
|
---|
214 | RoomName:= 'Všichni';
|
---|
215 | RoomType:= rtPublic;
|
---|
216 | end;
|
---|
217 | LocalUser.CoreVersion:= CoreVersion;
|
---|
218 | SetLength(RoomList,1);
|
---|
219 | with RoomList[0] do begin
|
---|
220 | Name:= 'Všichni';
|
---|
221 | Typ:= rtPublic;
|
---|
222 | // AddMessage(0,'Vítejte v SunriseChatu!');
|
---|
223 | end;
|
---|
224 | (*
|
---|
225 | with RoomList[1] do begin
|
---|
226 | Name:= 'George';
|
---|
227 | Typ:= rtPrivate;
|
---|
228 | ActiveRoomIndex:= 1;
|
---|
229 | //AddMessage(1,'Test');
|
---|
230 | end;
|
---|
231 | *)
|
---|
232 | end;
|
---|
233 |
|
---|
234 | destructor TSunriseChatCore.Done;
|
---|
235 | begin
|
---|
236 |
|
---|
237 | end;
|
---|
238 |
|
---|
239 | procedure TSunriseChatCore.ExecuteCommand(Text: string);
|
---|
240 | var
|
---|
241 | RemoteUser: TUser;
|
---|
242 | ProtocolVersion: Integer;
|
---|
243 | DestinationIP: string;
|
---|
244 | DestinationID: Integer;
|
---|
245 | Seq: Integer;
|
---|
246 | Command: string;
|
---|
247 | Data: string;
|
---|
248 | NewNick: string;
|
---|
249 | I: Integer;
|
---|
250 | IdleTime2: Integer;
|
---|
251 |
|
---|
252 | function Parse: string;
|
---|
253 | begin
|
---|
254 | Result:= Copy(Text,1,Pos('|',Text)-1);
|
---|
255 | Delete(Text,1,Length(Result)+1);
|
---|
256 | end;
|
---|
257 |
|
---|
258 | begin
|
---|
259 | // OnAddMessage(Text,clSysMessage);
|
---|
260 | //AddMessage(Command);
|
---|
261 | with SunriseChatCore, RemoteUser do try
|
---|
262 | ProtocolVersion:= StrToInt(Parse);
|
---|
263 | case ProtocolVersion of
|
---|
264 | 1: begin
|
---|
265 | Client:= Parse;
|
---|
266 | ClientVersion:= Parse;
|
---|
267 | Nick:= Parse;
|
---|
268 | OSVersion:= Parse;
|
---|
269 | ID:= StrToInt(Parse);
|
---|
270 | Color:= StrToInt(Parse);
|
---|
271 | Uptime:= StrToDateTime(Parse);
|
---|
272 | IP:= Parse;
|
---|
273 | HostName:= Parse;
|
---|
274 | Command:= Parse;
|
---|
275 | Data:= Parse;
|
---|
276 | if Command = 'Message' then begin
|
---|
277 | // if not BlockMessages then OnAddMessage('(Nepodporovaná verze) <'+Nick+'> '+Data,Color);
|
---|
278 | end else
|
---|
279 | end;
|
---|
280 | 2: begin
|
---|
281 | DestinationIP:= Parse; // Destination IP
|
---|
282 | DestinationID:= StrToInt(Parse); // Destination ID
|
---|
283 | IP:= Parse; // Source IP
|
---|
284 | ID:= StrToInt(Parse); // Source ID
|
---|
285 | Seq:= StrToInt(Parse); // sequence command number
|
---|
286 |
|
---|
287 | // Load remote user data
|
---|
288 | I:= 0;
|
---|
289 | while (I<Length(UserList)) and ((UserList[I].IP<>IP) or (UserList[I].ID<>ID)) do I:= I + 1;
|
---|
290 | if I<Length(UserList) then begin
|
---|
291 | RemoteUser:= UserList[I];
|
---|
292 | end else Sequence:= Seq-1;
|
---|
293 | if Seq<>(RemoteUser.Sequence+1) then ErrorCount:= ErrorCount + 1;
|
---|
294 | Sequence:= Seq;
|
---|
295 | UpdateUser(RemoteUser);
|
---|
296 |
|
---|
297 | if ((DestinationIP = LocalUser.IP) and (DestinationID = LocalUser.ID)) or (DestinationIP='') then begin
|
---|
298 |
|
---|
299 | Command:= Parse; // Command
|
---|
300 | if Command = 'Message' then begin
|
---|
301 | Color:= StrToInt(Parse);
|
---|
302 | LastMessage:= Parse;
|
---|
303 | RoomName:= Parse;
|
---|
304 | RoomType:= TRoomType(StrToInt(Parse));
|
---|
305 |
|
---|
306 | // Search room
|
---|
307 | I:= 0;
|
---|
308 | while (I<Length(RoomList)) and (RoomList[I].Name<>RoomName) do I:= I + 1;
|
---|
309 | if (RoomType = rtPublic) and (I=Length(RoomList)) then begin
|
---|
310 | SetLength(RoomList,Length(RoomList)+1);
|
---|
311 | with RoomList[High(RoomList)] do begin
|
---|
312 | Name:= RoomName;
|
---|
313 | Typ:= RoomType;
|
---|
314 | SetLength(Lines,FMaxRoomLines);
|
---|
315 | StartLine:= 0;
|
---|
316 | Count:= 0;
|
---|
317 | end;
|
---|
318 | if Assigned(FOnRoomListChanged) then FOnRoomListChanged;
|
---|
319 | end;
|
---|
320 |
|
---|
321 | UpdateUser(RemoteUser);
|
---|
322 | if (I<Length(RoomList)) and not BlockMessages then begin
|
---|
323 | AddMessage(I, [RemoteUser.Nick, LastMessage], aeCommonMessage,Color,Nick);
|
---|
324 | end;
|
---|
325 | end else
|
---|
326 | if Command = 'CreateRoom' then begin
|
---|
327 | RoomName:= Parse;
|
---|
328 | RoomType:= TRoomType(StrToInt(Parse));
|
---|
329 | //ShowMessage(LocalUser.IP+','+IP+' '+IntToStr(LocalUser.ID)+','+IntToStr(ID));
|
---|
330 | if (RoomType = rtPublic) or ((RoomType = rtPrivate) and (LocalUser.IP = DestinationIP) and (LocalUser.ID = DestinationID)) then begin
|
---|
331 | // Search room
|
---|
332 | I:= 0;
|
---|
333 | while (I<Length(RoomList)) and (RoomList[I].Name<>RoomName) do I:= I + 1;
|
---|
334 | if I<Length(RoomList) then
|
---|
335 | else begin
|
---|
336 | SetLength(RoomList,Length(RoomList)+1);
|
---|
337 | with RoomList[High(RoomList)] do begin
|
---|
338 | Name:= RoomName;
|
---|
339 | Typ:= RoomType;
|
---|
340 | SetLength(Lines,FMaxRoomLines);
|
---|
341 | StartLine:= 0;
|
---|
342 | Count:= 0;
|
---|
343 | end;
|
---|
344 | end;
|
---|
345 | //ActiveRoomIndex:= I;
|
---|
346 | if Assigned(FOnRoomListChanged) then FOnRoomListChanged;
|
---|
347 | AddMessage(riAll, [RemoteUser.Nick, RoomName] ,aeCreateRoom);
|
---|
348 | end;
|
---|
349 | end else
|
---|
350 | if Command = 'LeaveRoom' then begin
|
---|
351 | RoomName:= Parse;
|
---|
352 |
|
---|
353 | // Search room
|
---|
354 | I:= 0;
|
---|
355 | while (I<Length(RoomList)) and (RoomList[I].Name<>RoomName) do I:= I + 1;
|
---|
356 | if I<Length(RoomList) then
|
---|
357 | AddMessage(riAll, [RemoteUser.Nick, RoomName], aeLeaveRoom);
|
---|
358 | end else
|
---|
359 | if Command = 'Connect' then begin
|
---|
360 | Nick:= Parse;
|
---|
361 | NickTime:= StrToDateTime(Parse);
|
---|
362 | if (LocalUser.IP<>IP) or (LocalUser.ID<>ID) then
|
---|
363 | AddMessage(riAll,[Nick, HostName], aeUserConnect);
|
---|
364 | SendCommand('UserInfo','');
|
---|
365 | UpdateUser(RemoteUser);
|
---|
366 | end else
|
---|
367 | if Command = 'Disconnect' then begin
|
---|
368 | AddMessage(riAll,[Nick],aeUserDisconnect);
|
---|
369 |
|
---|
370 | // Delete disconnected user
|
---|
371 | I:= 0;
|
---|
372 | while (I<Length(UserList)) and ((UserList[I].IP <> RemoteUser.IP) or (UserList[I].ID <> RemoteUser.ID)) do I:= I + 1;
|
---|
373 | if I < Length(UserList) then begin
|
---|
374 | UserList[I]:= UserList[High(UserList)];
|
---|
375 | SetLength(UserList,High(UserList));
|
---|
376 | end;
|
---|
377 | if Assigned(OnUserListChange) then OnUserListChange;
|
---|
378 | end else
|
---|
379 | if Command = 'GoAway' then begin
|
---|
380 | Reason:= Parse;
|
---|
381 | Status:= usAway;
|
---|
382 | AddMessage(riAll, [Nick, Reason], aeUserGoAway);
|
---|
383 | UpdateUser(RemoteUser);
|
---|
384 | end else
|
---|
385 | if Command = 'GoOnline' then begin
|
---|
386 | Status:= usOnline;
|
---|
387 | AddMessage(riAll, [Nick], aeUserGoBack);
|
---|
388 | UpdateUser(RemoteUser);
|
---|
389 | end else
|
---|
390 | if Command = 'CallUp' then begin
|
---|
391 | if not BlockMessages then AddMessage(riAll, [Nick], aeReceiveCallUp);
|
---|
392 | end else
|
---|
393 | if Command = 'Ping' then begin
|
---|
394 | SendCommand('PingResponse',Parse,IP,ID);
|
---|
395 | end else
|
---|
396 | if Command = 'PingResponse' then begin
|
---|
397 | AddMessage(riAll,[Nick,TimeToStr(Now-StrToTime(Parse))],aePingResponse);
|
---|
398 | end else
|
---|
399 | if Command = 'Alive' then begin
|
---|
400 | Delay:= Now-LastTime;
|
---|
401 | LastTime:= Now;
|
---|
402 | if not TryStrToInt(Parse,IdleTime2) then IdleTime2:= 0;
|
---|
403 | if (IdleTime2 > AutoAwayIdleTime*60) and (IdleTime < AutoAwayIdleTime*60) and (Status = usOnline) then begin
|
---|
404 | AddMessage(riAll,[Nick, IntToStr(AutoAwayIdleTime)], aeUserAutoGoAway);
|
---|
405 | end;
|
---|
406 | if (IdleTime > AutoAwayIdleTime*60) and (IdleTime2 < AutoAwayIdleTime*60) and (Status = usOnline) then begin
|
---|
407 | AddMessage(riAll, [Nick, IntToStr(IdleTime div 60)], aeUserAutoGoBack);
|
---|
408 | end;
|
---|
409 | IdleTime:= IdleTime2;
|
---|
410 | UpdateUser(RemoteUser);
|
---|
411 | end else
|
---|
412 | if Command = 'WhoIs' then begin
|
---|
413 | SendCommand('UserInfo','');
|
---|
414 | end else
|
---|
415 | if Command = 'UserInfo' then begin
|
---|
416 | NewNick:= Parse;
|
---|
417 | if (NewNick <> Nick) and (NickTime<>0) then AddMessage(riAll, [Nick, NewNick], aeUserChangeNick);
|
---|
418 | Nick:= NewNick;
|
---|
419 | NickTime:= StrToDateTime(Parse);
|
---|
420 | if (HostName='') and (LastTime<>0) then AddMessage(riAll, [RemoteUser.Nick], aeUserRestore);
|
---|
421 | Reason:= Parse;
|
---|
422 | Status:= Parse;
|
---|
423 | HostName:= Parse;
|
---|
424 | OSVersion:= Parse;
|
---|
425 | OSUser:= Parse;
|
---|
426 | Uptime:= StrToDateTime(Parse);
|
---|
427 | Client:= Parse;
|
---|
428 | ClientVersion:= Parse;
|
---|
429 | CoreVersion:= Parse;
|
---|
430 | if Length(Text)>0 then begin
|
---|
431 | LocalSystemTime:= StrToDateTime(Parse);
|
---|
432 | end;
|
---|
433 | DetailInfo:= Parse;
|
---|
434 |
|
---|
435 | UserInfoTime:= Now;
|
---|
436 |
|
---|
437 | // Nick conflict test
|
---|
438 | if (LocalUser.Nick = Nick) and ((LocalUser.IP <> IP) or (LocalUser.ID <> ID)) then begin
|
---|
439 | if LocalUser.NickTime > NickTime then begin
|
---|
440 | // Set nick to Host(Guest) n
|
---|
441 | if Copy(LocalUser.Nick,1,4) = 'Host' then begin
|
---|
442 | if TryStrToInt(Copy(LocalUser.Nick,5,255),I) then I:= I + 1 else I:= 1;
|
---|
443 | end else I:= 1;
|
---|
444 | ChangeNick('Host' + IntToStr(I), False);
|
---|
445 | AddMessage(riAll, [LocalUser.Nick], aeUserChangeNickConflict);
|
---|
446 | end else SendCommand('UserInfo','');
|
---|
447 | end;
|
---|
448 | UpdateUser(RemoteUser);
|
---|
449 | end;
|
---|
450 | if Nick='' then SendCommand('WhoIs','',IP,ID);
|
---|
451 | end;
|
---|
452 | end;
|
---|
453 | end;
|
---|
454 | except
|
---|
455 | end;
|
---|
456 | end;
|
---|
457 |
|
---|
458 | function UserIdleTime: Integer;
|
---|
459 | begin
|
---|
460 | end;
|
---|
461 |
|
---|
462 | procedure TSunriseChatCore.SendCommand(Command, Text: string; DestinationIP: string = ''; DestinationID: Integer = 0);
|
---|
463 | var
|
---|
464 | Data: string;
|
---|
465 |
|
---|
466 | procedure AddPart(Part: string);
|
---|
467 | begin
|
---|
468 | Data:= Data + Part + '|';
|
---|
469 | end;
|
---|
470 |
|
---|
471 | begin
|
---|
472 | if FConnected and (LocalUser.Status <> usInvisible) then begin
|
---|
473 | //if not NoResloveHostName then
|
---|
474 | Data:= '';
|
---|
475 | with LocalUser do begin
|
---|
476 | AddPart(IntToStr(ProtocolVersion));// Version of protocol
|
---|
477 | AddPart(DestinationIP); // Destination IP
|
---|
478 | AddPart(IntToStr(DestinationID)); // Destination ID
|
---|
479 | AddPart(IP); // Source IP
|
---|
480 | AddPart(IntToStr(ID)); // Source ID
|
---|
481 | Sequence:= Sequence + 1;
|
---|
482 | AddPart(IntToStr(Sequence)); // Sequence command number
|
---|
483 | AddPart(Command); // Command
|
---|
484 | if Command = 'Message' then begin
|
---|
485 | AddPart(IntToStr(Color)); // User text color
|
---|
486 | AddPart(Text); // Command data
|
---|
487 | AddPart(RoomList[ActiveRoomIndex].Name); // Room name
|
---|
488 | AddPart(IntToStr(Integer(RoomList[ActiveRoomIndex].Typ))); // Public or private room
|
---|
489 | end else
|
---|
490 | if Command = 'Connect' then begin
|
---|
491 | AddPart(Nick);
|
---|
492 | AddPart(DateTimeToStr(NickTime));
|
---|
493 | end else
|
---|
494 | if Command = 'Disconnect' then begin
|
---|
495 | end else
|
---|
496 | if Command = 'GoAway' then begin
|
---|
497 | AddPart(Reason); // Away mode reason
|
---|
498 | end else
|
---|
499 | if Command = 'GoOnline' then begin
|
---|
500 | end else
|
---|
501 | if Command = 'GoAutoAway' then begin
|
---|
502 | end else
|
---|
503 | if Command = 'GoAutoOnline' then begin
|
---|
504 | end else
|
---|
505 | if Command = 'CallUp' then begin
|
---|
506 | end else
|
---|
507 | if Command = 'CallUpResponse' then begin
|
---|
508 | end else
|
---|
509 | if Command = 'Ping' then begin
|
---|
510 | AddPart(TimeToStr(Now)); // Send time
|
---|
511 | end else
|
---|
512 | if Command = 'PingResponse' then begin
|
---|
513 | AddPart(Text); // Send time
|
---|
514 | end else
|
---|
515 | if Command = 'Alive' then begin
|
---|
516 | AddPart(IntToStr(SecondsIdle));
|
---|
517 | end else
|
---|
518 | if Command = 'WhoIs' then begin
|
---|
519 | end else
|
---|
520 | if Command = 'CreateRoom' then begin
|
---|
521 | AddPart(RoomName); // Room name
|
---|
522 | AddPart(IntToStr(Integer(RoomType))); // Public or private room
|
---|
523 | end else
|
---|
524 | if Command = 'LeaveRoom' then begin
|
---|
525 | AddPart(RoomList[ActiveRoomIndex].Name); // Room name
|
---|
526 | end else
|
---|
527 | if Command = 'UserInfo' then begin
|
---|
528 | AddPart(Nick); // User name
|
---|
529 | AddPart(DateTimeToStr(NickTime)); // User name time
|
---|
530 | AddPart(Reason); // Away mode reason
|
---|
531 | AddPart(Status); // User status
|
---|
532 | AddPart(HostName); // Local host name
|
---|
533 | AddPart(OSVersion); // OS version
|
---|
534 | AddPart(OSUser); // Logged user
|
---|
535 | AddPart(DateTimeToStr(Uptime)); // Application uptime
|
---|
536 | AddPart(Client); // Name of client application
|
---|
537 | AddPart(ClientVersion); // Version of application
|
---|
538 | AddPart(CoreVersion); // SunriseChatCoreVersion
|
---|
539 | AddPart(DateTimeToStr(Now)); // Local system time
|
---|
540 | AddPart(DetailInfo); // Detailed info about user
|
---|
541 | end;
|
---|
542 | end;
|
---|
543 | fndTCPClient1.Socket.SendStr(Data+#13);
|
---|
544 | end;
|
---|
545 | end;
|
---|
546 |
|
---|
547 | procedure TSunriseChatCore.fndTCPServer1DataAvailable(Sender: TTCPServerClient);
|
---|
548 | var
|
---|
549 | Text: string;
|
---|
550 | begin
|
---|
551 | if Sender.Socket.InBufferSize>0 then begin
|
---|
552 | Text:= Sender.Socket.ReadAvailable;
|
---|
553 | if BroadcastType = btGlobal then
|
---|
554 | fndUDPClientSocket1.Broadcast(IntToStr(UDPPort), Text) else
|
---|
555 | fndUDPClientSocket1.SendStr(Text);
|
---|
556 | end;
|
---|
557 | end;
|
---|
558 |
|
---|
559 | procedure TSunriseChatCore.fndTCPClient1ConnectFailed(Sender: ATCPClient);
|
---|
560 | begin
|
---|
561 | // ShowMessage(Sender.Socket.ErrorMessage);
|
---|
562 | end;
|
---|
563 |
|
---|
564 | procedure TSunriseChatCore.fndTCPClient1DataAvailable(Sender: ATCPClient);
|
---|
565 | var
|
---|
566 | Text: string;
|
---|
567 | begin
|
---|
568 | if Sender.Socket.InBufferSize > 0 then begin
|
---|
569 | InputBuffer := InputBuffer + Sender.Socket.ReadAvailable;
|
---|
570 | while Pos(#13, InputBuffer) > 0 do begin
|
---|
571 | Text := Copy(InputBuffer, 1, Pos(#13, InputBuffer) - 1);
|
---|
572 | Delete(InputBuffer, 1, Length(Text) + 1);
|
---|
573 | ExecuteCommand(Text);
|
---|
574 | end;
|
---|
575 | end;
|
---|
576 | end;
|
---|
577 |
|
---|
578 | procedure TSunriseChatCore.fndUDPClientSocket1DataAvailable(
|
---|
579 | Sender: AUDPSocket);
|
---|
580 | var
|
---|
581 | Text: string;
|
---|
582 | Address : TSockAddr;
|
---|
583 | I: Integer;
|
---|
584 | LocalIPs: TInAddrArray;
|
---|
585 | begin
|
---|
586 | if FConnected then begin
|
---|
587 | Sender.ReadPacket(Text,Address);
|
---|
588 |
|
---|
589 | // ShowMessage(Text);
|
---|
590 | for I:= 0 to fndTCPServer1.ClientCount-1 do
|
---|
591 | with fndTCPServer1.Client[I] do Socket.SendStr(Text);
|
---|
592 | end;
|
---|
593 | end;
|
---|
594 |
|
---|
595 | procedure TSunriseChatCore.fndTCPClient1Close(Sender: ATCPClient);
|
---|
596 | begin
|
---|
597 | // ShowMessage('TCPClient close');
|
---|
598 | FConnected := False;
|
---|
599 | Timer1.Enabled:= True;
|
---|
600 | if Assigned(FOnChangeNetworkState) then FOnChangeNetworkState;
|
---|
601 | end;
|
---|
602 |
|
---|
603 | procedure TSunriseChatCore.StartNetwork;
|
---|
604 | var
|
---|
605 | I, II: Integer;
|
---|
606 | const
|
---|
607 | Stav: array [0..6] of string = ('Closed', 'Resolving', 'Resolved', 'Connecting',
|
---|
608 | 'Negotiating', 'Connected', 'Listening');
|
---|
609 | begin
|
---|
610 | fndTCPClient1.OnClose:= nil;
|
---|
611 | Timer1.Enabled:= False;
|
---|
612 | FConnected:= False;
|
---|
613 | fndTCPClient1.Active:= False;
|
---|
614 | with fndTCPServer1 do begin
|
---|
615 | Active:= False;
|
---|
616 | ListenPort:= IntToStr(UDPPort+1);
|
---|
617 | LocalHost:= LocalUser.IP; //'localhost';
|
---|
618 | try
|
---|
619 | Active:= True;
|
---|
620 | except
|
---|
621 | end;
|
---|
622 | // ShowMessage(Stav[Integer(fndTCPServer1.Socket.State)]);
|
---|
623 |
|
---|
624 | fndUDPClientSocket1.Terminate;
|
---|
625 | fndUDPClientSocket1.LocalHost:= LocalUser.IP;
|
---|
626 | fndUDPClientSocket1.LocalPort:= IntToStr(UDPPort);
|
---|
627 | fndUDPClientSocket1.Host:= NetworkInterfaces[NetworkInterfaceIndex].BroadcastIPAddress;
|
---|
628 | fndUDPClientSocket1.Port:= IntToStr(UDPPort);
|
---|
629 | fndUDPClientSocket1.BroadcastOption:= True;
|
---|
630 | try
|
---|
631 | fndUDPClientSocket1.Bind;
|
---|
632 | except
|
---|
633 | // on EWinSock do begin
|
---|
634 | // ShowMessage('Nelze inicializovat síť!');
|
---|
635 | // Application.Terminate;
|
---|
636 | // end;
|
---|
637 | end;
|
---|
638 | end;
|
---|
639 | with fndTCPClient1 do begin
|
---|
640 | Active:= False;
|
---|
641 | Host:= LocalUser.IP; // 'localhost';
|
---|
642 | Port:= IntToStr(UDPPort+1);
|
---|
643 | LocalHost:= LocalUser.IP; //'localhost';
|
---|
644 | I:= 2;
|
---|
645 | repeat
|
---|
646 | Active:= False;
|
---|
647 | LocalPort:= IntToStr(UDPPort+I);
|
---|
648 | I:= I + 1;
|
---|
649 | try
|
---|
650 | Active:= True;
|
---|
651 | except
|
---|
652 | end;
|
---|
653 | II:= 0;
|
---|
654 | while (Socket.State in [ssResolving, ssNegotiating, ssConnecting]) and (II<100) do begin
|
---|
655 | Application.ProcessMessages;
|
---|
656 | //Sleep(10);
|
---|
657 | II:= II + 1;
|
---|
658 | end;
|
---|
659 | // ShowMessage(Stav[Integer(fndTCPClient1.Socket.State)]);
|
---|
660 | until (Socket.State in [ssConnected, ssResolved]) or (I>30); //or (fndTCPServer1.Socket.State = ssClosed);
|
---|
661 | FConnected := not (fndUDPClientSocket1.Bound xor (fndTCPServer1.Socket.State = ssListening)) and
|
---|
662 | (fndTCPClient1.Socket.State in [ssConnected, ssResolved]);
|
---|
663 | //ShowMessage(IntToStr(Integer(fndTCPClient1.Socket.State))+','+BoolToStr(fndUDPClientSocket1.Bound)
|
---|
664 | //+','+BoolToStr(FConnected)+','+BoolToStr(fndTCPClient1.Socket.Connected));
|
---|
665 | if FConnected then begin
|
---|
666 | SunriseChatCore.SendCommand('UserInfo','');
|
---|
667 | SunriseChatCore.SendCommand('Connect','');
|
---|
668 | end;
|
---|
669 | if Assigned(FOnChangeNetworkState) then OnChangeNetworkState;
|
---|
670 | end;
|
---|
671 | Timer1.Enabled := True;
|
---|
672 | fndTCPClient1.OnClose:= fndTCPClient1Close;
|
---|
673 | end;
|
---|
674 |
|
---|
675 | procedure TSunriseChatCore.Timer1Timer(Sender: TObject);
|
---|
676 | begin
|
---|
677 | // Timer1.Enabled := False;
|
---|
678 | // if fndUDPClientSocket1.State
|
---|
679 | if not FConnected then StartNetwork;
|
---|
680 | if FConnected and (HourOf(Now) <> LastHour) then begin
|
---|
681 | LastHour:= HourOf(Now);
|
---|
682 | AddMessage(riAll,[HourOf(Now),MinuteOf(Now)], aeShowHours);
|
---|
683 | end;
|
---|
684 | // Timer1.Enabled := True;
|
---|
685 | end;
|
---|
686 |
|
---|
687 | procedure TSunriseChatCore.Init;
|
---|
688 | begin
|
---|
689 | StartNetwork;
|
---|
690 | end;
|
---|
691 |
|
---|
692 | function TSunriseChatCore.GetWindowsVersionStr: string;
|
---|
693 | begin
|
---|
694 | case Win32Platform of
|
---|
695 | 1: case Win32MajorVersion of
|
---|
696 | 4: case Win32MinorVersion of
|
---|
697 | 0: Result:= '95';
|
---|
698 | 10: Result:= '98';
|
---|
699 | 90: Result:= 'Me';
|
---|
700 | end;
|
---|
701 | end;
|
---|
702 | 2: case Win32MajorVersion of
|
---|
703 | 4: case Win32MinorVersion of
|
---|
704 | 0: Result:= 'NT 4.0';
|
---|
705 | end;
|
---|
706 | 5: case Win32MinorVersion of
|
---|
707 | 0: Result:= '2000';
|
---|
708 | 1: Result:= 'XP';
|
---|
709 | 2: Result:= 'Server 2003';
|
---|
710 | end;
|
---|
711 | 6: case Win32MinorVersion of
|
---|
712 | 0: Result := 'Vista';
|
---|
713 | end;
|
---|
714 | end;
|
---|
715 | end;
|
---|
716 | Result:= 'Windows ' + Result;
|
---|
717 | end;
|
---|
718 |
|
---|
719 | procedure TSunriseChatCore.DeleteOfflineUsers;
|
---|
720 | var
|
---|
721 | I: Integer;
|
---|
722 | Changed: Boolean;
|
---|
723 | begin
|
---|
724 | I:= 0;
|
---|
725 | Changed:= False;
|
---|
726 | while (I<Length(UserList)) do begin
|
---|
727 | if (Now - UserList[I].LastTime)>RemoveTimeout then begin
|
---|
728 | AddMessage(riAll, [UserList[I].Nick], aeUserTimeout);
|
---|
729 | UserList[I]:= UserList[High(UserList)];
|
---|
730 | SetLength(UserList,High(UserList));
|
---|
731 | Changed:= True;
|
---|
732 | end else I:= I + 1;
|
---|
733 | end;
|
---|
734 | if Changed and Assigned(FOnUserListChange) then FOnUserListChange;
|
---|
735 | // TSocketState
|
---|
736 | end;
|
---|
737 |
|
---|
738 | procedure TSunriseChatCore.UpdateUser(User: TUser);
|
---|
739 | var
|
---|
740 | I: Integer;
|
---|
741 | begin
|
---|
742 | I:= 0;
|
---|
743 | while (I<Length(UserList)) and ((UserList[I].IP<>User.IP) or ((UserList[I].ID<>User.ID))) do I:= I + 1;
|
---|
744 | if I = Length(UserList) then begin
|
---|
745 | SetLength(UserList,Length(UserList)+1);
|
---|
746 | end;
|
---|
747 | User.LastTime:= Now;
|
---|
748 | UserList[I]:= User;
|
---|
749 | LastUserIndex:= I;
|
---|
750 | if Assigned(FOnUserListChange) then FOnUserListChange;
|
---|
751 | end;
|
---|
752 |
|
---|
753 | procedure TSunriseChatCore.Timer2Timer(Sender: TObject);
|
---|
754 | begin
|
---|
755 | // MainWindow.Label1.Caption:= IntToStr(Integer(fndTCPClient1.Socket.State));
|
---|
756 | SendCommand('Alive', '');
|
---|
757 | // MainWindow.Label3.Caption := IntToStr(StrToInt(MainWindow.Label3.Caption) + 1);
|
---|
758 | DeleteOfflineUsers;
|
---|
759 | end;
|
---|
760 |
|
---|
761 | procedure TSunriseChatCore.AddMessage(RoomIndex: Integer; const Args: array of const; EventType: TAppEventType; TextColor: TColor = clSysMessage; Nick: string = '');
|
---|
762 | var
|
---|
763 | I: Integer;
|
---|
764 | begin
|
---|
765 | if Assigned(OnAddMessage) then OnAddMessage(RoomIndex, Args, EventType, TextColor, Nick);
|
---|
766 |
|
---|
767 | if (LastMessage<>'') and (RoomIndex < Length(RoomList)) then begin
|
---|
768 | if RoomIndex = riAll then begin
|
---|
769 | for RoomIndex := 0 to High(RoomList) do with RoomList[RoomIndex] do begin
|
---|
770 | Count := Count + 1;
|
---|
771 | if Count > FMaxRoomLines then begin
|
---|
772 | StartLine := (StartLine + 1) mod FMaxRoomLines;
|
---|
773 | Count := FMaxRoomLines;
|
---|
774 | end;
|
---|
775 | I := (StartLine + Count - 1) mod FMaxRoomLines;
|
---|
776 | Lines[I].Text := LastMessage;
|
---|
777 | Lines[I].Font := LastFont;
|
---|
778 | Lines[I].Time := Now;
|
---|
779 | Lines[I].Nick := Nick;
|
---|
780 | end;
|
---|
781 | end else with RoomList[RoomIndex] do begin
|
---|
782 | Count := Count + 1;
|
---|
783 | if Count > FMaxRoomLines then begin
|
---|
784 | StartLine := (StartLine + 1) mod FMaxRoomLines;
|
---|
785 | Count := FMaxRoomLines;
|
---|
786 | end;
|
---|
787 | I := (StartLine + Count - 1) mod FMaxRoomLines;
|
---|
788 | Lines[I].Text := LastMessage;
|
---|
789 | Lines[I].Font := LastFont;
|
---|
790 | Lines[I].Time := Now;
|
---|
791 | Lines[I].Nick := Nick;
|
---|
792 | end;
|
---|
793 | end;
|
---|
794 | end;
|
---|
795 |
|
---|
796 | procedure TSunriseChatCore.DeleteRoom(RoomIndex: Integer);
|
---|
797 | begin
|
---|
798 | RoomList[RoomIndex]:= RoomList[High(RoomList)];
|
---|
799 | SetLength(RoomList,High(RoomList));
|
---|
800 | FOnRoomListChanged;
|
---|
801 | end;
|
---|
802 |
|
---|
803 | procedure TSunriseChatCore.ChangeNick(NewNick: string; SendCmd: Boolean = True);
|
---|
804 | begin
|
---|
805 | with SunriseChatCore do begin
|
---|
806 | LocalUser.NickTime:= Now;
|
---|
807 | LocalUser.Nick:= NewNick;
|
---|
808 | SendCommand('UserInfo','');
|
---|
809 | end;
|
---|
810 | end;
|
---|
811 |
|
---|
812 | procedure TSunriseChatCore.SetMaxRoomLines(Number: Integer);
|
---|
813 | var
|
---|
814 | I: Integer;
|
---|
815 | begin
|
---|
816 | FMaxRoomLines:= Number;
|
---|
817 | for I:= 0 to High(RoomList) do with RoomList[I] do begin
|
---|
818 | SetLength(Lines,Number);
|
---|
819 | StartLine:= 0;
|
---|
820 | Count:= 0;
|
---|
821 | end;
|
---|
822 | end;
|
---|
823 |
|
---|
824 | procedure TSunriseChatCore.DataModuleCreate(Sender: TObject);
|
---|
825 | begin
|
---|
826 | LastHour:= HourOf(Now);
|
---|
827 | LoadNetworkInterfaceList;
|
---|
828 | end;
|
---|
829 |
|
---|
830 | procedure TSunriseChatCore.LoadNetworkInterfaceList;
|
---|
831 | var
|
---|
832 | I, II: Integer;
|
---|
833 | Status: Cardinal;
|
---|
834 | AdaptersList : array of IP_ADAPTER_INFO;
|
---|
835 | BufSize: Cardinal;
|
---|
836 | IPParts: TArrayOfString;
|
---|
837 | SubnetParts: TArrayOfString;
|
---|
838 |
|
---|
839 | function IpListToStr(pIpAddr : PIP_ADDR_STRING) : String;
|
---|
840 | begin
|
---|
841 | Result := '';
|
---|
842 | repeat
|
---|
843 | Result := Result + ', ' + Pchar(Addr(pIpAddr^.IpAddress));
|
---|
844 | pIpAddr := pIpAddr.Next;
|
---|
845 | until pIpAddr = nil;
|
---|
846 | Delete(Result, 1, 2);
|
---|
847 | if Result = '' then Result := 'none';
|
---|
848 | end;
|
---|
849 |
|
---|
850 | begin
|
---|
851 | SetLength(NetworkInterfaces,0); // Clear list
|
---|
852 | if Win32Platform > 1 then begin
|
---|
853 | BufSize := 0;
|
---|
854 | Status := GetAdaptersInfo(@AdaptersList[0], BufSize);
|
---|
855 | SetLength(AdaptersList, BufSize div SizeOf(IP_ADAPTER_INFO));
|
---|
856 | SetLength(NetworkInterfaces, Length(AdaptersList));
|
---|
857 | Status := GetAdaptersInfo(@AdaptersList[0], BufSize);
|
---|
858 | for I := 0 to High(AdaptersList) do with NetworkInterfaces[I], AdaptersList[I] do begin
|
---|
859 | // IPAddress := CurrentIpAddress^.IpAddress.s;
|
---|
860 | // SubNetMask := CurrentIpAddress^.IpMask.s;
|
---|
861 | IPAddress := IpAddressList.IPAddress.S;
|
---|
862 | SubNetMask := IpAddressList.IPMask.s;
|
---|
863 | GUID := AdapterName;
|
---|
864 | (*
|
---|
865 | II := MAX_ADAPTER_DESCRIPTION_LENGTH;
|
---|
866 | while Description[II] = #0 do Dec(II);
|
---|
867 | SetLength(Name, II);
|
---|
868 | Move(Description[0], Name[1], Length(Name));
|
---|
869 | *)
|
---|
870 | Name := Description;
|
---|
871 | SubnetParts := Explode('.', SubNetMask);
|
---|
872 | IPParts := Explode('.', IPAddress);
|
---|
873 | for II := 0 to 3 do
|
---|
874 | IPParts[II] := IntToStr(StrToInt(IPParts[II]) or (StrToInt(SubnetParts[II]) xor $ff));
|
---|
875 | BroadcastIPAddress := IPParts[0]+'.'+IPParts[1]+'.'+IPParts[2]+'.'+IPParts[3];
|
---|
876 | end;
|
---|
877 | // DisplayIfConf;
|
---|
878 | // NetworkInterfaces := GetNetworkAdapterList;
|
---|
879 | end else begin
|
---|
880 | // For Windows 9x compatibility
|
---|
881 | SetLength(NetworkInterfaces,Length(LocalIPAddressesStr));
|
---|
882 | for I:= 0 to High(LocalIPAddressesStr) do with NetworkInterfaces[I] do begin
|
---|
883 | IPAddress:= LocalIPAddressesStr[I];
|
---|
884 | Name:= LocalIPAddressesStr[I];
|
---|
885 | GUID:= LocalIPAddressesStr[I];
|
---|
886 | end;
|
---|
887 | end;
|
---|
888 | end;
|
---|
889 |
|
---|
890 | procedure TSunriseChatCore.SelectNetworkInterface(SelectedGUID: string);
|
---|
891 | var
|
---|
892 | I: Integer;
|
---|
893 | begin
|
---|
894 | I:= 0;
|
---|
895 | while (I<Length(NetworkInterfaces)) and (NetworkInterfaces[I].GUID <> SelectedGUID) do I:= I + 1;
|
---|
896 | if I<Length(NetworkInterfaces) then begin
|
---|
897 | NetworkInterfaceIndex:= I;
|
---|
898 | LocalUser.IP:= NetworkInterfaces[I].IPAddress;
|
---|
899 | end else begin
|
---|
900 | if Length(NetworkInterfaces)>0 then begin
|
---|
901 | NetworkInterfaceIndex:= 0;
|
---|
902 | LocalUser.IP:= NetworkInterfaces[0].IPAddress;
|
---|
903 | end else begin
|
---|
904 | NetworkInterfaceIndex:= 0;
|
---|
905 | LocalUser.IP:= '127.0.0.1';
|
---|
906 | end;
|
---|
907 | end;
|
---|
908 | StartNetwork;
|
---|
909 | end;
|
---|
910 |
|
---|
911 | function TSunriseChatCore.Explode(Separator: Char;
|
---|
912 | Data: string): TArrayOfString;
|
---|
913 | begin
|
---|
914 | SetLength(Result,0);
|
---|
915 | while Pos(Separator,Data)>0 do begin
|
---|
916 | SetLength(Result, Length(Result)+1);
|
---|
917 | Result[High(Result)]:= Copy(Data,1,Pos(Separator,Data)-1);
|
---|
918 | Delete(Data,1,Pos(Separator,Data));
|
---|
919 | end;
|
---|
920 | SetLength(Result, Length(Result)+1);
|
---|
921 | Result[High(Result)]:= Data;
|
---|
922 | end;
|
---|
923 |
|
---|
924 | procedure TSunriseChatCore.fndUDPClientSocket1Error(Sender: ASocket);
|
---|
925 | begin
|
---|
926 | // ShowMessage('UDPClient error');
|
---|
927 | end;
|
---|
928 |
|
---|
929 | procedure TSunriseChatCore.Timer3Timer(Sender: TObject);
|
---|
930 | begin
|
---|
931 | try
|
---|
932 | MainWindow.Caption := GetEnumName(TypeInfo(TSocketState), Integer(fndTCPClient1.Socket.State)) +
|
---|
933 | ','+GetEnumName(TypeInfo(TSocketState), Integer(fndUDPClientSocket1.State))+ BoolToStr(fndUDPClientSocket1.Bound);
|
---|
934 | finally
|
---|
935 | end;
|
---|
936 | end;
|
---|
937 |
|
---|
938 | end.
|
---|