Skip to content

Commit

Permalink
Merge branches 'score-structure-v44', 'score-solo-index', 'beatmap-pa…
Browse files Browse the repository at this point in the history
…ck-es', 'user-scores', 'solo-profile-recent', 'solo-profile', 'search-rank-table', 'score-legacy-toggle-ui' and 'client-check-2' into private-staging-v2
  • Loading branch information
nanaya committed Jan 24, 2024
10 parents 5e792d1 + 1a3a815 + c26977f + 868fbd6 + f76dc8b + c98a79d + b9ab1a4 + a9c61ec + 9457af8 + f49a64c commit c7f616c
Show file tree
Hide file tree
Showing 58 changed files with 1,189 additions and 1,113 deletions.
12 changes: 12 additions & 0 deletions app/Exceptions/ClientCheckParseTokenException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the GNU Affero General Public License v3.0.
// See the LICENCE file in the repository root for full licence text.

declare(strict_types=1);

namespace App\Exceptions;

class ClientCheckParseTokenException extends \Exception
{
}
8 changes: 6 additions & 2 deletions app/Http/Controllers/BeatmapPacksController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

namespace App\Http\Controllers;

use App\Libraries\Search\ScoreSearchParams;
use App\Models\Beatmap;
use App\Models\BeatmapPack;
use App\Transformers\BeatmapPackTransformer;
use Auth;

/**
* @group Beatmap Packs
Expand Down Expand Up @@ -100,7 +100,11 @@ public function show($idOrTag)
$pack = $query->where('tag', $idOrTag)->firstOrFail();
$mode = Beatmap::modeStr($pack->playmode ?? 0);
$sets = $pack->beatmapsets;
$userCompletionData = $pack->userCompletionData(Auth::user());
$currentUser = \Auth::user();
$userCompletionData = $pack->userCompletionData(
$currentUser,
ScoreSearchParams::showLegacyForUser($currentUser),
);

if (is_api_request()) {
return json_item(
Expand Down
217 changes: 99 additions & 118 deletions app/Http/Controllers/BeatmapsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
use App\Jobs\Notifications\BeatmapOwnerChange;
use App\Libraries\BeatmapDifficultyAttributes;
use App\Libraries\Score\BeatmapScores;
use App\Libraries\Score\UserRank;
use App\Libraries\Search\ScoreSearch;
use App\Libraries\Search\ScoreSearchParams;
use App\Models\Beatmap;
use App\Models\BeatmapsetEvent;
use App\Models\Score\Best\Model as BestModel;
Expand Down Expand Up @@ -51,6 +54,66 @@ private static function baseScoreQuery(Beatmap $beatmap, $mode, $mods, $type = n
return $query;
}

private static function beatmapScores(string $id, ?string $scoreTransformerType, ?bool $isLegacy): array
{
$beatmap = Beatmap::findOrFail($id);
if ($beatmap->approved <= 0) {
return ['scores' => []];
}

$params = get_params(request()->all(), null, [
'limit:int',
'mode',
'mods:string[]',
'type:string',
], ['null_missing' => true]);

if ($params['mode'] !== null) {
$rulesetId = Beatmap::MODES[$params['mode']] ?? null;
if ($rulesetId === null) {
throw new InvariantException('invalid mode specified');
}
}
$rulesetId ??= $beatmap->playmode;
$mods = array_values(array_filter($params['mods'] ?? []));
$type = presence($params['type'], 'global');
$currentUser = \Auth::user();

static::assertSupporterOnlyOptions($currentUser, $type, $mods);

$esFetch = new BeatmapScores([
'beatmap_ids' => [$beatmap->getKey()],
'is_legacy' => $isLegacy,
'limit' => $params['limit'],
'mods' => $mods,
'ruleset_id' => $rulesetId,
'type' => $type,
'user' => $currentUser,
]);
$scores = $esFetch->all()->loadMissing(['beatmap', 'user.country', 'user.userProfileCustomization']);
$userScore = $esFetch->userBest();
$scoreTransformer = new ScoreTransformer($scoreTransformerType);

$results = [
'scores' => json_collection(
$scores,
$scoreTransformer,
static::DEFAULT_SCORE_INCLUDES
),
];

if (isset($userScore)) {
$results['user_score'] = [
'position' => $esFetch->rank($userScore),
'score' => json_item($userScore, $scoreTransformer, static::DEFAULT_SCORE_INCLUDES),
];
// TODO: remove this old camelCased json field
$results['userScore'] = $results['user_score'];
}

return $results;
}

public function __construct()
{
parent::__construct();
Expand Down Expand Up @@ -280,7 +343,7 @@ public function show($id)
/**
* Get Beatmap scores
*
* Returns the top scores for a beatmap
* Returns the top scores for a beatmap. Depending on user preferences, this may only show legacy scores.
*
* ---
*
Expand All @@ -296,60 +359,18 @@ public function show($id)
*/
public function scores($id)
{
$beatmap = Beatmap::findOrFail($id);
if ($beatmap->approved <= 0) {
return ['scores' => []];
}

$params = get_params(request()->all(), null, [
'limit:int',
'mode:string',
'mods:string[]',
'type:string',
], ['null_missing' => true]);

$mode = presence($params['mode']) ?? $beatmap->mode;
$mods = array_values(array_filter($params['mods'] ?? []));
$type = presence($params['type']) ?? 'global';
$currentUser = auth()->user();

static::assertSupporterOnlyOptions($currentUser, $type, $mods);

$query = static::baseScoreQuery($beatmap, $mode, $mods, $type);

if ($currentUser !== null) {
// own score shouldn't be filtered by visibleUsers()
$userScore = (clone $query)->where('user_id', $currentUser->user_id)->first();
}

$scoreTransformer = new ScoreTransformer();

$results = [
'scores' => json_collection(
$query->visibleUsers()->forListing($params['limit']),
$scoreTransformer,
static::DEFAULT_SCORE_INCLUDES
),
];

if (isset($userScore)) {
$results['user_score'] = [
'position' => $userScore->userRank(compact('type', 'mods')),
'score' => json_item($userScore, $scoreTransformer, static::DEFAULT_SCORE_INCLUDES),
];
// TODO: remove this old camelCased json field
$results['userScore'] = $results['user_score'];
}

return $results;
return static::beatmapScores(
$id,
null,
// TODO: change to imported name after merge with other PRs
\App\Libraries\Search\ScoreSearchParams::showLegacyForUser(\Auth::user()),
);
}

