Task = new Task($System); $this->Id = $Id; $DbResult = $this->Database->query('SELECT * FROM `Realm` WHERE `Id`='.$Id); if($DbResult->num_rows > 0) { $this->Data = $DbResult->fetch_assoc(); $DbResult = $this->Database->query('SELECT * FROM `Database` WHERE `Id`='.$this->Data['Database']); if($DbResult->num_rows > 0) $this->Data['Database'] = $DbResult->fetch_assoc(); else $this->Data['Database'] = array('Emulator' => 0); $DbResult = $this->Database->query('SELECT * FROM `Emulator` WHERE `Id`='.$this->Data['Database']['Emulator']); if($DbResult->num_rows > 0) $this->Data['Database']['Emulator'] = $DbResult->fetch_assoc(); else $this->Data['Database']['Emulator'] = array('Client' => 0); $DbResult = $this->Database->query('SELECT * FROM `Client` WHERE `Id`='.$this->Data['Database']['Emulator']['Client']); if($DbResult->num_rows > 0) $this->Data['Database']['Emulator']['Client'] = $DbResult->fetch_assoc(); else $this->Data['Database']['Emulator']['Client'] = array(); } } function GetState() { $State = array(); $State['WorlddPortState'] = $this->System->NetworkPortState('localhost', $this->Data['NetworkPortWorldd']); $State['Online'] = $State['WorlddPortState']; $State['Uptime'] = $this->Uptime(); $DbResult = $this->Database->query('SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = "realm'.$this->Id.'_characters"'); $DbRow = $DbResult->fetch_row(); if($DbRow[0] > 0) { $DbResult = $this->Database->query('SELECT COUNT(*) FROM realm'.$this->Id.'_characters.characters AS T WHERE T.online = 1'); $DbRow = $DbResult->fetch_row(); $State['CharacterOnlineCount'] = $DbRow[0]; $DbResult = $this->Database->query('SELECT COUNT(*) FROM realm'.$this->Id.'_characters.characters AS T'); $DbRow = $DbResult->fetch_row(); $State['CharacterCount'] = $DbRow[0]; } else { $State['CharacterOnlineCount'] = 0; $State['CharacterCount'] = 0; } return($State); } function CreateDatabase() { $this->Database->query('CREATE DATABASE `realm'.$this->Id.'_mangos`'); $this->Database->query('CREATE DATABASE `realm'.$this->Id.'_characters`'); $this->Database->query('CREATE DATABASE `realm'.$this->Id.'_scriptdev2`'); $this->Database->query('GRANT ALL PRIVILEGES ON `realm'.$this->Id.'\_mangos` . * TO "server'.$this->Data['Server'].'"@"localhost" WITH GRANT OPTION'); $this->Database->query('GRANT ALL PRIVILEGES ON `realm'.$this->Id.'\_characters` . * TO "server'.$this->Data['Server'].'"@"localhost" WITH GRANT OPTION'); $this->Database->query('GRANT ALL PRIVILEGES ON `realm'.$this->Id.'\_scriptdev2` . * TO "server'.$this->Data['Server'].'"@"localhost" WITH GRANT OPTION'); } function DeleteDatabase() { $this->Database->query('DROP DATABASE `realm'.$this->Id.'_mangos`'); $this->Database->query('DROP DATABASE `realm'.$this->Id.'_characters`'); $this->Database->query('DROP DATABASE `realm'.$this->Id.'_scriptdev2`'); } function ImportDatabase($Delete = false) { $this->Lock(); $CommandList = array( 'php www/shell.php RealmLock '.$this->Id, ); // Empty all tables if($Delete == true) { $CommandList = array_merge($CommandList, array( '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', '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', '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', )); } // Lookup nearest database with full import $DbResult = $this->Database->query('SELECT * FROM `Database` WHERE (`Emulator` <> 0) AND (`Revision` <= '.$this->Data['Database']['Revision'].') AND (`SourceFileName` <> "") ORDER BY `Revision` DESC'); $Database = $DbResult->fetch_assoc(); $CommandList = array_merge($CommandList, array( 'mysql --user=server'.$this->Data['Server'].' --password=server'.$this->Data['Server'].' realm'.$this->Id.'_mangos < database/'.$Database['Id'].'/'.$Database['SourceFileName'], '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', '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', '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', 'mysql --user=server'.$this->Data['Server'].' --password=server'.$this->Data['Server'].' realm'.$this->Id.'_characters < emulator/'.$Database['Emulator'].'/source/sql/characters.sql')); if($Database['ACIDSourceFileName'] != '') $CommandList[] = 'mysql --user=server'.$this->Data['Server'].' --password=server'.$this->Data['Server'].' realm'.$this->Id.'_mangos < database/'.$Database['Id'].'/'.$Database['ACIDSourceFileName']; $CommandList[] = 'php www/shell.php RealmDatabaseChange '.$this->Id.' '.$Database['Id']; $commandList[] = 'php www/shell.php RealmUnLock '.$this->Id; $this->Task->Add('Inicializace databáze', $CommandList); if($Database['Id'] != $this->Data['Database']['Id']) { $NewDatabaseId = $this->Data['Database']['Id']; $this->Data['Database']['Id'] = $Database['Id']; $this->Update($NewDatabaseId, false, false); } return('Úloha načtení nové databáze zařazena do fronty.'); } function Start() { $this->Lock(); $this->SaveConfiguration(); $this->Task->Add('Start světa', array( 'php www/shell.php RealmLock '.$this->Id, 'realm/'.$this->Id.'/bin/start.sh', 'php www/shell.php RealmUnLock '.$this->Id, )); return('Požadavek na start světa zařazen.'); } function Stop() { $this->Lock(); $this->Task->Add('Zastavení světa', array( 'php www/shell.php RealmLock '.$this->Id, 'realm/'.$this->Id.'/bin/stop.sh', 'php www/shell.php RealmUnLock '.$this->Id, )); return('Požadavek na zastavení světa zařazen.'); } function UpdateRealmlist() { $Server = new Server($this->System, $this->Data['Server']); $Server->UpdateRealmList(); } function SaveConfiguration() { $this->SetupConfigurationFiles(); $this->UpdateRealmlist(); $this->UpdateScripts(); } function UpdateScripts() { $RealmBinDir = '../realm/'.$this->Id.'/bin/'; if(!file_exists($RealmBinDir)) mkdir($RealmBinDir, 0777, true); // GDB script $ScriptFileName = '../realm/'.$this->Id.'/bin/mangos.gdb'; $Content = array ( 'run -c realm/'.$this->Id.'/etc/mangosd.conf', 'info thread', ); for($I = 1; $I < $this->Config['MangosWorlddThreadCountMax']; $I++) $Content[] = 'thread apply '.$I.' bt full'; file_put_contents($ScriptFileName, implode("\n", $Content)); chmod($ScriptFileName, 0666); // Start script $ScriptFileName = '../realm/'.$this->Id.'/bin/start.sh'; $Content = array ( '#!/bin/sh', 'if [ -z `ps -ef | grep \'SCREEN -A -m -d -S realm'.$this->Id.'-worldd\' | grep -v grep | awk \'{print $2}\'` ]', 'then', 'screen -A -m -d -S realm'.$this->Id.'-worldd realm/'.$this->Id.'/bin/worldd_restarter.sh', 'fi', ); file_put_contents($ScriptFileName, implode("\n", $Content)); chmod($ScriptFileName, 0777); $ScriptFileName = '../realm/'.$this->Id.'/bin/worldd_restarter.sh'; $Content = array ( '#!/bin/sh', 'while [ 1=1 ] ; do', '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', 'php www/shell.php ServerProcessLog '.$this->Id.' >>realm/'.$this->Id.'/log/mangos_debug.log 2>>realm/'.$this->Id.'/log/mangos_debug.err', 'sleep 3', 'done', ); file_put_contents($ScriptFileName, implode("\n", $Content)); chmod($ScriptFileName, 0777); // Stop script $ScriptFileName = '../realm/'.$this->Id.'/bin/stop.sh'; $Content = array ( '#!/bin/sh', 'ps -ef | grep \'SCREEN -A -m -d -S realm'.$this->Id.'-worldd\' | grep -v grep | awk \'{print $2}\' | xargs -i kill {}', ); file_put_contents($ScriptFileName, implode("\n", $Content)); chmod($ScriptFileName, 0777); } function SetupConfigurationFiles() { $EmulatorEtcDir = '../emulator/'.$this->Data['Database']['Emulator']['Id'].'/etc/'; $RealmEtcDir = '../realm/'.$this->Id.'/etc/'; $RealmLogDir = '../realm/'.$this->Id.'/log/'; if(!file_exists($RealmEtcDir)) mkdir($RealmEtcDir, 0777, true); if(!file_exists($RealmLogDir)) mkdir($RealmLogDir, 0777, true); // mangosd.conf if(!file_exists($RealmEtcDir.'mangosd.conf')) file_put_contents($RealmEtcDir.'mangosd.conf', file_get_contents($EmulatorEtcDir.'mangosd.conf.dist')); $EmulatorConfig = new MangosConfigurationFile($this->System); $EmulatorConfig->Load($RealmEtcDir.'mangosd.conf'); $EmulatorConfig->ParameterList['RealmID'] = $this->Data['Id']; $EmulatorConfig->ParameterList['LoginDatabaseInfo'] = 'localhost;3306;server'.$this->Data['Server'].';server'.$this->Data['Server'].';server'.$this->Data['Server'].'_realmd'; $EmulatorConfig->ParameterList['WorldDatabaseInfo'] = 'localhost;3306;server'.$this->Data['Server'].';server'.$this->Data['Server'].';realm'.$this->Id.'_mangos'; $EmulatorConfig->ParameterList['CharacterDatabaseInfo'] = 'localhost;3306;server'.$this->Data['Server'].';server'.$this->Data['Server'].';realm'.$this->Id.'_characters'; $EmulatorConfig->ParameterList['ScriptDev2DatabaseInfo'] = 'localhost;3306;server'.$this->Data['Server'].';server'.$this->Data['Server'].';realm'.$this->Id.'_scriptdev2'; $EmulatorConfig->ParameterList['WorldServerPort'] = $this->Data['NetworkPortWorldd']; $EmulatorConfig->ParameterList['DataDir'] = 'wowclient/'.$this->Data['Database']['Emulator']['Client']['Version']; $EmulatorConfig->ParameterList['LogsDir'] = 'realm/'.$this->Id.'/log'; $EmulatorConfig->ParameterList['LogLevel'] = 1; $EmulatorConfig->ParameterList['LogSQL'] = 0; $EmulatorConfig->Save($RealmEtcDir.'mangosd.conf'); // scriptdev2.conf $EmulatorConfig = new MangosConfigurationFile($this->System); $EmulatorConfig->Load($EmulatorEtcDir.'scriptdev2.conf'); $EmulatorConfig->ParameterList['ScriptDev2DatabaseInfo'] = 'localhost;3306;server'.$this->Data['Server'].';server'.$this->Data['Server'].';realm'.$this->Id.'_scriptdev2'; $EmulatorConfig->Save($RealmEtcDir.'scriptdev2.conf'); } function Update($DatabaseId, $DoBackup = true, $DoStop = true) { $this->Lock(); $Output = ''; // Stop server before update if($DoStop) { $Output .= $this->Stop(); } // Backup current if($DoBackup) { $Backup = new Backup($this->System, 0); $Output .= '
'.$Backup->Create($this->Id); } // Do update $Commands = array( 'php www/shell.php RealmLock '.$this->Id, ); $DbResult = $this->Database->query('SELECT `Revision` FROM `Database` WHERE `Id` = '.$this->Data['Database']['Id']); $DbRow = $DbResult->fetch_assoc(); $DatabaseRevisionStart = $DbRow['Revision']; $DbResult = $this->Database->query('SELECT `Revision` FROM `Database` WHERE `Id` = '.$DatabaseId); $DbRow = $DbResult->fetch_assoc(); $DatabaseRevisionEnd = $DbRow['Revision']; $DbResult = $this->Database->query('SELECT * FROM `Database` WHERE (`Revision` > '.$DatabaseRevisionStart.') AND (`Revision` <= '.$DatabaseRevisionEnd.') ORDER BY `Revision`'); while($DbRow = $DbResult->fetch_assoc()) { $Updates = explode("\n", $DbRow['Update']); foreach($Updates as $Update) if($Update != '') { $Parts = explode('|', $Update); if($Parts[0] != 'realmd') $Command = 'mysql --user=server'.$this->Data['Server'].' --password=server'.$this->Data['Server'].' realm'.$this->Id.'_'.$Parts[0].' < database/'.$DbRow['Id'].'/'.$Parts[1]; $Commands[] = $Command; } } $Commands = array_merge($Commands, array( 'php www/shell.php RealmDatabaseChange '.$this->Id.' '.$DatabaseId, 'php www/shell.php RealmUnLock '.$this->Id, )); $this->Task->Add('Aktualizace databáze', $Commands); $Output .= '
Úloha aktualizace serveru byla přidána do fronty.'; return($Output); } function Lock() { $this->Database->update('Realm', 'Id='.$this->Id, array('Lock' => 1)); } function UnLock() { $this->Database->update('Realm', 'Id='.$this->Id, array('Lock' => 0)); } function ChangeDatabaseId($Id) { $this->Database->update('Realm', 'Id='.$this->Id, array('Database' => $Id)); $this->SaveConfiguration(); } function GetUsedMemory() { $Output = array(); if(isset($this->Data['Database']['Emulator']['Id'])) exec('ps aux|grep "emulator/'.$this->Data['Database']['Emulator']['Id'].'/bin/mangos-worldd -c realm/'.$this->Id.'/etc/mangosd.conf"| grep -v grep', $Output); if(count($Output) > 0) { while(strpos($Output[0], ' ') > 0) $Output[0] = str_replace(' ', ' ', $Output[0]); $Parts = explode(' ', $Output[0]); return($Parts[4]); } else return(0); } function ProcessLog() { $File = fopen('../realm/'.$this->Id.'/log/mangos-worldd.log', 'r'); while(true) { $Readers = array($File); if(stream_select($Readers, $Writers=null, $Except=null, 0, 15) < 1) { continue; } else { // read data from the fifo $Data = fread($File, 1024); echo($Data); $this->Database->insert('RealmLog', array('Time' => 'NOW()', 'Realm' => $this->Id, 'Text' => $Data)); } sleep(1); } fclose($File); } function GetUser() { $DbResult = $this->Database->select('Server', 'User', 'Id='.$this->Data['Server']); $DbRow = $DbResult->fetch_assoc(); return($DbRow['User']); } function UpdateState() { $State = $this->GetState(); $this->Database->update('Realm', 'Id='.$this->Id, array( 'Online' => $State['Online'], 'CharacterOnlineCount' => $State['CharacterOnlineCount'], 'CharacterCount' => $State['CharacterCount'], )); } function UpdateStateAll() { $DbResult = $this->Database->select('Realm', 'Id'); while($DbRow = $DbResult->fetch_assoc()) { $Realm = new Realm($this->System, $DbRow['Id']); $Realm->UpdateState(); } } function BackupCharacter($AccountId) { } function Uptime() { $DbResult = $this->Database->query('SELECT uptime FROM server'.$this->Data['Server'].'_realmd.uptime WHERE realmid='.$this->Id.' ORDER BY starttime DESC LIMIT 1'); $DbRow = $DbResult->fetch_assoc(); return($DbRow['uptime']); } }