1 | unit UMainForm;
|
---|
2 |
|
---|
3 | // Plnìní statistiky pro game-server
|
---|
4 |
|
---|
5 | interface
|
---|
6 |
|
---|
7 | uses
|
---|
8 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
|
---|
9 | Dialogs, StdCtrls, ExtCtrls, Registry, IdBaseComponent, IdComponent,
|
---|
10 | IdTCPConnection, IdTCPClient, IdHTTP, USqlDatabase, UAutoRegistry,
|
---|
11 | ComCtrls;
|
---|
12 |
|
---|
13 | type
|
---|
14 | TMainForm = class(TForm)
|
---|
15 | Timer1: TTimer;
|
---|
16 | Button1: TButton;
|
---|
17 | IdHTTP1: TIdHTTP;
|
---|
18 | Button2: TButton;
|
---|
19 | ListView1: TListView;
|
---|
20 | procedure Timer1Timer(Sender: TObject);
|
---|
21 | procedure FormActivate(Sender: TObject);
|
---|
22 | procedure FormCreate(Sender: TObject);
|
---|
23 | procedure Button1Click(Sender: TObject);
|
---|
24 | procedure FormDestroy(Sender: TObject);
|
---|
25 | procedure Button2Click(Sender: TObject);
|
---|
26 | private
|
---|
27 | function GetCPUUsage: Real;
|
---|
28 | { Private declarations }
|
---|
29 | public
|
---|
30 | started : boolean;
|
---|
31 | reg : TRegistry;
|
---|
32 | Database: TSqlDatabase;
|
---|
33 | StatServerURL: string;
|
---|
34 | DatabaseHostname: string;
|
---|
35 | DatabaseUserName: string;
|
---|
36 | DatabasePassword: string;
|
---|
37 | DatabaseDatabase: string;
|
---|
38 | //MangosFailure: string;
|
---|
39 | AutoRegistry: TAutoRegistry;
|
---|
40 | end;
|
---|
41 |
|
---|
42 | const
|
---|
43 | SystemBasicInformation = 0;
|
---|
44 | SystemPerformanceInformation = 2;
|
---|
45 | SystemTimeInformation = 3;
|
---|
46 |
|
---|
47 | type
|
---|
48 | TPDWord = ^DWORD;
|
---|
49 |
|
---|
50 | TSystem_Basic_Information = packed record
|
---|
51 | dwUnknown1: DWORD;
|
---|
52 | uKeMaximumIncrement: ULONG;
|
---|
53 | uPageSize: ULONG;
|
---|
54 | uMmNumberOfPhysicalPages: ULONG;
|
---|
55 | uMmLowestPhysicalPage: ULONG;
|
---|
56 | uMmHighestPhysicalPage: ULONG;
|
---|
57 | uAllocationGranularity: ULONG;
|
---|
58 | pLowestUserAddress: Pointer;
|
---|
59 | pMmHighestUserAddress: Pointer;
|
---|
60 | uKeActiveProcessors: ULONG;
|
---|
61 | bKeNumberProcessors: byte;
|
---|
62 | bUnknown2: byte;
|
---|
63 | wUnknown3: word;
|
---|
64 | end;
|
---|
65 |
|
---|
66 | type
|
---|
67 | TSystem_Performance_Information = packed record
|
---|
68 | liIdleTime: LARGE_INTEGER; {LARGE_INTEGER}
|
---|
69 | dwSpare: array[0..75] of DWORD;
|
---|
70 | end;
|
---|
71 |
|
---|
72 | type
|
---|
73 | TSystem_Time_Information = packed record
|
---|
74 | liKeBootTime: LARGE_INTEGER;
|
---|
75 | liKeSystemTime: LARGE_INTEGER;
|
---|
76 | liExpTimeZoneBias: LARGE_INTEGER;
|
---|
77 | uCurrentTimeZoneId: ULONG;
|
---|
78 | dwReserved: DWORD;
|
---|
79 | end;
|
---|
80 |
|
---|
81 | var
|
---|
82 | NtQuerySystemInformation: function(infoClass: DWORD;
|
---|
83 | buffer: Pointer;
|
---|
84 | bufSize: DWORD;
|
---|
85 | returnSize: TPDword): DWORD; stdcall = nil;
|
---|
86 |
|
---|
87 |
|
---|
88 | liOldIdleTime: LARGE_INTEGER = ();
|
---|
89 | liOldSystemTime: LARGE_INTEGER = ();
|
---|
90 |
|
---|
91 | MainForm: TMainForm;
|
---|
92 |
|
---|
93 | implementation
|
---|
94 |
|
---|
95 | uses UOptionsForm;
|
---|
96 |
|
---|
97 | {$R *.dfm}
|
---|
98 |
|
---|
99 |
|
---|
100 | const
|
---|
101 | // Sets UnixStartDate to TDateTime of 01/01/1970
|
---|
102 | UnixStartDate: TDateTime = 25569.0;
|
---|
103 |
|
---|
104 | function DateTimeToUnix(ConvDate: TDateTime): Longint;
|
---|
105 | begin
|
---|
106 | //example: DateTimeToUnix(now);
|
---|
107 | Result := Round((ConvDate - UnixStartDate) * 86400);
|
---|
108 | end;
|
---|
109 |
|
---|
110 | function UnixToDateTime(USec: Longint): TDateTime;
|
---|
111 | begin
|
---|
112 | //Example: UnixToDateTime(1003187418);
|
---|
113 | Result := (Usec / 86400) + UnixStartDate;
|
---|
114 | end;
|
---|
115 |
|
---|
116 | procedure TMainForm.Timer1Timer(Sender: TObject);
|
---|
117 | var
|
---|
118 | Status : TMemoryStatus;
|
---|
119 | UsedMemory: Cardinal;
|
---|
120 | WebFile: TextFile;
|
---|
121 | WoWUsers: string;
|
---|
122 | CpuUsage: Real;
|
---|
123 | WoWPlayers: Integer;
|
---|
124 | DbRows: TDbRows;
|
---|
125 | ListItem: TListItem;
|
---|
126 | MangosRestartCount: Integer;
|
---|
127 | DiskFreeSpace: Double;
|
---|
128 | MangosNewAccountCount: Integer;
|
---|
129 | I: Integer;
|
---|
130 | Asc: TAssocArray;
|
---|
131 | begin
|
---|
132 | with ListView1.Items do begin
|
---|
133 | BeginUpdate;
|
---|
134 | Clear;
|
---|
135 |
|
---|
136 | // Free memory
|
---|
137 | Status.dwLength := SizeOf(TMemoryStatus);
|
---|
138 | GlobalMemoryStatus(Status);
|
---|
139 | ListItem := Add;
|
---|
140 | ListItem.Caption := 'Celkem pamìti';
|
---|
141 | ListItem.SubItems.Add(IntToStr(Status.dwTotalPageFile div 1024 div 1024) + ' MB');
|
---|
142 | UsedMemory := (Status.dwTotalPageFile - Status.dwAvailPageFile) div 1024 div 1024;
|
---|
143 | ListItem := Add;
|
---|
144 | ListItem.Caption := 'Pouité pamìti';
|
---|
145 | ListItem.SubItems.Add(IntToStr(UsedMemory) + ' MB');
|
---|
146 | IdHTTP1.Get(StatServerURL + '?MeasureId=3&Value=' + IntToStr(UsedMemory));
|
---|
147 |
|
---|
148 | // CPU utilization
|
---|
149 | CpuUsage := GetCpuUsage;
|
---|
150 | ListItem := Add;
|
---|
151 | ListItem.Caption := 'Zatíení CPU';
|
---|
152 | ListItem.SubItems.Add(FormatFloat('0.0 %', CpuUsage));
|
---|
153 | IdHTTP1.Get(StatServerURL + '?MeasureId=4&Value=' + IntToStr(Round(CpuUsage)));
|
---|
154 |
|
---|
155 | // WoW players count
|
---|
156 | Database.Database := DatabaseDatabase;
|
---|
157 | DbRows := Database.Select('account', 'COUNT(*)', 'online=1');
|
---|
158 | if DbRows.Count = 1 then begin
|
---|
159 | WoWPlayers := StrToInt(DbRows[0].Values['COUNT(*)']);
|
---|
160 | end;
|
---|
161 | DbRows.Free;
|
---|
162 | ListItem := Add;
|
---|
163 | ListItem.Caption := 'Hráèù WoW';
|
---|
164 | ListItem.SubItems.Add(IntToStr(WoWPlayers));
|
---|
165 | IdHTTP1.Get(StatServerURL + '?MeasureId=5&Value=' + IntToStr(WoWPlayers));
|
---|
166 | // ShowMessage(Database.LastErrorMessage);
|
---|
167 |
|
---|
168 | // Mangos new account count
|
---|
169 | Database.Database := DatabaseDatabase;
|
---|
170 | DbRows := Database.Select('account', 'COUNT(*)', 'joindate > (NOW() - INTERVAL 1 DAY)');
|
---|
171 | if DbRows.Count = 1 then begin
|
---|
172 | MangosNewAccountCount := StrToInt(DbRows[0].Values['COUNT(*)']);
|
---|
173 | end;
|
---|
174 | DbRows.Free;
|
---|
175 | ListItem := Add;
|
---|
176 | ListItem.Caption := 'Nových registrací WoW';
|
---|
177 | ListItem.SubItems.Add(IntToStr(MangosNewAccountCount) + ' za den');
|
---|
178 | IdHTTP1.Get(StatServerURL + '?MeasureId=8&Value=' + IntToStr(MangosNewAccountCount));
|
---|
179 |
|
---|
180 | // Mangos restarts count
|
---|
181 | Database.Database := 'wow';
|
---|
182 | DbRows := Database.Select('mangos_restart', 'COUNT(*)', 'time > (NOW() - INTERVAL 1 DAY)');
|
---|
183 | if DbRows.Count = 1 then begin
|
---|
184 | MangosRestartCount := StrToInt(DbRows[0].Values['COUNT(*)']);
|
---|
185 | end;
|
---|
186 | DbRows.Free;
|
---|
187 | ListItem := Add;
|
---|
188 | ListItem.Caption := 'Restarty MaNGOSu';
|
---|
189 | ListItem.SubItems.Add(IntToStr(MangosRestartCount) + ' za den');
|
---|
190 | IdHTTP1.Get(StatServerURL + '?MeasureId=6&Value=' + IntToStr(MangosRestartCount));
|
---|
191 |
|
---|
192 | // Harddisk free space
|
---|
193 | DiskFreeSpace := Round(DiskFree(3) div 1024 div 1024 / 1024 * 1000) / 1000;
|
---|
194 | ListItem := Add;
|
---|
195 | ListItem.Caption := 'Volné místo na disku';
|
---|
196 | ListItem.SubItems.Add(FloatToStr(DiskFreeSpace) + ' GB');
|
---|
197 | IdHTTP1.Get(StatServerURL + '?MeasureId=7&Value=' + MySQLFloatToStr(DiskFreeSpace));
|
---|
198 |
|
---|
199 | EndUpdate;
|
---|
200 | end;
|
---|
201 | end;
|
---|
202 |
|
---|
203 | function Li2Double(x: LARGE_INTEGER): Double;
|
---|
204 | begin
|
---|
205 | Result := x.HighPart * 4.294967296E9 + x.LowPart
|
---|
206 | end;
|
---|
207 |
|
---|
208 | function TMainForm.GetCPUUsage: Real;
|
---|
209 | var
|
---|
210 | SysBaseInfo: TSystem_Basic_Information;
|
---|
211 | SysPerfInfo: TSystem_Performance_Information;
|
---|
212 | SysTimeInfo: TSystem_Time_Information;
|
---|
213 | status: Longint; {long}
|
---|
214 | dbSystemTime: Double;
|
---|
215 | dbIdleTime: Double;
|
---|
216 |
|
---|
217 | bLoopAborted : boolean;
|
---|
218 |
|
---|
219 | begin
|
---|
220 | if @NtQuerySystemInformation = nil then
|
---|
221 | NtQuerySystemInformation := GetProcAddress(GetModuleHandle('ntdll.dll'),
|
---|
222 | 'NtQuerySystemInformation');
|
---|
223 |
|
---|
224 | // get number of processors in the system
|
---|
225 |
|
---|
226 | status := NtQuerySystemInformation(SystemBasicInformation, @SysBaseInfo, SizeOf(SysBaseInfo), nil);
|
---|
227 | if status <> 0 then Exit;
|
---|
228 |
|
---|
229 | (*
|
---|
230 | // Show some information
|
---|
231 | with SysBaseInfo do begin
|
---|
232 | ShowMessage(
|
---|
233 | Format('uKeMaximumIncrement: %d'#13'uPageSize: %d'#13+
|
---|
234 | 'uMmNumberOfPhysicalPages: %d'+#13+'uMmLowestPhysicalPage: %d'+#13+
|
---|
235 | 'uMmHighestPhysicalPage: %d'+#13+'uAllocationGranularity: %d'#13+
|
---|
236 | 'uKeActiveProcessors: %d'#13'bKeNumberProcessors: %d',
|
---|
237 | [uKeMaximumIncrement, uPageSize, uMmNumberOfPhysicalPages,
|
---|
238 | uMmLowestPhysicalPage, uMmHighestPhysicalPage, uAllocationGranularity,
|
---|
239 | uKeActiveProcessors, bKeNumberProcessors]));
|
---|
240 | end;
|
---|
241 | *)
|
---|
242 |
|
---|
243 | bLoopAborted := False;
|
---|
244 |
|
---|
245 | // while not bLoopAborted do
|
---|
246 | begin
|
---|
247 |
|
---|
248 | // get new system time
|
---|
249 | status := NtQuerySystemInformation(SystemTimeInformation, @SysTimeInfo, SizeOf(SysTimeInfo), 0);
|
---|
250 | if status <> 0 then Exit;
|
---|
251 |
|
---|
252 | // get new CPU's idle time
|
---|
253 | status := NtQuerySystemInformation(SystemPerformanceInformation, @SysPerfInfo, SizeOf(SysPerfInfo), nil);
|
---|
254 | if status <> 0 then Exit;
|
---|
255 |
|
---|
256 | // if it's a first call - skip it
|
---|
257 | if (liOldIdleTime.QuadPart <> 0) then begin
|
---|
258 |
|
---|
259 | // CurrentValue = NewValue - OldValue
|
---|
260 | dbIdleTime := Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
|
---|
261 | dbSystemTime := Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
|
---|
262 |
|
---|
263 | // CurrentCpuIdle = IdleTime / SystemTime
|
---|
264 | dbIdleTime := dbIdleTime / dbSystemTime;
|
---|
265 |
|
---|
266 | // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
|
---|
267 | dbIdleTime := 100.0 - dbIdleTime * 100.0 / SysBaseInfo.bKeNumberProcessors + 0.5;
|
---|
268 |
|
---|
269 | // Show Percentage
|
---|
270 | Result := dbIdleTime;
|
---|
271 |
|
---|
272 | Application.ProcessMessages;
|
---|
273 |
|
---|
274 | // Abort if user pressed ESC or Application is terminated
|
---|
275 | bLoopAborted := (GetKeyState(VK_ESCAPE) and 128 = 128) or Application.Terminated;
|
---|
276 |
|
---|
277 | end;
|
---|
278 |
|
---|
279 | // store new CPU's idle and system time
|
---|
280 | liOldIdleTime := SysPerfInfo.liIdleTime;
|
---|
281 | liOldSystemTime := SysTimeInfo.liKeSystemTime;
|
---|
282 |
|
---|
283 | // wait one second
|
---|
284 | Sleep(100);
|
---|
285 | end;
|
---|
286 | if Result > 100 then Result := 100;
|
---|
287 | end;
|
---|
288 |
|
---|
289 | procedure TMainForm.FormActivate(Sender: TObject);
|
---|
290 | begin
|
---|
291 | Timer1Timer(nil);
|
---|
292 | end;
|
---|
293 |
|
---|
294 | procedure TMainForm.FormCreate(Sender: TObject);
|
---|
295 | begin
|
---|
296 | AutoRegistry := TAutoRegistry.Create('\Software\Chronosoft\ServerStat');
|
---|
297 | with AutoRegistry do begin
|
---|
298 | Include('StatServerUrl', StatServerUrl, 'http://localhost/game-server/statistic/add.php');
|
---|
299 | Include('DatabaseDatabase', DatabaseDatabase, 'realmd');
|
---|
300 | Include('DatabaseHostname', DatabaseHostname, 'localhost');
|
---|
301 | Include('DatabaseUsername', DatabaseUsername, 'mangos');
|
---|
302 | Include('DatabasePassword', DatabasePassword, 'mangos');
|
---|
303 | //Include('MangosFailure', MangosFailure, 'c:\Mangos\Restarter\failure.txt');
|
---|
304 | LoadFromRegistry;
|
---|
305 | end;
|
---|
306 | Database := TSqlDatabase.Create;
|
---|
307 | with Database do begin
|
---|
308 | Hostname := DatabaseHostname;
|
---|
309 | Database := DatabaseDatabase;
|
---|
310 | UserName := DatabaseUserName;
|
---|
311 | Password := DatabasePassword;
|
---|
312 | Connect;
|
---|
313 | end;
|
---|
314 | Timer1Timer(nil);
|
---|
315 | end;
|
---|
316 |
|
---|
317 | procedure TMainForm.Button1Click(Sender: TObject);
|
---|
318 | begin
|
---|
319 | Timer1Timer(nil);
|
---|
320 | end;
|
---|
321 |
|
---|
322 | procedure TMainForm.FormDestroy(Sender: TObject);
|
---|
323 | begin
|
---|
324 | Database.Free;
|
---|
325 | AutoRegistry.SaveToRegistry;
|
---|
326 | AutoRegistry.Free;
|
---|
327 | end;
|
---|
328 |
|
---|
329 | procedure TMainForm.Button2Click(Sender: TObject);
|
---|
330 | begin
|
---|
331 | OptionsForm.ShowModal;
|
---|
332 | end;
|
---|
333 |
|
---|
334 | end.
|
---|