Skip to content

Commit e02d92b

Browse files
committed
active matches V2 API
1 parent ad87361 commit e02d92b

File tree

3 files changed

+182
-8
lines changed

3 files changed

+182
-8
lines changed

cncnet-api/app/Helpers/SiteHelper.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Carbon\Carbon;
77
use Exception;
88
use Illuminate\Support\Facades\Log;
9+
use App\Models\Map;
910

1011
class SiteHelper
1112
{
@@ -61,6 +62,28 @@ public static function getMapPreviewUrl($history, $map, $hash)
6162
}
6263
}
6364

65+
public static function getMapPreviewUrlV2(string $game, Map $map)
66+
{
67+
try {
68+
if (!$map) {
69+
return "";
70+
}
71+
72+
$description = $map->description ?? '';
73+
$imageHash = $map->image_hash ?: $map->hash;
74+
75+
if (!$imageHash) {
76+
return "";
77+
}
78+
79+
return "https://ladder.cncnet.org/images/maps/{$game}/{$imageHash}.png";
80+
} catch (Exception $ex) {
81+
Log::info("Error fetching map preview url for map='$description', ladder='$game'");
82+
return "";
83+
}
84+
}
85+
86+
6487
public static function getEmojiByMonth()
6588
{
6689
$now = Carbon::now();

cncnet-api/app/Http/Controllers/ApiQuickMatchController.php

Lines changed: 158 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use App\Helpers\AIHelper;
77
use App\Helpers\GameHelper;
88
use App\Helpers\LeagueHelper;
9+
use App\Helpers\SiteHelper;
910
use App\Http\Services\LadderService;
1011
use App\Http\Services\PlayerService;
1112
use App\Http\Services\QuickMatchService;
@@ -57,7 +58,8 @@ public function statsRequest(Request $request, string $ladderAbbrev = null, int
5758
$ladders = \App\Models\Ladder::query()
5859
->where('private', '=', false)
5960
->with([
60-
'current_history' => function($q) {
61+
'current_history' => function ($q)
62+
{
6163
$q->with([
6264
'queued_players'
6365
]);
@@ -97,14 +99,15 @@ public function statsRequest(Request $request, string $ladderAbbrev = null, int
9799
}
98100

99101
return $allStats;
100-
}
101-
else
102+
}
103+
else
102104
{
103105
return $this->getStats($ladderAbbrev, $tierId);
104106
}
105107
}
106108

107-
private function getStats(Ladder|string $ladder, int $tierId = 1) {
109+
private function getStats(Ladder|string $ladder, int $tierId = 1)
110+
{
108111
$ladder = is_string($ladder) ? $this->ladderService->getLadderByGame($ladder) : $ladder;
109112
$history = $ladder->current_history;
110113
$qmStats = $this->statsService->getQmStats($history, $tierId);
@@ -131,7 +134,8 @@ public function getActiveMatches(Request $request, $ladderAbbrev = null)
131134
$ladders = \App\Models\Ladder::query()
132135
->where('private', '=', false)
133136
->with([
134-
'current_history' => function($q) {
137+
'current_history' => function ($q)
138+
{
135139
},
136140
])
137141
->with([
@@ -167,6 +171,58 @@ public function getActiveMatches(Request $request, $ladderAbbrev = null)
167171
return $games;
168172
}
169173

174+
/**
175+
* This V2 function will return the data as json array, where each object in the array is an object.
176+
* V1 returns array of strings.
177+
*/
178+
public function getActiveMatchesV2(Request $request, string $ladderAbbrev)
179+
{
180+
$games = [];
181+
if ($ladderAbbrev == "all")
182+
{
183+
$ladders = Ladder::query()
184+
->where('private', '=', false)
185+
->with([
186+
'current_history' => function ()
187+
{
188+
},
189+
'sides',
190+
'recent_spawned_matches',
191+
'recent_spawned_matches.players',
192+
'recent_spawned_matches.players.clan:id,short',
193+
'recent_spawned_matches.players.player:id,username',
194+
'recent_spawned_matches.map',
195+
])
196+
->get();
197+
198+
$ladders->each(function (Ladder $ladder) use (&$games)
199+
{
200+
$games[$ladder->abbreviation] = $this->getActiveMatchesByLadderV2($ladder);
201+
});
202+
}
203+
else
204+
{
205+
$ladder = Ladder::query()
206+
->where('abbreviation', '=', $ladderAbbrev)
207+
->with([
208+
'current_history' => function ($q)
209+
{
210+
},
211+
'sides',
212+
'recent_spawned_matches',
213+
'recent_spawned_matches.players',
214+
'recent_spawned_matches.players.clan:id,short',
215+
'recent_spawned_matches.players.player:id,username',
216+
'recent_spawned_matches.map',
217+
])
218+
->first();
219+
220+
$games[$ladder->abbreviation] = $this->getActiveMatchesByLadderV2($ladder);
221+
}
222+
223+
return $games;
224+
}
225+
170226
private function getActiveMatchesByLadder(Ladder|string $ladder)
171227
{
172228
$ladder = is_string($ladder) ? $this->ladderService->getLadderByGame($ladder) : $ladder;
@@ -210,6 +266,58 @@ private function getActiveMatchesByLadder(Ladder|string $ladder)
210266
return $games;
211267
}
212268

269+
private function getActiveMatchesByLadderV2(Ladder $ladder)
270+
{
271+
$sides = $ladder->sides->pluck('name', 'local_id')->toArray();
272+
273+
if ($ladder == null)
274+
{
275+
abort(400, "Invalid ladder provided");
276+
}
277+
278+
//get all recent QMs that whose games have spawned. (state_type_id == 5)
279+
$qms = $ladder->recent_spawned_matches;
280+
281+
$games = [];
282+
283+
foreach ($qms as $qm) //iterate over every active quick match
284+
{
285+
$dt = $qm->created_at;
286+
287+
//get the player data pertaining to this quick match
288+
$qmPlayers = $qm->players;
289+
290+
$playersData = [];
291+
if ($ladder->clans_allowed)
292+
{
293+
$playersData = $this->getActiveClanMatchesData($sides, $qmPlayers);
294+
}
295+
else if ($ladder->ladder_type == Ladder::TWO_VS_TWO) // 2v2
296+
{
297+
$playersData = $this->getTeamActivePlayerMatchesDataV2($sides, $qmPlayers, $qm->created_at);
298+
}
299+
else
300+
{
301+
$playersData = $this->getActivePlayerMatchesDataV2($sides, $qmPlayers, $qm->created_at);
302+
}
303+
304+
$duration = Carbon::now()->diff($dt);
305+
$duration_formatted = $duration->format('%i mins %s sec');
306+
307+
$games[] = [
308+
"ladderName" => $ladder->name,
309+
"ladderType" => $ladder->ladder_type,
310+
"players" => $playersData,
311+
"gameDuration" => $duration_formatted,
312+
"mapName" => trim($qm->map->description),
313+
"mapHash" => $qm->map->map->hash,
314+
"mapUrl" => SiteHelper::getMapPreviewUrlV2($ladder->game, $qm->map->map)
315+
];
316+
}
317+
318+
return $games;
319+
}
320+
213321
private function getActiveClanMatchesData($sides, $players)
214322
{
215323
$clans = [];
@@ -243,7 +351,7 @@ private function getActiveClanMatchesData($sides, $players)
243351
$i = 0;
244352
foreach ($players as $player)
245353
{
246-
$playersString .= '['. $player->clan->short .']' . $player->name . " (" . ($sides[$player->actual_side] ?? '') . ")";
354+
$playersString .= '[' . $player->clan->short . ']' . $player->name . " (" . ($sides[$player->actual_side] ?? '') . ")";
247355

248356
if ($i < count($players) - 1)
249357
$playersString .= " and ";
@@ -279,12 +387,33 @@ private function getActivePlayerMatchesData($sides, $players, $created_at)
279387
return $playersString;
280388
}
281389

390+
/**
391+
* @return an array containing every player's name and their faction
392+
*/
393+
private function getActivePlayerMatchesDataV2(array $sides, $qmPlayers, $created_at)
394+
{
395+
$dt = new DateTime($created_at);
396+
$showRealNames = abs(Carbon::now()->diffInSeconds($dt)) > 120;
397+
398+
return collect($qmPlayers)
399+
->values()
400+
->map(function ($qmPlayer, $index) use ($sides, $showRealNames)
401+
{
402+
return [
403+
"playerName" => $showRealNames ? $qmPlayer->player->username : "Player" . ($index + 1),
404+
"playerFaction" => $sides[$qmPlayer->actual_side] ?? '',
405+
"playerColor" => $qmPlayer->color
406+
];
407+
})
408+
->all();
409+
}
410+
282411
/**
283412
* returns a 'pretty' message describing the players on each team
284413
*
285414
* should probably return a json array with the data but we are where we are
286415
*/
287-
private function getTeamActivePlayerMatchesData($sides, $players, $created_at) // TODO will this logic work for clan ladder?
416+
private function getTeamActivePlayerMatchesData($sides, $players, $created_at)
288417
{
289418
$playersString = "";
290419
$dt = new DateTime($created_at);
@@ -304,7 +433,7 @@ private function getTeamActivePlayerMatchesData($sides, $players, $created_at) /
304433
{
305434
$playerName = "Player" . ($playerNum + 1);
306435
if (abs(Carbon::now()->diffInSeconds($dt)) > 60) //only show real player name if 1 min has passed
307-
{
436+
{
308437
$playerName = $player->player->username;
309438
}
310439
$playersString .= $playerName . " (" . ($sides[$player->actual_side] ?? '') . ")";
@@ -325,6 +454,27 @@ private function getTeamActivePlayerMatchesData($sides, $players, $created_at) /
325454
return $playersString;
326455
}
327456

457+
private function getTeamActivePlayerMatchesDataV2(array $sides, $qmPlayers, $created_at)
458+
{
459+
$dt = new DateTime($created_at);
460+
$showRealNames = abs(Carbon::now()->diffInSeconds($dt)) > 120;
461+
462+
return collect($qmPlayers)
463+
->groupBy('team')
464+
->flatten()
465+
->values()
466+
->map(function ($qmPlayer, $index) use ($sides, $showRealNames)
467+
{
468+
return [
469+
"teamId" => $qmPlayer->team,
470+
"playerName" => $showRealNames ? $qmPlayer->player->username : "Player" . ($index + 1),
471+
"playerFaction" => $sides[$qmPlayer->actual_side] ?? '',
472+
"playerColor" => $qmPlayer->color
473+
];
474+
})
475+
->all();
476+
}
477+
328478
public function mapListRequest(Request $request, $ladderAbbrev = null)
329479
{
330480
return \App\Models\QmMap::findMapsByLadder($this->ladderService->getLadderByGame($ladderAbbrev)->id);

cncnet-api/routes/api.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
Route::get('/qm/ladder/{ladderAbbrev}/stats', [\App\Http\Controllers\ApiQuickMatchController::class, 'statsRequest']);
7777
Route::get('/qm/ladder/{ladderAbbrev}/stats/{tierId}', [\App\Http\Controllers\ApiQuickMatchController::class, 'statsRequest']);
7878
Route::get('/qm/ladder/{ladderAbbrev}/current_matches', [\App\Http\Controllers\ApiQuickMatchController::class, 'getActiveMatches']);
79+
Route::get('/qm/ladder/{ladderAbbrev}/active_matches', [\App\Http\Controllers\ApiQuickMatchController::class, 'getActiveMatchesV2']);
7980
Route::get('/qm/ladder/{ladderAbbrev}/erroredGames', [\App\Http\Controllers\ApiQuickMatchController::class, 'getErroredGames']);
8081
Route::get('/qm/ladder/{ladderAbbrev}/{hours}/recentlyWashedGames', [\App\Http\Controllers\ApiQuickMatchController::class, 'getRecentLadderWashedGamesCount']);
8182
});

0 commit comments

Comments
 (0)