Работа с турнирами в dota2-api

Из API можно получить общую информацию по турнирам — идентификатор (используется как matches.leagueid), название, описание и ссылку на официальный сайт.

require_once 'vendor/autoload.php';
require_once 'api-key.php';
 
\Dota2Api\Utils\Request::$apiKey = API_KEY;
 
$leaguesMapperWeb = new \Dota2Api\Mappers\LeaguesMapperWeb();
$leagues = $leaguesMapperWeb->load();
 
$ti6 = $leagues[4664];
echo $ti6->get('leagueid');       // 4664
echo $ti6->get('name');           // 'The International 2016'
echo $ti6->get('description');    // 'Who will emerge victorious? Witness the world's top teams battle at The International.'
echo $ti6->get('tournament_url'); // 'http://www.dota2.com/international/overview/'

У массива $leagues не сквозная нумерация индексов. По сути, индексы в нем — это идентификаторы турниров. Это сделано для более удобного доступа к данным.

Для работы с лигами в БД есть класс Dota2Api\Mappers\LeaguesMapperDb. Запись в БД:

$leaguesMapperDb = new \Dota2Api\Mappers\LeaguesMapperDb();
$leaguesMapperDb->save($ti6, false); // don't override existing data
$leaguesMapperDb->insert($ti6);      // same as previous

Чтение из БД:

$leaguesMapperDb->load(4664);               // load one league
$leaguesMapperDb->load(array(4664, 65000)); // load two leagues
$leaguesMapperDb->load();                   // load all leagues

Удаление из БД:

$leaguesMapperDb->delete(4664);               // delete one league
$leaguesMapperDb->delete(array(4664, 65000)); // delete two leagues

Казалось бы, все разобрали. Но «за бортом» остался один параметр под названием league_tier. Он указывает на ранг турнира:

  1. Amateur
  2. Professional
  3. Premier

По каким-то неведанным причинам его значение не возвращается из API для данных по лигам. Но! Оно доступно из API про текущие турнирные матчи (те, которые играются прямо сейчас). То есть, если мы хотим узнать ранг TI6, то надо дождаться, пока начнется хоть один матч и выполнить следующий код:

$lid = 4664;
$leagueMapper = new \Dota2Api\Mappers\LeagueMapper($lid);
$liveMatches = $leagueMapper->load();
 
if (count($liveMatches)) {
    $ti6Match = $liveMatches[0];
    $league_tier = $ti6Match->get('league_tier');
    $db = Db::obtain();
    $db->updatePDO(Db::realTablename('leagues'), array('league_tier' => $league_tier), array('leagueid' => $lid));
}

Для турниров, которые уже завершились, вышенаписанный код не подходит. Их тип вы можете посмотреть в клиенте игры или же на сайтах со статистикой (dota2statistic.com, dotabuff.com).

Остановимся немного детальнее на LeagueMapper. Что он делает и зачем он нужен? Он загружает из API данные по турнирным играм, которые идут в данный момент. Кстати, это же API использует и trackdota.com. Данные в API обновляются раз в 20 секунд, что дает возможность «держать руку на пульсе» игр. Вообще, из него можно получить довольно много полезных данных, которые не возвращает Dota2Api\Mappers\MatchMapperWeb (потому что их нет в GetMatchDetails). К таким данным относятся (помимо league_tier) поля series_id, series_type, radiant_series_wins, dire_series_wins, league_series_id, league_game_id и еще парочка. Все они указывают на то, что игра является частью Bo1, Bo3 или Bo5, а так же на счет в этой серии. Почему эти же данные не приходят в GetMatchDetails — не понятно. Пример использования:

$leagueMapper = new \Dota2Api\Mappers\LeagueMapper();
/* @var \Dota2Api\Models\LiveMatch */
$liveMatches = $leagueMapper->load();
$oneLiveMatch = $liveMatches[0];
$broadcasters = $oneLiveMatch->get('broadcasters');
echo $oneLiveMatch->get('duration');
echo $oneLiveMatch->get('series_id');
echo $oneLiveMatch->get('series_type');
echo $oneLiveMatch->get('radiant_series_wins');
echo $oneLiveMatch->get('dire_series_wins');
echo $oneLiveMatch->get('league_series_id');
echo $oneLiveMatch->get('league_game_id');
$liveSlots = $oneLiveMatch->getAllSlots();
foreach($liveSlots as $liveSlot) {
    $liveSlot->get('gold_per_min'); // player's GPM for `duration`-moment of the match
    $liveSlot->get('level'); // player's level
}

Для сохранения в БД данных о матче «здесь и сейчас» в dota2-api есть класс Dota2Api\Mappers\LiveMatchMapperDb:

$leagueMapper = new \Dota2Api\Mappers\LeagueMapper();
/* @var \Dota2Api\Models\LiveMatch[] */
$liveMatches = $leagueMapper->load();
$oneLiveMatch = $liveMatches[0];
$liveMatchMapperDb = new Dota2Api\Mappers\LiveMatchMapperDb();
$liveMatchMapperDb->save($oneLiveMatch);
$liveMatchMapperDb->insert($oneLiveMatch); // same as 'save'
$liveMatchMapperDb->update($oneLiveMatch); // same as 'save'

БД не даст сохранить два одинаковых liveMatch. Под «одинаковостью» понимается ситуация, когда у двух liveMatch совпадает match_id и duration. Но, в то же время, никто не запрещает держать в БД сколько угодно liveMatch, которые относятся к одному матчу (одинаковое значение match_id), но в разное его время (разное значение duration). Для загрузки всех таких «временных отпечатков» есть метод load:

$liveMatchMapperDb = new Dota2Api\Mappers\LiveMatchMapperDb();
/* @var \Dota2Api\Models\LiveMatch[] */
$liveMatches = $liveMatchMapperDb->load(123456789);

На основе $liveMatches уже можно смотреть, как менялись те или иные характеристики по ходу матча (например, net worth в матче Ad Finem — The Alliance).

$liveMatchMapperDb = new Dota2Api\Mappers\LiveMatchMapperDb();
/* @var \Dota2Api\Models\LiveMatch[] */
$liveMatches = $liveMatchMapperDb->load(123456789);
$netWorth = array();
foreach ($liveMatches as $liveMatch) {
    $liveSlots = $liveMatch->getAllSlotsDivided();
    $currentNetWorth = array(
        'duration' => $liveMatch->get('duration'),
        'radiant' => array_sum(array_map(function ($slot) {return $slot->get('net_worth');}, $liveSlots['radiant'])),
        'dire' => array_sum(array_map(function ($slot) {return $slot->get('net_worth');}, $liveSlots['dire']))
    );
    array_push($netWorth, $currentNetWorth);
}

Имея на руках такой массив, не составит труда сгенерировать js-код для highcharts или же любой другой библиотеки для построения графиков.

Точно таким же образом можно получить графики по количеству фрагов ($slot->get('kills')), количеству добитых крипов ($slot->get('last_hits')) и т.д.

, ,

Оставить комментарий

Top ↑ | Main page | Back