Skip to content

Commit

Permalink
Merge branch 'master' into room-interop
Browse files Browse the repository at this point in the history
  • Loading branch information
notbakaneko authored Jan 20, 2025
2 parents d0be2dc + a159a35 commit b3d621f
Show file tree
Hide file tree
Showing 67 changed files with 602 additions and 238 deletions.
16 changes: 0 additions & 16 deletions app/Http/Controllers/BeatmapTagsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,6 @@ public function __construct()
'destroy',
],
]);

$this->middleware('require-scopes:public', ['only' => 'index']);
}

public function index($beatmapId)
{
$topBeatmapTags = cache_remember_mutexed(
"beatmap_tags:{$beatmapId}",
$GLOBALS['cfg']['osu']['tags']['beatmap_tags_cache_duration'],
[],
fn () => Tag::topTags($beatmapId),
);

return [
'beatmap_tags' => $topBeatmapTags,
];
}

public function destroy($beatmapId, $tagId)
Expand Down
2 changes: 2 additions & 0 deletions app/Http/Controllers/BeatmapsetsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ private function showJson($beatmapset)
'beatmaps.failtimes',
'beatmaps.max_combo',
'beatmaps.owners',
'beatmaps.top_tag_ids',
'converts',
'converts.failtimes',
'converts.owners',
Expand All @@ -415,6 +416,7 @@ private function showJson($beatmapset)
'pack_tags',
'ratings',
'recent_favourites',
'related_tags',
'related_users',
'user',
]);
Expand Down
14 changes: 7 additions & 7 deletions app/Http/Controllers/HomeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use App\Models\NewsPost;
use App\Models\UserDonation;
use App\Transformers\MenuImageTransformer;
use App\Transformers\UserCompactTransformer;
use Auth;
use Jenssegers\Agent\Agent;
use Request;
Expand Down Expand Up @@ -142,12 +143,11 @@ public function quickSearch()
$result[$mode]['total'] = $search->count();
}

$result['user']['users'] = json_collection($searches['user']->data(), 'UserCompact', [
'country',
'cover',
'groups',
'support_level',
]);
$result['user']['users'] = json_collection(
$searches['user']->data(),
new UserCompactTransformer(),
[...UserCompactTransformer::CARD_INCLUDES, 'support_level'],
);
$result['beatmapset']['beatmapsets'] = json_collection($searches['beatmapset']->data(), 'Beatmapset', ['beatmaps']);
}

Expand Down Expand Up @@ -210,7 +210,7 @@ public function setLocale()
]);
}

return ext_view('layout.ujs-reload', [], 'js')
return ext_view('layout.ujs_full_reload', [], 'js')
->withCookie(cookie()->forever('locale', $newLocale));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

namespace App\Http\Controllers\Multiplayer\Rooms\Playlist;

use App\Exceptions\InvariantException;
use App\Http\Controllers\Controller as BaseController;
use App\Libraries\ClientCheck;
use App\Models\Multiplayer\PlaylistItem;
Expand Down Expand Up @@ -182,15 +181,11 @@ public function store($roomId, $playlistId)
$playlistItem = $room->playlist()->findOrFail($playlistId);
$user = \Auth::user();
$request = \Request::instance();
$params = $request->all();

if (get_string($params['beatmap_hash'] ?? null) !== $playlistItem->beatmap->checksum) {
throw new InvariantException(osu_trans('score_tokens.create.beatmap_hash_invalid'));
}

$buildId = ClientCheck::parseToken($request)['buildId'];

$scoreToken = $room->startPlay($user, $playlistItem, $buildId);
$scoreToken = $room->startPlay($user, $playlistItem, [
...$request->all(),
'build_id' => ClientCheck::parseToken($request)['buildId'],
]);

return json_item($scoreToken, new ScoreTokenTransformer());
}
Expand Down
35 changes: 11 additions & 24 deletions app/Http/Controllers/ScoreTokensController.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,33 +29,20 @@ public function store($beatmapId)
$beatmap = Beatmap::increasesStatistics()->findOrFail($beatmapId);
$user = auth()->user();
$request = \Request::instance();
$params = get_params($request->all(), null, [
'beatmap_hash',
'ruleset_id:int',
]);

