source: trunk/www/Application/Model/Realm.php@ 69

Last change on this file since 69 was 69, checked in by george, 16 years ago
  • Rozpracovaná verze.
  • Přeorganizována struktura souborů projektu.
  • Názvy přepány na stejné s prvním velkým písmenem.
  • Uživatelské podsložky přesunuty do podsložky Application, systémové do podsložky Base.
  • Použití koncepce Model-View-Controller.
File size: 15.9 KB
Line 
1<?php
2
3class Realm extends Module
4{
5 var $Id;
6 var $Data;
7 var $Task;
8
9 function __construct($Database, $Id)
10 {
11 $this->Database = $Database;
12 $this->Task = new Task($Database);
13 $this->Id = $Id;
14 $DbResult = $this->Database->query('SELECT * FROM `Realm` WHERE `Id`='.$Id);
15 if($DbResult->num_rows > 0)
16 {
17 $this->Data = $DbResult->fetch_assoc();
18 $DbResult = $this->Database->query('SELECT * FROM `Database` WHERE `Id`='.$this->Data['Database']);
19 if($DbResult->num_rows > 0) $this->Data['Database'] = $DbResult->fetch_assoc();
20 else $this->Data['Database'] = array('Emulator' => 0);
21 $DbResult = $this->Database->query('SELECT * FROM `Emulator` WHERE `Id`='.$this->Data['Database']['Emulator']);
22 if($DbResult->num_rows > 0) $this->Data['Database']['Emulator'] = $DbResult->fetch_assoc();
23 else $this->Data['Database']['Emulator'] = array('Client' => 0);
24 $DbResult = $this->Database->query('SELECT * FROM `Client` WHERE `Id`='.$this->Data['Database']['Emulator']['Client']);
25 if($DbResult->num_rows > 0) $this->Data['Database']['Emulator']['Client'] = $DbResult->fetch_assoc();
26 else $this->Data['Database']['Emulator']['Client'] = array();
27 }
28 }
29
30 function GetState()
31 {
32 global $System;
33
34 $State = array();
35 $State['WorlddPortState'] = $System->NetworkPortState('localhost', $this->Data['NetworkPortWorldd']);
36 $State['Online'] = $State['WorlddPortState'];
37 $State['Uptime'] = $this->Uptime();
38 $DbResult = $this->Database->query('SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = "realm'.$this->Id.'_characters"');
39 $DbRow = $DbResult->fetch_row();
40 if($DbRow[0] > 0)
41 {
42 $DbResult = $this->Database->query('SELECT COUNT(*) FROM realm'.$this->Id.'_characters.characters AS T WHERE T.online = 1');
43 $DbRow = $DbResult->fetch_row();
44 $State['CharacterOnlineCount'] = $DbRow[0];
45 $DbResult = $this->Database->query('SELECT COUNT(*) FROM realm'.$this->Id.'_characters.characters AS T');
46 $DbRow = $DbResult->fetch_row();
47 $State['CharacterCount'] = $DbRow[0];
48 } else
49 {
50 $State['CharacterOnlineCount'] = 0;
51 $State['CharacterCount'] = 0;
52 }
53 return($State);
54 }
55
56 function CreateDatabase()
57 {
58 $this->Database->query('CREATE DATABASE `realm'.$this->Id.'_mangos`');
59 $this->Database->query('CREATE DATABASE `realm'.$this->Id.'_characters`');
60 $this->Database->query('CREATE DATABASE `realm'.$this->Id.'_scriptdev2`');
61 $this->Database->query('GRANT ALL PRIVILEGES ON `realm'.$this->Id.'\_mangos` . * TO "server'.$this->Data['Server'].'"@"localhost" WITH GRANT OPTION');
62 $this->Database->query('GRANT ALL PRIVILEGES ON `realm'.$this->Id.'\_characters` . * TO "server'.$this->Data['Server'].'"@"localhost" WITH GRANT OPTION');
63 $this->Database->query('GRANT ALL PRIVILEGES ON `realm'.$this->Id.'\_scriptdev2` . * TO "server'.$this->Data['Server'].'"@"localhost" WITH GRANT OPTION');
64 }
65
66 function DeleteDatabase()
67 {
68 $this->Database->query('DROP DATABASE `realm'.$this->Id.'_mangos`');
69 $this->Database->query('DROP DATABASE `realm'.$this->Id.'_characters`');
70 $this->Database->query('DROP DATABASE `realm'.$this->Id.'_scriptdev2`');
71 }
72
73 function ImportDatabase($Delete = false)
74 {
75 $this->Lock();
76 $CommandList = array(
77 'php www/shell.php RealmLock '.$this->Id,
78 );
79
80 // Empty all tables
81 if($Delete == true)
82 {
83 $CommandList = array_merge($CommandList, array(
84 'mysql --silent --skip-column-names -u server'.$this->Data['Server'].' -pserver'.$this->Data['Server'].' realm'.$this->Id.'_mangos -e "show tables" | gawk \'{print "drop table " $1 ";"}\' | mysql -u server'.$this->Data['Server'].' -pserver'.$this->Data['Server'].' realm'.$this->Id.'_mangos',
85 'mysql --silent --skip-column-names -u server'.$this->Data['Server'].' -pserver'.$this->Data['Server'].' realm'.$this->Id.'_characters -e "show tables" | gawk \'{print "drop table " $1 ";"}\' | mysql -u server'.$this->Data['Server'].' -pserver'.$this->Data['Server'].' realm'.$this->Id.'_characters',
86 'mysql --silent --skip-column-names -u server'.$this->Data['Server'].' -pserver'.$this->Data['Server'].' realm'.$this->Id.'_scriptdev2 -e "show tables" | gawk \'{print "drop table " $1 ";"}\' | mysql -u server'.$this->Data['Server'].' -pserver'.$this->Data['Server'].' realm'.$this->Id.'_scriptdev2',
87 ));
88 }
89
90 // Lookup nearest database with full import
91 $DbResult = $this->Database->query('SELECT * FROM `Database` WHERE (`Emulator` <> 0) AND (`Revision` <= '.$this->Data['Database']['Revision'].') AND (`SourceFileName` <> "") ORDER BY `Revision` DESC');
92 $Database = $DbResult->fetch_assoc();
93
94 $CommandList = array_merge($CommandList, array(
95 'mysql --user=server'.$this->Data['Server'].' --password=server'.$this->Data['Server'].' realm'.$this->Id.'_mangos < database/'.$Database['Id'].'/'.$Database['SourceFileName'],
96 'mysql --user=server'.$this->Data['Server'].' --password=server'.$this->Data['Server'].' realm'.$this->Id.'_scriptdev2 < emulator/'.$Database['Emulator'].'/source/src/bindings/ScriptDev2/sql/scriptdev2_create_structure.sql',
97 'mysql --user=server'.$this->Data['Server'].' --password=server'.$this->Data['Server'].' realm'.$this->Id.'_scriptdev2 < emulator/'.$Database['Emulator'].'/source/src/bindings/ScriptDev2/sql/scriptdev2_script_full.sql',
98 'mysql --user=server'.$this->Data['Server'].' --password=server'.$this->Data['Server'].' realm'.$this->Id.'_mangos < emulator/'.$Database['Emulator'].'/source/src/bindings/ScriptDev2/sql/mangos_scriptname_full.sql',
99 'mysql --user=server'.$this->Data['Server'].' --password=server'.$this->Data['Server'].' realm'.$this->Id.'_characters < emulator/'.$Database['Emulator'].'/source/sql/characters.sql'));
100 if($Database['ACIDSourceFileName'] != '')
101 $CommandList[] = 'mysql --user=server'.$this->Data['Server'].' --password=server'.$this->Data['Server'].' realm'.$this->Id.'_mangos < database/'.$Database['Id'].'/'.$Database['ACIDSourceFileName'];
102 $CommandList[] = 'php www/shell.php RealmDatabaseChange '.$this->Id.' '.$Database['Id'];
103 $commandList[] = 'php www/shell.php RealmUnLock '.$this->Id;
104 $this->Task->Add('Inicializace databáze', $CommandList);
105
106 if($Database['Id'] != $this->Data['Database']['Id'])
107 {
108 $NewDatabaseId = $this->Data['Database']['Id'];
109 $this->Data['Database']['Id'] = $Database['Id'];
110 $this->Update($NewDatabaseId, false, false);
111 }
112 return('Úloha načtení nové databáze zařazena do fronty.');
113 }
114
115 function Start()
116 {
117 $this->Lock();
118 $this->SaveConfiguration();
119 $this->Task->Add('Start světa', array(
120 'php www/shell.php RealmLock '.$this->Id,
121 'realm/'.$this->Id.'/bin/start.sh',
122 'php www/shell.php RealmUnLock '.$this->Id,
123 ));
124 return('Požadavek na start světa zařazen.');
125 }
126
127 function Stop()
128 {
129 $this->Lock();
130 $this->Task->Add('Zastavení světa', array(
131 'php www/shell.php RealmLock '.$this->Id,
132 'realm/'.$this->Id.'/bin/stop.sh',
133 'php www/shell.php RealmUnLock '.$this->Id,
134 ));
135 return('Požadavek na zastavení světa zařazen.');
136 }
137
138 function UpdateRealmlist()
139 {
140 $Server = new Server($this->Database, $this->Data['Server']);
141 $Server->UpdateRealmList();
142 }
143
144 function SaveConfiguration()
145 {
146 $this->SetupConfigurationFiles();
147 $this->UpdateRealmlist();
148 $this->UpdateScripts();
149 }
150
151 function UpdateScripts()
152 {
153 global $Config;
154
155 $RealmBinDir = '../realm/'.$this->Id.'/bin/';
156 if(!file_exists($RealmBinDir)) mkdir($RealmBinDir, 0777, true);
157
158 // GDB script
159 $ScriptFileName = '../realm/'.$this->Id.'/bin/mangos.gdb';
160 $Content = array
161 (
162 'run -c realm/'.$this->Id.'/etc/mangosd.conf',
163 'info thread',
164 );
165 for($I = 1; $I < $Config['MangosWorlddThreadCountMax']; $I++)
166 $Content[] = 'thread apply '.$I.' bt full';
167 file_put_contents($ScriptFileName, implode("\n", $Content));
168 chmod($ScriptFileName, 0666);
169
170 // Start script
171 $ScriptFileName = '../realm/'.$this->Id.'/bin/start.sh';
172 $Content = array
173 (
174 '#!/bin/sh',
175 'if [ -z `ps -ef | grep \'SCREEN -A -m -d -S realm'.$this->Id.'-worldd\' | grep -v grep | awk \'{print $2}\'` ]',
176 'then',
177 'screen -A -m -d -S realm'.$this->Id.'-worldd realm/'.$this->Id.'/bin/worldd_restarter.sh',
178 'fi',
179 );
180 file_put_contents($ScriptFileName, implode("\n", $Content));
181 chmod($ScriptFileName, 0777);
182
183 $ScriptFileName = '../realm/'.$this->Id.'/bin/worldd_restarter.sh';
184 $Content = array
185 (
186 '#!/bin/sh',
187 'while [ 1=1 ] ; do',
188 'gdb emulator/'.$this->Data['Database']['Emulator']['Id'].'/bin/mangos-worldd -x realm/'.$this->Id.'/bin/mangos.gdb --batch >>realm/'.$this->Id.'/log/mangos-worldd.log 2>>realm/'.$this->Id.'/log/mangos-worldd.err',
189 'php www/shell.php ServerProcessLog '.$this->Id.' >>realm/'.$this->Id.'/log/mangos_debug.log 2>>realm/'.$this->Id.'/log/mangos_debug.err',
190 'sleep 3',
191 'done',
192 );
193 file_put_contents($ScriptFileName, implode("\n", $Content));
194 chmod($ScriptFileName, 0777);
195
196 // Stop script
197 $ScriptFileName = '../realm/'.$this->Id.'/bin/stop.sh';
198 $Content = array
199 (
200 '#!/bin/sh',
201 'ps -ef | grep \'SCREEN -A -m -d -S realm'.$this->Id.'-worldd\' | grep -v grep | awk \'{print $2}\' | xargs -i kill {}',
202 );
203 file_put_contents($ScriptFileName, implode("\n", $Content));
204 chmod($ScriptFileName, 0777);
205 }
206
207 function SetupConfigurationFiles()
208 {
209 global $Config;
210
211 $EmulatorEtcDir = '../emulator/'.$this->Data['Database']['Emulator']['Id'].'/etc/';
212 $RealmEtcDir = '../realm/'.$this->Id.'/etc/';
213 $RealmLogDir = '../realm/'.$this->Id.'/log/';
214 if(!file_exists($RealmEtcDir)) mkdir($RealmEtcDir, 0777, true);
215 if(!file_exists($RealmLogDir)) mkdir($RealmLogDir, 0777, true);
216
217 // mangosd.conf
218 if(!file_exists($RealmEtcDir.'mangosd.conf'))
219 file_put_contents($RealmEtcDir.'mangosd.conf', file_get_contents($EmulatorEtcDir.'mangosd.conf.dist'));
220 $EmulatorConfig = new MangosConfigurationFile($this->Database);
221 $EmulatorConfig->Load($RealmEtcDir.'mangosd.conf');
222 $EmulatorConfig->ParameterList['RealmID'] = $this->Data['Id'];
223 $EmulatorConfig->ParameterList['LoginDatabaseInfo'] = 'localhost;3306;server'.$this->Data['Server'].';server'.$this->Data['Server'].';server'.$this->Data['Server'].'_realmd';
224 $EmulatorConfig->ParameterList['WorldDatabaseInfo'] = 'localhost;3306;server'.$this->Data['Server'].';server'.$this->Data['Server'].';realm'.$this->Id.'_mangos';
225 $EmulatorConfig->ParameterList['CharacterDatabaseInfo'] = 'localhost;3306;server'.$this->Data['Server'].';server'.$this->Data['Server'].';realm'.$this->Id.'_characters';
226 $EmulatorConfig->ParameterList['ScriptDev2DatabaseInfo'] = 'localhost;3306;server'.$this->Data['Server'].';server'.$this->Data['Server'].';realm'.$this->Id.'_scriptdev2';
227 $EmulatorConfig->ParameterList['WorldServerPort'] = $this->Data['NetworkPortWorldd'];
228 $EmulatorConfig->ParameterList['DataDir'] = 'wowclient/'.$this->Data['Database']['Emulator']['Client']['Version'];
229 $EmulatorConfig->ParameterList['LogsDir'] = 'realm/'.$this->Id.'/log';
230 $EmulatorConfig->ParameterList['LogLevel'] = 1;
231 $EmulatorConfig->ParameterList['LogSQL'] = 0;
232 $EmulatorConfig->Save($RealmEtcDir.'mangosd.conf');
233
234 // scriptdev2.conf
235 $EmulatorConfig = new MangosConfigurationFile($this->Database);
236 $EmulatorConfig->Load($EmulatorEtcDir.'scriptdev2.conf');
237 $EmulatorConfig->ParameterList['ScriptDev2DatabaseInfo'] = 'localhost;3306;server'.$this->Data['Server'].';server'.$this->Data['Server'].';realm'.$this->Id.'_scriptdev2';
238 $EmulatorConfig->Save($RealmEtcDir.'scriptdev2.conf');
239 }
240
241 function Update($DatabaseId, $DoBackup = true, $DoStop = true)
242 {
243 $this->Lock();
244 $Output = '';
245
246 // Stop server before update
247 if($DoStop)
248 {
249 $Output .= $this->Stop();
250 }
251
252 // Backup current
253 if($DoBackup)
254 {
255 $Backup = new Backup($this->Database, 0);
256 $Output .= '<br />'.$Backup->Create($this->Id);
257 }
258
259 // Do update
260 $Commands = array(
261 'php www/shell.php RealmLock '.$this->Id,
262 );
263 $DbResult = $this->Database->query('SELECT `Revision` FROM `Database` WHERE `Id` = '.$this->Data['Database']['Id']);
264 $DbRow = $DbResult->fetch_assoc();
265 $DatabaseRevisionStart = $DbRow['Revision'];
266 $DbResult = $this->Database->query('SELECT `Revision` FROM `Database` WHERE `Id` = '.$DatabaseId);
267 $DbRow = $DbResult->fetch_assoc();
268 $DatabaseRevisionEnd = $DbRow['Revision'];
269 $DbResult = $this->Database->query('SELECT * FROM `Database` WHERE (`Revision` > '.$DatabaseRevisionStart.') AND (`Revision` <= '.$DatabaseRevisionEnd.') ORDER BY `Revision`');
270 while($DbRow = $DbResult->fetch_assoc())
271 {
272 $Updates = explode("\n", $DbRow['Update']);
273 foreach($Updates as $Update)
274 if($Update != '')
275 {
276 $Parts = explode('|', $Update);
277 if($Parts[0] != 'realmd')
278 $Command = 'mysql --user=server'.$this->Data['Server'].' --password=server'.$this->Data['Server'].' realm'.$this->Id.'_'.$Parts[0].' < database/'.$DbRow['Id'].'/'.$Parts[1];
279 $Commands[] = $Command;
280 }
281 }
282 $Commands = array_merge($Commands, array(
283 'php www/shell.php RealmDatabaseChange '.$this->Id.' '.$DatabaseId,
284 'php www/shell.php RealmUnLock '.$this->Id,
285 ));
286
287 $this->Task->Add('Aktualizace databáze', $Commands);
288 $Output .= '<br />Úloha aktualizace serveru byla přidána do fronty.';
289 return($Output);
290 }
291
292 function Lock()
293 {
294 $this->Database->update('Realm', 'Id='.$this->Id, array('Lock' => 1));
295 }
296
297 function UnLock()
298 {
299 $this->Database->update('Realm', 'Id='.$this->Id, array('Lock' => 0));
300 }
301
302 function ChangeDatabaseId($Id)
303 {
304 $this->Database->update('Realm', 'Id='.$this->Id, array('Database' => $Id));
305 $this->SaveConfiguration();
306 }
307
308 function GetUsedMemory()
309 {
310 $Output = array();
311 if(isset($this->Data['Database']['Emulator']['Id']))
312 exec('ps aux|grep "emulator/'.$this->Data['Database']['Emulator']['Id'].'/bin/mangos-worldd -c realm/'.$this->Id.'/etc/mangosd.conf"| grep -v grep', $Output);
313 if(count($Output) > 0)
314 {
315 while(strpos($Output[0], ' ') > 0) $Output[0] = str_replace(' ', ' ', $Output[0]);
316 $Parts = explode(' ', $Output[0]);
317 return($Parts[4]);
318 } else return(0);
319 }
320
321 function ProcessLog()
322 {
323 $File = fopen('../realm/'.$this->Id.'/log/mangos-worldd.log', 'r');
324 while(true)
325 {
326 $Readers = array($File);
327 if(stream_select($Readers, $Writers=null, $Except=null, 0, 15) < 1)
328 {
329 continue;
330 } else
331 {
332 // read data from the fifo
333 $Data = fread($File, 1024);
334 echo($Data);
335 $this->Database->insert('RealmLog', array('Time' => 'NOW()', 'Realm' => $this->Id, 'Text' => $Data));
336 }
337 sleep(1);
338 }
339 fclose($File);
340 }
341
342 function GetUser()
343 {
344 $DbResult = $this->Database->select('Server', 'User', 'Id='.$this->Data['Server']);
345 $DbRow = $DbResult->fetch_assoc();
346 return($DbRow['User']);
347 }
348
349 function UpdateState()
350 {
351 $State = $this->GetState();
352 $this->Database->update('Realm', 'Id='.$this->Id, array(
353 'Online' => $State['Online'],
354 'CharacterOnlineCount' => $State['CharacterOnlineCount'],
355 'CharacterCount' => $State['CharacterCount'],
356 ));
357 }
358
359 function UpdateStateAll()
360 {
361 $DbResult = $this->Database->select('Realm', 'Id');
362 while($DbRow = $DbResult->fetch_assoc())
363 {
364 $Realm = new Realm($this->Database, $DbRow['Id']);
365 $Realm->UpdateState();
366 }
367 }
368
369 function BackupCharacter($AccountId)
370 {
371 }
372
373 function Uptime()
374 {
375 $DbResult = $this->Database->query('SELECT uptime FROM server'.$this->Data['Server'].'_realmd.uptime WHERE realmid='.$this->Id.' ORDER BY starttime DESC LIMIT 1');
376 $DbRow = $DbResult->fetch_assoc();
377 return($DbRow['uptime']);
378 }
379}
380
381?>
Note: See TracBrowser for help on using the repository browser.