Task = new Task($System); $this->Id = $Id; $DbResult = $this->Database->query('SELECT * FROM `Server` WHERE `Id`='.$Id); if($DbResult->num_rows > 0) { $this->Server = $DbResult->fetch_assoc(); $DbResult = $this->Database->query('SELECT * FROM `Database` WHERE `Id`='.$this->Server['Database']); if($DbResult->num_rows > 0) $this->Server['Database'] = $DbResult->fetch_assoc(); else $this->Server['Database'] = array('Emulator' => 0); $DbResult = $this->Database->query('SELECT * FROM `Emulator` WHERE `Id`='.$this->Server['Database']['Emulator']); if($DbResult->num_rows > 0) $this->Server['Database']['Emulator'] = $DbResult->fetch_assoc(); else $this->Server['Database']['Emulator'] = array('Client' => 0); $DbResult = $this->Database->query('SELECT * FROM `Client` WHERE `Id`='.$this->Server['Database']['Emulator']['Client']); if($DbResult->num_rows > 0) $this->Server['Database']['Emulator']['Client'] = $DbResult->fetch_assoc(); else $this->Server['Database']['Emulator']['Client'] = array(); } } function CreateDatabase() { $this->Database->query('CREATE DATABASE `server'.$this->Id.'_realmd`'); $this->Database->query('CREATE USER "server'.$this->Id.'"@"localhost" IDENTIFIED BY "server'.$this->Id.'"'); $this->Database->query('GRANT ALL PRIVILEGES ON `server'.$this->Id.'\_realmd` . * TO "server'.$this->Id.'"@"localhost" WITH GRANT OPTION'); } function DeleteDatabase() { $this->Database->query('DROP DATABASE `server'.$this->Id.'_realmd`'); $this->Database->query('DROP USER "server'.$this->Id.'"@"localhost"'); } function Start() { $this->Lock(); $this->SaveConfiguration(); $this->Task->Add('Start emulátoru', array( 'php www/shell.php ServerLock '.$this->Id, 'server/'.$this->Id.'/bin/start.sh', 'php www/shell.php ServerUnLock '.$this->Id, )); return('Požadavek na start serveru zařazen.'); } function Stop() { $this->Lock(); $this->Task->Add('Zastavení emulátoru', array( 'php www/shell.php ServerLock '.$this->Id, 'server/'.$this->Id.'/bin/stop.sh', 'php www/shell.php ServerUnLock '.$this->Id, )); return('Požadavek na zastavení serveru zařazen.'); } function GetState() { $State = array(); $State['RealmdPortState'] = $this->System->NetworkPortState('localhost', $this->Server['NetworkPortRealmd']); $State['Online'] = $State['RealmdPortState']; $DbResult = $this->Database->query('SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = "server'.$this->Id.'_realmd"'); $DbRow = $DbResult->fetch_row(); if($DbRow[0] > 0) { $State['AccountCount'] = $DbRow[0]; $DbResult = $this->Database->query('SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = "server'.$this->Id.'_realmd" AND TABLE_NAME = "uptime"'); $DbRow = $DbResult->fetch_row(); if($DbRow[0] > 0) { $DbResult = $this->Database->query('SELECT uptime FROM server'.$this->Id.'_realmd.uptime AS T ORDER BY T.startstring DESC'); $DbRow = $DbResult->fetch_assoc(); $State['Uptime'] = $DbRow['uptime']; } else $State['Uptime'] = 0; } else { $State['AccountCount'] = 0; $State['Uptime'] = 0; } $State['UsedMemory'] = $this->GetUsedMemory(); return($State); } function UpdateRealmlist() { $this->Database->query('TRUNCATE TABLE server'.$this->Id.'_realmd.realmlist'); $DbResult = $this->Database->select('Realm', '*', 'Server = '.$this->Id); while($Realm = $DbResult->fetch_assoc()) { $this->Database->insert('server'.$this->Id.'_realmd`.`realmlist', array('id' => $Realm['Id'], 'name' => addslashes($Realm['Name']), 'address' => $this->Config['Web']['Host'], 'port' => $Realm['NetworkPortWorldd'], 'icon' => 0, 'timezone' => 1, 'color' => 0)); } } function SaveConfiguration() { $this->SetupConfigurationFiles(); $this->UpdateRealmlist(); $this->UpdateScripts(); } function UpdateScripts() { $ServerBinDir = '../server/'.$this->Id.'/bin/'; if(!file_exists($ServerBinDir)) mkdir($ServerBinDir, 0777, true); // Start script $ScriptFileName = '../server/'.$this->Id.'/bin/start.sh'; $Content = array ( '#!/bin/sh', 'if [ -z `ps -ef | grep \'SCREEN -A -m -d -S server'.$this->Id.'-realmd\' | grep -v grep | awk \'{print $2}\'` ]', 'then', 'screen -A -m -d -S server'.$this->Id.'-realmd emulator/'.$this->Server['Database']['Emulator']['Id'].'/bin/mangos-realmd -c server/'.$this->Id.'/etc/realmd.conf', 'fi', ); file_put_contents($ScriptFileName, implode("\n", $Content)); chmod($ScriptFileName, 0777); // Stop script $ScriptFileName = '../server/'.$this->Id.'/bin/stop.sh'; $Content = array ( '#!/bin/sh', 'ps -ef | grep \'SCREEN -A -m -d -S server'.$this->Id.'-realmd\' | grep -v grep | awk \'{print $2}\' | xargs -i kill {}', ); file_put_contents($ScriptFileName, implode("\n", $Content)); chmod($ScriptFileName, 0777); } function SetupConfigurationFiles() { $EmulatorEtcDir = '../emulator/'.$this->Server['Database']['Emulator']['Id'].'/etc/'; $ServerEtcDir = '../server/'.$this->Id.'/etc/'; $ServerLogDir = '../server/'.$this->Id.'/log/'; if(!file_exists($ServerEtcDir)) mkdir($ServerEtcDir, 0777, true); if(!file_exists($ServerLogDir)) mkdir($ServerLogDir, 0777, true); // realmd.conf $EmulatorConfig = new MangosConfigurationFile($this->System); $EmulatorConfig->Load($EmulatorEtcDir.'realmd.conf.dist'); $EmulatorConfig->ParameterList['LoginDatabaseInfo'] = 'localhost;3306;server'.$this->Id.';server'.$this->Id.';server'.$this->Id.'_realmd'; $EmulatorConfig->ParameterList['RealmServerPort'] = $this->Server['NetworkPortRealmd']; $EmulatorConfig->ParameterList['LogsDir'] = 'server/'.$this->Id.'/log'; $EmulatorConfig->Save($ServerEtcDir.'realmd.conf'); } function UpdateState() { $State = $this->GetState(); $this->Database->update('Server', 'Id='.$this->Id, array( 'Online' => $State['Online'], 'AccountCount' => $State['AccountCount'], )); } function UpdateStateAll() { $DbResult = $this->Database->select('Server', 'Id'); while($DbRow = $DbResult->fetch_assoc()) { $Server = new Server($this->System, $DbRow['Id']); $Server->UpdateState(); } } function NewAccount($Name, $Password, $Password2, $Email, $Expansion) { $Output = ''; if(($Password == '') or ($Password2 == '') or ($Name == '') or ($Email == '')) $Output = 'Vyplňte správně všechny údaje.'; else if($Password != $Password2) $Output = 'Hesla si neodpovídají.'; else { $Name = strtoupper($Name); $DbResult = $this->Database->query('SELECT Id FROM server'.$this->Id.'_realmd.account WHERE username="'.$Name.'"'); if($DbResult->num_rows > 0) $Output = 'Účet se zadaným jménem již existuje.'; else { $Password = sha1($Name.':'.strtoupper($Password)); $this->Database->query('INSERT INTO `server'.$this->Id.'_realmd`.`account` (`username`, `sha_pass_hash`, `email`, `joindate`, `expansion`) VALUES ("'.$Name.'", "'.$Password.'", "'.$Email.'", NOW(), '.$Expansion.')'); $Output = 'Nový účet vytvořen.'; } } return($Output); } function ImportDatabase($Delete = false) { $this->Lock(); $CommandList = array( 'php www/shell.php ServerLock '.$this->Id, ); if($Delete == true) { $CommandList = array_merge($CommandList, array( 'mysql --silent --skip-column-names -u server'.$this->Id.' -pserver'.$this->Id.' server'.$this->Id.'_realmd -e "show tables" | gawk \'{print "drop table " $1 ";"}\' | mysql -u server'.$this->Id.' -pserver'.$this->Id.' server'.$this->Id.'_realmd', )); } // Lookup nearest database with full import $DbResult = $this->Database->query('SELECT * FROM `Database` WHERE (`Emulator` <> 0) AND (`Revision` <= '.$this->Server['Database']['Revision'].') AND (`SourceFileName` <> "") ORDER BY `Revision` DESC'); $Database = $DbResult->fetch_assoc(); $CommandList = array_merge($CommandList, array( 'mysql --user=server'.$this->Id.' --password=server'.$this->Id.' server'.$this->Id.'_realmd < emulator/'.$Database['Emulator']['Id'].'/share/mangos/sql/realmd.sql', 'php www/shell.php ServerDatabaseChange '.$this->Id.' '.$Database['Id'], 'php www/shell.php ServerUnLock '.$this->Id, )); $this->Task->Add('Inicializace databáze', $CommandList); if($Database['Id'] != $this->Server['Database']['Id']) { $NewDatabaseId = $this->Server['Database']['Id']; $this->Server['Database']['Id'] = $Database['Id']; $this->Update($NewDatabaseId, false, false); } return('Úloha načtení nové databáze zařazena do fronty.'); } 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 ServerLock '.$this->Id, ); $DbResult = $this->Database->query('SELECT `Revision` FROM `Database` WHERE `Id` = '.$this->Server['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->Id.' --password=server'.$this->Id.' server'.$this->Id.'_'.$Parts[0].' < database/'.$DbRow['Id'].'/'.$Parts[1]; $Commands[] = $Command; } } $Commands = array_merge($Commands, array( 'php www/shell.php ServerDatabaseChange '.$this->Id.' '.$DatabaseId, 'php www/shell.php ServerUnLock '.$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('Server', 'Id='.$this->Id, array('Lock' => 1)); } function UnLock() { $this->Database->update('Server', 'Id='.$this->Id, array('Lock' => 0)); } function ChangeDatabaseId($Id) { $this->Database->update('Server', 'Id='.$this->Id, array('Database' => $Id)); $this->SaveConfiguration(); } function GetUsedMemory() { $UsedMemory = 0; $DbResult = $this->Database->select('Realm', 'Id', 'Server='.$this->Id); while($DbRow = $DbResult->fetch_assoc()) { $Realm = new Realm($this->System, $DbRow['Id']); $UsedMemory += $Realm->GetUsedMemory(); } return($UsedMemory); } function GetPatchList() { // http://us.version.worldofwarcraft.com/update/PatchSequenceFile.txt $Output = array('[WoW]', 'CurrentBuild='.$this->Server['Database']['Emulator']['Client']['BuildNumber']); $DbResult = $this->Database->query('SELECT * FROM Client WHERE BuildNumber <= '.$this->Server['Database']['Emulator']['Client']['BuildNumber'].' AND Patch != "" ORDER BY BuildNumber'); while($DbRow = $DbResult->fetch_assoc()) { $Output[] = $DbRow['BuildNumber'].'='.$DbRow['Patch']; } return(implode("\n", $Output)); } function RealmCount() { $DbResult = $this->Database->query('SELECT COUNT(*) FROM Realm WHERE Server='.$this->Id); $DbRow = $DbResult->fetch_row(); return($DbRow[0]); } function UpdateRealmlistAccountCount() { $this->Database->query('TRUNCATE TABLE server'.$this->Id.'_realmd.realmcharacters'); $DbResult = $this->Database->select('Realm', '*', 'Server = '.$this->Id); while($Realm = $DbResult->fetch_assoc()) { $this->Database->query('INSERT INTO server'.$this->Id.'_realmd.realmcharacters (SELECT '.$Realm['Id'].' AS realmid, server'.$this->Id.'_realmd.account.id AS acctid, (SELECT COUNT(*) FROM realm'.$Realm['Id'].'_characters.characters WHERE realm'.$Realm['Id'].'_characters.characters.account = server'.$this->Id.'_realmd.account.id) AS numchars FROM server'.$this->Id.'_realmd.account)'); } } }