$checks = [
'beatmap_hash' => fn (string $value): bool => $value === $beatmap->checksum,
'ruleset_id' => fn (int $value): bool => Beatmap::modeStr($value) !== null && $beatmap->canBeConvertedTo($value),
];
foreach ($checks as $key => $testFn) {
if (!isset($params[$key])) {
throw new InvariantException("missing {$key}");
}
if (!$testFn($params[$key])) {
throw new InvariantException("invalid {$key}");
}
}

$buildId = ClientCheck::parseToken($request)['buildId'];
$scoreToken = new ScoreToken([
'beatmap_id' => $beatmap->getKey(),
'build_id' => ClientCheck::parseToken($request)['buildId'],
'user_id' => $user->getKey(),
...get_params($request->all(), null, [
'beatmap_hash',
'ruleset_id:int',
]),
]);
$scoreToken->setRelation('beatmap', $beatmap);

try {
$scoreToken = ScoreToken::create([
'beatmap_id' => $beatmap->getKey(),
'build_id' => $buildId,
'ruleset_id' => $params['ruleset_id'],
'user_id' => $user->getKey(),
]);
$scoreToken->saveOrExplode();
} catch (PDOException $e) {
// TODO: move this to be a validation inside Score model
throw new InvariantException('failed creating score token');
Expand Down
12 changes: 1 addition & 11 deletions app/Http/Controllers/TagsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@

namespace App\Http\Controllers;

use App\Models\Tag;
use App\Transformers\TagTransformer;

class TagsController extends Controller
{
public function __construct()
Expand All @@ -21,15 +18,8 @@ public function __construct()

public function index()
{
$tags = cache_remember_mutexed(
'tags',
$GLOBALS['cfg']['osu']['tags']['tags_cache_duration'],
[],
fn () => Tag::all(),
);

return [
'tags' => json_collection($tags, new TagTransformer()),
'tags' => app('tags')->json(),
];
}
}
11 changes: 11 additions & 0 deletions app/Http/Controllers/TeamsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ public function __construct()
$this->middleware('auth', ['only' => ['part']]);
}

public function destroy(string $id): Response
{
$team = Team::findOrFail($id);
priv_check('TeamUpdate', $team)->ensureCan();

$team->delete();
\Session::flash('popup', osu_trans('teams.destroy.ok'));

return ujs_redirect(route('home'));
}

public function edit(string $id): Response
{
$team = Team::findOrFail($id);
Expand Down
18 changes: 13 additions & 5 deletions app/Http/Controllers/Users/LookupController.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ public function __construct()
public function index()
{
// TODO: referer check?
$ids = array_slice(array_reject_null(get_arr(request('ids'), presence(...)) ?? []), 0, 50);
$params = get_params(\Request::all(), null, [
'exclude_bots:bool',
'ids:string[]',
]);

$ids = array_slice(array_reject_null(get_arr($params['ids'] ?? [], presence(...))), 0, 50);

$numericIds = [];
$stringIds = [];
Expand All @@ -35,13 +40,16 @@ public function index()
}

$users = User::where(fn ($q) => $q->whereIn('user_id', $numericIds)->orWhereIn('username', $stringIds))
->where('group_id', '<>', app('groups')->byIdentifier('no_profile')->getKey())
->default()
->with(UserCompactTransformer::CARD_INCLUDES_PRELOAD)
->get();
->withoutNoProfile()
->with(UserCompactTransformer::CARD_INCLUDES_PRELOAD);

if ($params['exclude_bots'] ?? false) {
$users = $users->withoutBots();
}

return [
'users' => json_collection($users, new UserCompactTransformer(), UserCompactTransformer::CARD_INCLUDES),
'users' => json_collection($users->get(), new UserCompactTransformer(), UserCompactTransformer::CARD_INCLUDES),
];
}
}
2 changes: 1 addition & 1 deletion app/Libraries/Beatmapset/ChangeBeatmapOwners.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function handle(): void

