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)');
}
}
}