Dynamické povolování registrací
Úvod
Existují servery malé, střední a velké. Co server, to různá koncepce jak jej co nejlevněji financovat. Zatímco v případě velkých serverů majitelé většinou investují do drahého hardware a rychlého internetového připojení, které je nutno odpovídajícím způsobem měsíčně platit, tak některé menší servery jdou spíše cestou minimálních nákladů a majitelé je provozují např. doma, kde však nemusí mít dostatečnou kapacitu internetové linky v odchozím směru. Tak či tak, každý server může narazit pod náporem hráčů na své limity a musí pak přistoupit k omezení množství hráčů.
Existují dvě místa, kde lze tento počet omezit:
- Omezit max. počet hráčů online
- Omezit počet nových registrací
V prvním případě jsou však hráči při dosažení kapacity zařazovány do fronty a musí čekat, až se na ně dostane řada. To je nevýhodné z toho pohledu, že starší hráči musí čekat na úkor nově příchozích a v konečném důsledku mohou být nespokojeni všichni.
Naproti tomu pokud se zabrání příchodu nových hráčů, tak staří se mohou kdykoliv připojit a noví se na server ani nedostanou a tak nemají pocit, že o něco přicházejí.
Omezit registrace lze různým způsobem:
- Ručně je podle uvážení zablokovat
- Ručně zpracovávat všechny registrace přes email
- Pouze stávající hráči mohou rozdávat pozvánky novým hráčům
- Konstantně omezit denní počet registrací
- Dynamicky povolovat registrace k dosažen požadovaného množství hráčů
Každý ze způsobů má své výhody a nevýhody a jejich realizace je různě složitá. Každopádně pokud server má omezenu kapacitu a majitel chce udržovat počet online hráčů na určité úrovni, tak může s výhodou použít poslední uvedenou variantu a tedy automatický systém regulace. Pak počty připojených hráčů budou se budou přibližovat k žádané hodnotě a budou kolem ní v obou směrech oscilovat. Samotný online limit lze nastavit např. na 1,5 násobek předpokládané hodnoty, aby se všichni hráči vždy mohly připojit.
Realizace
Aby mohlo automatické omezování správně fungovat, potřebuje mít k výpočtu informaci o:
- Počtu účtů na konci předchozího dne
- Aktuální počet účtů
- Nejvyšší počet hráčů online během předchozího dne
- Požadovaný počet online hráčů
Inicializace databáze
Aby bylo možné tyto údaje získat a někde uchovat, je potřeba si vytvořit v databázi pomocnou tabulku:
CREATE TABLE IF NOT EXISTS `CharacterOnlineHistory` (
`Date` date NOT NULL,
`Min` int(11) NOT NULL,
`Max` int(11) NOT NULL,
`AccountCount` int(11) NOT NULL,
PRIMARY KEY (`Date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;
Zde je uveden datum Date jakožto primární klíč a pak maximální počet online hráčů a počet účtů ke konci daného dne AccountCount. Hodnota Min je zde spíše pro zajímavost.
Základní třída RegistrationLimit
Zde je PHP třída uložená v souboru registration_limit.php:
<?php
class RegistrationLimit
{
var $db;
var $Server;
var $Config;
function __construct($db, $Server, $Config)
{
$this->db = $db;
$this->Server = $Server;
$this->Config = $Config;
}
function Update()
{
$AccountOnlineCount = $this->Server->RealmOnline();
$AccountCount = $this->Server->AccountCount();
$this->db->select_db($this->Config['Database']['Database']);
$DbResult = $this->db->query('SELECT * FROM `CharacterOnlineHistory` WHERE `Date` = CURDATE()');
if($DbResult->num_rows > 0)
{
// Update max, min
$this->db->query('UPDATE `CharacterOnlineHistory` SET `Max` = GREATEST(`Max`, '.$AccountOnlineCount.'), `Min` = LEAST(`Min`, '.$AccountOnlineCount.'), `AccountCount` = '.$AccountCount.' WHERE `Date` = CURDATE()');
} else
$this->db->query('INSERT INTO `CharacterOnlineHistory` (`Max`, `Min`, `Date`, `AccountCount`) VALUES ('.$AccountOnlineCount.', '.$AccountOnlineCount.', CURDATE(), '.$AccountCount.')');
}
function GetFreeRegistrationCount()
{
$AccountCount = $this->Server->AccountCount();
$this->db->select_db($this->Config['Database']['Database']);
$DbResult = $this->db->query('SELECT * FROM `CharacterOnlineHistory` WHERE `Date` = DATE_SUB(CURDATE(), INTERVAL 1 DAY)');
if($DbResult->num_rows > 0)
{
$Yesterday = $DbResult->fetch_assoc();
} else
$Yesterday = array('Max' => 0, 'AccountCount' => 0);
$NextDayFreeRegistration = $this->Config['Mangos']['RequiredOnlinePlayers'] - $Yesterday['Max'];
if($NextDayFreeRegistration < 0) $NextDayFreeRegistration = 0;
$NextDayUsedRegistration = $AccountCount - $Yesterday['AccountCount'];
$FreeRegistration = $NextDayFreeRegistration - $NextDayUsedRegistration;
if($FreeRegistration < 0) $FreeRegistration = 0;
return($FreeRegistration);
}
function GetPerDeyRegistrationCount()
{
$AccountCount = $this->Server->AccountCount();
$this->db->select_db($this->Config['Database']['Database']);
$DbResult = $this->db->query('SELECT * FROM `CharacterOnlineHistory` WHERE `Date` = DATE_SUB(CURDATE(), INTERVAL 1 DAY)');
if($DbResult->num_rows > 0)
{
$Yesterday = $DbResult->fetch_assoc();
} else
$Yesterday = array('Max' => 0, 'AccountCount' => 0);
$NextDayFreeRegistration = $this->Config['Mangos']['RequiredOnlinePlayers'] - $Yesterday['Max'];
if($NextDayFreeRegistration < 0) $NextDayFreeRegistration = 0;
return($NextDayFreeRegistration);
}
}
?>
Třída poskytuje tři funkce:
- Update() - tuto funkci je potřeba během dne periodicky volat, aby bylo možné zjistit maximum hráčů online. Také ukládá počet účtů na konci dne.
- GetFreeRegistrationCount() - Vrací zbývající počet povolených registrací pro aktuální den.
- GetPerDeyRegistrationCount() - Vrací celkový počet povolených registrací pro aktuální den.
Konfigurační soubor
Nastavení lze provést přes parametr $Config. Ten lze inicializovat pomocí souboru config.php např. takto:
<?php
$Config = array(
'Database' => array
(
'Host' => 'localhost',
'User' => 'root',
'Password' => '',
'Database' => 'wow',
'Prefix' => '',
'Charset' => 'utf8',
),
'Mangos' => array(
'DatabaseRealmd' => 'realmd',
'RequiredOnlinePlayers' => 200,
),
);
?>
Samozřejmě je potřeba doplnit patřičné přihlašovací údaje k databázi s umístěním pomocné tabulky.
Aktualizace dat
Pro zjištění počtu hráčů online je nutno pravidelně během dnes např. každých 5 minut kontrolovat jejich stav. To zajistí jednoduchý skript registration_update.php:
<?php
include('server.php');
include('registration_limit.php');
include('config.php');
$db = new mysqli($Config['Database']['Host'], $Config['Database']['User'], $Config['Database']['Password'], $Config['Database']['Database']);
$Server = new Server($db, $Config);
$RegistrationLimit = new RegistrationLimit($db, $Server, $Config);
$RegistrationLimit->Update();
?>
Volání lze realizovat pomocí systémového plánovače ve Windows nebo v Linuxu pomocí plánovače cron:
Soubor registration_update.sh:
#!/bin/sh
cd /var/www/html
php registration_update.php
Provádění každou minutu přes cron:
* * * * * registration_update.sh
Třída Server
Ke správnému spuštění je pak ještě nutné doplnit třídu obstarávající užitečné funkce k serveru server.php. Zde jsou alespoň nejnutnější funkce:
class Server
{
private $db;
private $Config;
public function __construct($db, $Config)
{
$this->db = $db;
$this->Config = $Config;
}
public function RealmOnline()
{
$this->db->select_db($this->Config['Mangos']['DatabaseRealmd']);
$DbResult = $this->db->query('SELECT COUNT(*) FROM `account` WHERE `online` = 1');
$DbRow = $DbResult->fetch_row();
return($DbRow[0]);
}
public function AccountCount()
{
$this->db->select_db($this->Config['Mangos']['DatabaseRealmd']);
$row = $this->db->query('SELECT COUNT(*) FROM account')->fetch_row();
return($row[0]);
}
}
Zobrazení a kontrola stavu
Nakonec na stránce Registrace lze pak už jednoduše povolovat registrace a zobrazit jejich stav.
<?php
include('server.php');
include('registration_limit.php');
include('config.php');
$db = new mysqli($Config['Database']['Host'], $Config['Database']['User'], $Config['Database']['Password'], $Config['Database']['Database']);
$Server = new Server($db, $Config);
$RegistrationLimit = new RegistrationLimit($db, $Server, $Config);
echo('Dnes celkem povolených registrací: '.$RegistrationLimit->GetPerDeyRegistrationCount().'<br/>');
echo('Dnes zbývajících registrací: '.$RegistrationLimit->GetFreeRegistrationCount().'<br/>');
echo('<br/>');
if($RegistrationLimit->GetFreeRegistrationCount() > 0)
{
// Zobrazení registračního formuláře
} else
{
// Registrace nejsou povoleny
}
?>