/**
* Get Beatmap scores (temp)
* Get Beatmap scores (non-legacy)
*
* Returns the top scores for a beatmap from newer client.
*
* This is a temporary endpoint.
* Returns the top scores for a beatmap.
*
* ---
*
Expand All @@ -359,68 +380,14 @@ public function scores($id)
*
* @urlParam beatmap integer required Id of the [Beatmap](#beatmap).
*
* @queryParam legacy_only Set to true to only return legacy scores. Example: 0
* @queryParam mode The [Ruleset](#ruleset) to get scores for.
* @queryParam mods An array of matching Mods, or none // TODO.
* @queryParam type Beatmap score ranking type // TODO.
*/
public function soloScores($id)
{
$beatmap = Beatmap::findOrFail($id);
if ($beatmap->approved <= 0) {
return ['scores' => []];
}

$params = get_params(request()->all(), null, [
'limit:int',
'mode',
'mods:string[]',
'type:string',
], ['null_missing' => true]);

if ($params['mode'] !== null) {
$rulesetId = Beatmap::MODES[$params['mode']] ?? null;
if ($rulesetId === null) {
throw new InvariantException('invalid mode specified');
}
}
$rulesetId ??= $beatmap->playmode;
$mods = array_values(array_filter($params['mods'] ?? []));
$type = presence($params['type'], 'global');
$currentUser = auth()->user();

static::assertSupporterOnlyOptions($currentUser, $type, $mods);

$esFetch = new BeatmapScores([
'beatmap_ids' => [$beatmap->getKey()],
'is_legacy' => false,
'limit' => $params['limit'],
'mods' => $mods,
'ruleset_id' => $rulesetId,
'type' => $type,
'user' => $currentUser,
]);
$scores = $esFetch->all()->loadMissing(['beatmap', 'performance', 'user.country', 'user.userProfileCustomization']);
$userScore = $esFetch->userBest();
$scoreTransformer = new ScoreTransformer(ScoreTransformer::TYPE_SOLO);

$results = [
'scores' => json_collection(
$scores,
$scoreTransformer,
static::DEFAULT_SCORE_INCLUDES
),
];

if (isset($userScore)) {
$results['user_score'] = [
'position' => $esFetch->rank($userScore),
'score' => json_item($userScore, $scoreTransformer, static::DEFAULT_SCORE_INCLUDES),
];
// TODO: remove this old camelCased json field
$results['userScore'] = $results['user_score'];
}

return $results;
return static::beatmapScores($id, ScoreTransformer::TYPE_SOLO, null);
}

public function updateOwner($id)
Expand Down Expand Up @@ -481,13 +448,25 @@ public function userScore($beatmapId, $userId)
$mode = presence($params['mode'] ?? null, $beatmap->mode);
$mods = array_values(array_filter($params['mods'] ?? []));

