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