Skip to content

Commit

Permalink
Merge branch 'master' into seasons-score-calculation
Browse files Browse the repository at this point in the history
nanaya authored Jan 28, 2025
2 parents 106781a + 242079c commit c60df78
Showing 64 changed files with 1,576 additions and 832 deletions.
104 changes: 51 additions & 53 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -25,6 +25,8 @@ module.exports = {
'typescript-sort-keys',
],
rules: {
'@stylistic/member-delimiter-style': 'error',
'@stylistic/type-annotation-spacing': 'error',
'@typescript-eslint/array-type': [
'error',
{
@@ -41,20 +43,6 @@ module.exports = {
},
],
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/indent': [
'error',
2,
{
FunctionDeclaration: {
parameters: 'first',
},
FunctionExpression: {
parameters: 'first',
},
SwitchCase: 1,
},
],
'@typescript-eslint/member-delimiter-style': 'error',
'@typescript-eslint/member-ordering': [
'error',
{
@@ -101,17 +89,17 @@ module.exports = {
'@typescript-eslint/no-unsafe-member-access': 'warn',
'@typescript-eslint/no-unsafe-return': 'warn',
'@typescript-eslint/no-unused-expressions': 'error',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', ignoreRestSiblings: true }],
'@typescript-eslint/no-unused-vars': [
'error', {
argsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
ignoreRestSiblings: true,
},
],
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/object-curly-spacing': ['error', 'always'],
'@typescript-eslint/prefer-for-of': 'error',
'@typescript-eslint/prefer-function-type': 'error',
'@typescript-eslint/prefer-readonly': 'error',
'@typescript-eslint/quotes': [
'error',
'single',
{ avoidEscape: true },
],
'@typescript-eslint/restrict-template-expressions': [
'error',
{
@@ -121,21 +109,17 @@ module.exports = {
allowNumber: true,
},
],
'@typescript-eslint/semi': ['error', 'always'],
// TODO: make more strict.
'@typescript-eslint/strict-boolean-expressions': [
'error',
{
allowNullableBoolean: true,
},
],
'@typescript-eslint/type-annotation-spacing': 'error',
'@typescript-eslint/unified-signatures': 'error',
'dot-notation': 'off',
'no-invalid-this': 'off',
'no-shadow': 'off',
'object-curly-spacing': 'off',
quotes: 'off',
'react-hooks/exhaustive-deps': 'error',
'react/jsx-boolean-value': 'error',
'react/jsx-curly-spacing': 'error',
@@ -190,22 +174,57 @@ module.exports = {
sourceType: 'module',
},
plugins: [
'@stylistic',
'eslint-plugin-jsdoc',
'eslint-plugin-import',
],
rules: {
'@stylistic/arrow-parens': 'error',
'@stylistic/arrow-spacing': 'error',
'@stylistic/brace-style': 'error',
'@stylistic/comma-dangle': ['error', 'always-multiline'],
'@stylistic/eol-last': 'error',
'@stylistic/indent': [
'error',
2,
{
FunctionDeclaration: {
parameters: 'first',
},
FunctionExpression: {
parameters: 'first',
},
SwitchCase: 1,
},
],
'@stylistic/max-len': 'off',
'@stylistic/new-parens': 'error',
'@stylistic/no-multiple-empty-lines': 'error',
'@stylistic/no-trailing-spaces': 'error',
'@stylistic/object-curly-spacing': ['error', 'always'],
'@stylistic/quote-props': ['error', 'as-needed'],
'@stylistic/quotes': [
'error',
'single',
{ avoidEscape: true },
],
'@stylistic/semi': ['error', 'always'],
'@stylistic/space-before-function-paren': [
'error',
{
anonymous: 'never',
asyncArrow: 'always',
named: 'never',
},
],
'@stylistic/spaced-comment': 'error',
'arrow-body-style': 'error',
'arrow-parens': 'error',
'arrow-spacing': 'error',
'brace-style': 'error',
'comma-dangle': ['error', 'always-multiline'],
complexity: 'off',
curly: ['error', 'multi-line'],
'dot-notation': 'error',
'eol-last': 'error',
eqeqeq: ['error', 'smart'],
'guard-for-in': 'error',
'id-blacklist': [
'id-denylist': [
'error',
'any',
'Number',
@@ -221,43 +240,22 @@ module.exports = {
'import/order': ['error', { alphabetize: { order: 'asc' } }],
'jsdoc/check-alignment': 'error',
'jsdoc/check-indentation': 'error',
'jsdoc/newline-after-description': 'error',
'jsdoc/tag-lines': ['error', 'never', { startLines: 1 }],
'max-classes-per-file': 'error',
'max-len': 'off',
'new-parens': 'error',
'no-bitwise': 'error',
'no-caller': 'error',
'no-console': ['error', { allow: ['error', 'warn'] }],
'no-empty-function': 'error',
'no-eval': 'error',
'no-invalid-this': 'error',
'no-multiple-empty-lines': 'error',
'no-new-wrappers': 'error',
'no-shadow': ['error', { hoist: 'all' }],
'no-throw-literal': 'error',
'no-trailing-spaces': 'error',
'no-undef-init': 'error',
'no-unsafe-finally': 'error',
'object-curly-spacing': ['error', 'always'],
'object-shorthand': 'error',
'one-var': ['error', 'never'],
'quote-props': ['error', 'as-needed'],
quotes: [
'error',
'single',
{ avoidEscape: true },
],
radix: 'error',
semi: ['error', 'always'],
'sort-keys': ['error', 'asc', { caseSensitive: false }],
'space-before-function-paren': [
'error',
{
anonymous: 'never',
asyncArrow: 'always',
named: 'never',
},
],
'spaced-comment': 'error',
},
};
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -49,7 +49,7 @@ jobs:
- name: Install js dependencies
run: yarn --frozen-lockfile

- run: 'yarn lint --max-warnings 87 > /dev/null'
- run: 'yarn lint --max-warnings 82 > /dev/null'

- run: yarn pretty

15 changes: 12 additions & 3 deletions app/Http/Controllers/InterOp/Multiplayer/RoomsController.php
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@
use App\Http\Controllers\Controller;
use App\Models\Multiplayer\Room;
use App\Models\User;
use App\Transformers\Multiplayer\RoomTransformer;

class RoomsController extends Controller
{
@@ -20,7 +19,17 @@ public function join(string $id, string $userId)
$room->assertCorrectPassword(get_string(request('password')));
$room->join($user);

return RoomTransformer::createShowResponse($room);
return response(null, 204);
}

public function part(string $id, string $userId)
{
$user = User::findOrFail($userId);
$room = Room::findOrFail($id);

$room->part($user);

return response(null, 204);
}

public function store()
@@ -30,6 +39,6 @@ public function store()

$room = (new Room())->startGame($user, $params);

return RoomTransformer::createShowResponse($room);
return $room->getKey();
}
}
6 changes: 4 additions & 2 deletions app/Http/Controllers/Multiplayer/RoomsController.php
Original file line number Diff line number Diff line change
@@ -138,12 +138,14 @@ public function leaderboard($roomId)

public function part($roomId, $userId)
{
$currentUser = \Auth::user();
// this allows admins/host/whoever to remove users from games in the future
if (get_int($userId) !== auth()->user()->user_id) {
if (get_int($userId) !== $currentUser->getKey()) {
abort(403);
}

Room::findOrFail($roomId)->channel->removeUser(auth()->user());
$room = Room::findOrFail($roomId);
$room->part($currentUser);

return response([], 204);
}
2 changes: 1 addition & 1 deletion app/Libraries/OsuWiki.php
Original file line number Diff line number Diff line change
@@ -148,7 +148,7 @@ private function fetch(): array
} catch (GithubException $e) {
$message = $e->getMessage();

if ($message === 'Not Found') {
if ($e->getCode() === 404) {
throw new GitHubNotFoundException($message);
} elseif (starts_with($message, 'This API returns blobs up to 1 MB in size.')) {
throw new GitHubTooLargeException($message);
5 changes: 5 additions & 0 deletions app/Models/Multiplayer/Room.php
Original file line number Diff line number Diff line change
@@ -525,6 +525,11 @@ public function join(User $user)
$this->channel->addUser($user);
}

public function part(User $user)
{
$this->channel->removeUser($user);
}

public function participants(): HasMany
{
$query = $this->userHighScores();
34 changes: 17 additions & 17 deletions app/Models/User.php
Original file line number Diff line number Diff line change
@@ -318,24 +318,24 @@ public function getAuthPassword()

public function usernameChangeCost()
{
$changesToDate = $this->usernameChangeHistory()
->whereIn('type', ['support', 'paid'])
->count();
$minTier = $this->usernameChangeHistory()->paid()->exists() ? 1 : 0;

$tier = max(
$this->usernameChangeHistory()
->paid()
->where('timestamp', '>', Carbon::now()->subYears(3))
->count(),
$minTier,
);

switch ($changesToDate) {
case 0:
return 0;
case 1:
return 8;
case 2:
return 16;
case 3:
return 32;
case 4:
return 64;
default:
return 100;
}
return match ($tier) {
0 => 0,
1 => 8,
2 => 16,
3 => 32,
4 => 64,
default => 100,
};
}

public function revertUsername($type = 'revert'): UsernameChangeHistory
7 changes: 5 additions & 2 deletions app/Models/UserProfileCustomization.php
Original file line number Diff line number Diff line change
@@ -85,7 +85,7 @@ public static function forUser(?User $user): array|static
return $ret;
}

public static function repairExtrasOrder($value)
public static function repairExtrasOrder(array $value): array
{
// read from inside out
return array_values(
@@ -316,7 +316,10 @@ public function getExtrasOrderAttribute($value)
public function setExtrasOrderAttribute($value)
{
$this->attributes['extras_order'] = null;
$this->setOption('extras_order', static::repairExtrasOrder($value));
$this->setOption(
'extras_order',
$value === null ? null : static::repairExtrasOrder($value),
);
}

public function getProfileCoverExpandedAttribute()
5 changes: 5 additions & 0 deletions app/Models/UsernameChangeHistory.php
Original file line number Diff line number Diff line change
@@ -21,6 +21,11 @@ class UsernameChangeHistory extends Model
protected $table = 'osu_username_change_history';
protected $primaryKey = 'change_id';

public function scopePaid($query)
{
$query->whereIn('type', ['support', 'paid']); // changed by support counts as paid.
}

public function scopeVisible($query)
{
$query->whereIn('type', ['support', 'paid', 'admin']);
31 changes: 31 additions & 0 deletions database/factories/UsernameChangeHistoryFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?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 Database\Factories;

use App\Models\User;
use App\Models\UsernameChangeHistory;
use Carbon\Carbon;

class UsernameChangeHistoryFactory extends Factory
{
protected $model = UsernameChangeHistory::class;

public function definition(): array
{
return [
'timestamp' => Carbon::now(),
'type' => 'paid',
'user_id' => User::factory(),

// depend on user_id; the username will be incorrect when factorying multiple names at once,
// so they should be handled separately if realistic name changes are wanted.
'username' => fn (array $attr) => User::find($attr['user_id'])->username,
'username_last' => fn (array $attr) => "{$attr['username']}_prev",
];
}
}
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -50,8 +50,8 @@ services:
<<: *x-web
volumes:
- .:/app
- .docker/js-build/assets:/app/public/assets
- .docker/js-build/builds:/app/resources/builds
- ./storage/testjs-assets:/app/public/assets
- ./storage/testjs-builds:/app/resources/builds
profiles: ['testjs']
command: ['test', 'js']

2 changes: 1 addition & 1 deletion docker/development/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -8,6 +8,6 @@ if [ "$uid" != 0 ]; then
groupmod -g "$gid" -o osuweb > /dev/null
fi

chown -f "${uid}:${gid}" .docker/js-build/assets .docker/js-build/builds
chown -f "${uid}:${gid}" ./storage/testjs-*

exec gosu osuweb ./docker/development/run.sh "$@"
Loading

0 comments on commit c60df78

Please sign in to comment.