$score = static::baseScoreQuery($beatmap, $mode, $mods)
->visibleUsers()
->where('user_id', $userId)
->firstOrFail();
$baseParams = ScoreSearchParams::fromArray([
'beatmap_ids' => [$beatmap->getKey()],
'is_legacy' => ScoreSearchParams::showLegacyForUser(\Auth::user()),
'limit' => 1,
'mods' => $mods,
'ruleset_id' => Beatmap::MODES[$mode],
'sort' => 'score_desc',
'user_id' => (int) $userId,
]);
$score = (new ScoreSearch($baseParams))->records()->first();
abort_if($score === null, 404);

$rankParams = clone $baseParams;
$rankParams->beforeScore = $score;
$rankParams->userId = null;
$rank = UserRank::getRank($rankParams);

return [
'position' => $score->userRank(compact('mods')),
'position' => $rank,
'score' => json_item(
$score,
new ScoreTransformer(),
Expand Down Expand Up @@ -518,12 +497,14 @@ public function userScoreAll($beatmapId, $userId)
{
$beatmap = Beatmap::scoreable()->findOrFail($beatmapId);
$mode = presence(get_string(request('mode'))) ?? $beatmap->mode;
$scores = BestModel::getClass($mode)
::default()
->where([
'beatmap_id' => $beatmap->getKey(),
'user_id' => $userId,
])->get();
$params = ScoreSearchParams::fromArray([
'beatmap_ids' => [$beatmap->getKey()],
'is_legacy' => ScoreSearchParams::showLegacyForUser(\Auth::user()),
'ruleset_id' => Beatmap::MODES[$mode],
'sort' => 'score_desc',
'user_id' => (int) $userId,
]);
$scores = (new ScoreSearch($params))->records();

return [
'scores' => json_collection($scores, new ScoreTransformer()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,10 @@ public function store($roomId, $playlistId)
$room = Room::findOrFail($roomId);
$playlistItem = $room->playlist()->where('id', $playlistId)->firstOrFail();
$user = auth()->user();
$params = request()->all();
$request = \Request::instance();
$params = $request->all();

$buildId = ClientCheck::findBuild($user, $params)?->getKey()
?? $GLOBALS['cfg']['osu']['client']['default_build_id'];
$buildId = ClientCheck::parseToken($request)['buildId'];

$scoreToken = $room->startPlay($user, $playlistItem, $buildId);

Expand All @@ -181,6 +181,8 @@ public function store($roomId, $playlistId)
*/
public function update($roomId, $playlistItemId, $tokenId)
{
$request = \Request::instance();
$clientTokenData = ClientCheck::parseToken($request);
$scoreLink = \DB::transaction(function () use ($roomId, $playlistItemId, $tokenId) {
$room = Room::findOrFail($roomId);

Expand All @@ -202,15 +204,14 @@ public function update($roomId, $playlistItemId, $tokenId)
});

$score = $scoreLink->score;
$transformer = ScoreTransformer::newSolo();
if ($score->wasRecentlyCreated) {
$scoreJson = json_item($score, $transformer);
$score::queueForProcessing($scoreJson);
ClientCheck::queueToken($clientTokenData, $score->getKey());
$score->queueForProcessing();
}

return json_item(
$scoreLink,
$transformer,
ScoreTransformer::newSolo(),
[
...ScoreTransformer::MULTIPLAYER_BASE_INCLUDES,
'position',
Expand Down
8 changes: 4 additions & 4 deletions app/Http/Controllers/ScoreTokensController.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ public function store($beatmapId)
{
$beatmap = Beatmap::increasesStatistics()->findOrFail($beatmapId);
$user = auth()->user();
$rawParams = request()->all();
$params = get_params($rawParams, null, [
$request = \Request::instance();
$params = get_params($request->all(), null, [
'beatmap_hash',
'ruleset_id:int',
]);
Expand All @@ -43,12 +43,12 @@ public function store($beatmapId)
}
}

$build = ClientCheck::findBuild($user, $rawParams);
$buildId = ClientCheck::parseToken($request)['buildId'];

try {
$scoreToken = ScoreToken::create([
'beatmap_id' => $beatmap->getKey(),
'build_id' => $build?->getKey() ?? $GLOBALS['cfg']['osu']['client']['default_build_id'],
'build_id' => $buildId,
'ruleset_id' => $params['ruleset_id'],
'user_id' => $user->getKey(),
]);
Expand Down
Loading

0 comments on commit c7f616c

Please sign in to comment.