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