the browser-facing portion of osu!
1<?php
2
3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
4// See the LICENCE file in the repository root for full licence text.
5
6declare(strict_types=1);
7
8namespace App\Libraries\Score;
9
10use App\Libraries\Search\ScoreSearch;
11use App\Libraries\Search\ScoreSearchParams;
12use App\Models\Solo\Score as SoloScore;
13use Illuminate\Database\Eloquent\Collection;
14
15class BeatmapScores
16{
17 public array $result;
18 private ScoreSearchParams $baseParams;
19
20 public function __construct(private array $rawParams)
21 {
22 $rawParams['limit'] = \Number::clamp($rawParams['limit'] ?? 50, 1, $GLOBALS['cfg']['osu']['beatmaps']['max_scores']);
23 $rawParams['sort'] ??= 'score_desc';
24 $this->baseParams = ScoreSearchParams::fromArray($rawParams);
25 }
26
27 public function all(): Collection
28 {
29 $this->result = (new FetchDedupedScores('user_id', clone $this->baseParams))->all();
30
31 return new Collection(array_values($this->result));
32 }
33
34 public function rank(SoloScore $score): int
35 {
36 if (isset($this->result)) {
37 $userId = $score->user_id;
38 if (isset($this->result[$userId])) {
39 $rank = 0;
40 foreach ($this->result as $checkUserId => $score) {
41 $rank++;
42 if ($userId === $checkUserId) {
43 return $rank;
44 }
45 }
46 }
47 }
48
49 $params = clone $this->baseParams;
50 $params->beforeScore = $score;
51 $params->setSort(null);
52
53 return UserRank::getRank($params);
54 }
55
56 public function userBest(): ?SoloScore
57 {
58 if (!isset($this->baseParams->user)) {
59 return null;
60 }
61
62 $userId = $this->baseParams->user->getKey();
63
64 if (isset($this->result[$userId])) {
65 return $this->result[$userId];
66 }
67
68 $params = clone $this->baseParams;
69 $params->size = 1;
70 $params->userId = $userId;
71 $search = new ScoreSearch($params);
72
73 $search->response();
74 $search->assertNoError();
75
76 return $search->records()[0] ?? null;
77 }
78}