diff --git a/app/Platform/Actions/UpdateGamePlayerCountAction.php b/app/Platform/Actions/UpdateGamePlayerCountAction.php index d5ec102960..04cb01e2d7 100644 --- a/app/Platform/Actions/UpdateGamePlayerCountAction.php +++ b/app/Platform/Actions/UpdateGamePlayerCountAction.php @@ -29,21 +29,26 @@ public function execute(Game $game): void } } - $playersQuery = PlayerGame::whereIn('game_id', $gameIds) - ->leftJoin('unranked_users', 'player_games.user_id', '=', 'unranked_users.user_id') - ->whereNull('unranked_users.id'); - - if (count($gameIds) > 1) { - $playersQuery->distinct('player_games.user_id'); - } + // multi-gameId path means parent + bonus subset; the same user can appear in both, + // so we COUNT(DISTINCT user_id) there instead of SUM-ing rows directly + $isMultiGame = count($gameIds) > 1; + $countExpr = fn (string $column): string => $isMultiGame + ? "COUNT(DISTINCT CASE WHEN player_games.{$column} > 0 THEN player_games.user_id END)" + : "SUM(CASE WHEN player_games.{$column} > 0 THEN 1 ELSE 0 END)"; - $game->players_total = $playersQuery->clone() - ->where('achievements_unlocked', '>', 0) - ->count(); + $row = PlayerGame::query() + ->whereIn('player_games.game_id', $gameIds) + ->leftJoin('unranked_users', 'player_games.user_id', '=', 'unranked_users.user_id') + ->whereNull('unranked_users.id') + ->selectRaw(sprintf( + '%s AS total, %s AS hardcore', + $countExpr('achievements_unlocked'), + $countExpr('achievements_unlocked_hardcore'), + )) + ->first(); - $game->players_hardcore = $playersQuery->clone() - ->where('achievements_unlocked_hardcore', '>', 0) - ->count(); + $game->players_total = (int) ($row->total ?? 0); + $game->players_hardcore = (int) ($row->hardcore ?? 0); if ($game->isDirty()) { $game->saveQuietly();