$newUserIds = $this->userIds->diff($currentOwners);

if (User::whereIn('user_id', $newUserIds->toArray())->default()->count() !== $newUserIds->count()) {
if (User::whereIn('user_id', $newUserIds->toArray())->default()->withoutBots()->withoutNoProfile()->count() !== $newUserIds->count()) {
throw new InvariantException('invalid user_id');
}

Expand Down
17 changes: 16 additions & 1 deletion app/Models/Beatmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use App\Exceptions\InvariantException;
use App\Jobs\EsDocument;
use App\Libraries\Transactions\AfterCommit;
use App\Traits\Memoizes;
use DB;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
Expand Down Expand Up @@ -53,7 +54,7 @@
*/
class Beatmap extends Model implements AfterCommit
{
use SoftDeletes;
use Memoizes, SoftDeletes;

public $convert = false;

Expand Down Expand Up @@ -348,6 +349,20 @@ public function status()
return array_search($this->approved, Beatmapset::STATES, true);
}

public function topTagIds()
{
// TODO: Add option to multi query when beatmapset requests all tags for beatmaps?
return $this->memoize(
__FUNCTION__,
fn () => cache_remember_mutexed(
"beatmap_top_tag_ids:{$this->getKey()}",
$GLOBALS['cfg']['osu']['tags']['beatmap_tags_cache_duration'],
[],
fn () => $this->beatmapTags()->topTagIds()->limit(50)->get()->toArray(),
),
);
}

private function getDifficultyrating()
{
if ($this->convert) {
Expand Down
16 changes: 16 additions & 0 deletions app/Models/BeatmapTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,34 @@

namespace App\Models;

use Illuminate\Contracts\Database\Eloquent\Builder;

/**
* @property-read Beatmap $beatmap
* @property int $beatmap_id
* @property \Carbon\Carbon $created_at
* @property int $tag_id
* @property \Carbon\Carbon $updated_at
* @property-read User $user
* @property int $user_id
*/
class BeatmapTag extends Model
{
public $incrementing = false;

protected $primaryKey = ':composite';
protected $primaryKeys = ['beatmap_id', 'tag_id', 'user_id'];

public function scopeTopTagIds(Builder $query)
{
return $query->whereHas('user', fn ($userQuery) => $userQuery->default())
->groupBy('tag_id')
->select('tag_id')
->selectRaw('COUNT(*) as count')
->orderBy('count', 'desc')
->orderBy('tag_id', 'asc');
}

public function beatmap()
{
return $this->belongsTo(Beatmap::class, 'beatmap_id');
Expand Down
10 changes: 10 additions & 0 deletions app/Models/Multiplayer/PlaylistItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* @property int $owner_id
* @property int|null $playlist_order
* @property json|null $required_mods
* @property bool $freestyle
* @property Room $room
* @property int $room_id
* @property int|null $ruleset_id
Expand All @@ -35,6 +36,7 @@ class PlaylistItem extends Model
protected $casts = [
'allowed_mods' => 'object',
'expired' => 'boolean',
'freestyle' => 'boolean',
'required_mods' => 'object',
];

Expand Down Expand Up @@ -64,6 +66,7 @@ public static function fromJsonParams(User $owner, $json)
$obj->$field = $value;
}

$obj->freestyle = get_bool($json['freestyle'] ?? false);
$obj->max_attempts = get_int($json['max_attempts'] ?? null);

$modsHelper = app('mods');
Expand Down Expand Up @@ -169,6 +172,13 @@ private function assertValidRuleset()

private function assertValidMods()
{
if ($this->freestyle) {
if (count($this->allowed_mods) !== 0 || count($this->required_mods) !== 0) {
throw new InvariantException("mod isn't allowed in freestyle");
}
return;
}

$allowedModIds = array_column($this->allowed_mods, 'acronym');
$requiredModIds = array_column($this->required_mods, 'acronym');

Expand Down
Loading

0 comments on commit b3d621f

Please sign in to comment.