From 103d21b5effa0f03bd024c9d7232087918b7cdbb Mon Sep 17 00:00:00 2001 From: Exynox Date: Tue, 31 Dec 2024 20:24:15 +0200 Subject: [PATCH] Localized ranking and modified controllers to read data from cache tables. --- .../Highscore/GuildHighscoreController.php | 86 +++++++ .../Highscore/HighscoreController.php | 85 ++++++ app/Models/Enums/CharacterClassEnum.php | 21 ++ app/Models/Enums/CharacterJobEnum.php | 25 ++ app/Models/Enums/EmpireEnum.php | 28 ++ .../Game/Highscore/GuildHighscoreCache.php | 65 +++++ app/Models/Game/Highscore/HighscoreCache.php | 67 +++++ app/Providers/ViewServiceProvider.php | 2 + app/View/Composers/HighscoreComposer.php | 24 ++ lang/en/app/highscore.php | 30 +++ lang/en/app/names.php | 17 ++ lang/ro/app/highscore.php | 30 +++ lang/ro/app/names.php | 17 ++ resources/views/layouts/app.blade.php | 34 ++- resources/views/main/guildhighscore.blade.php | 243 ++++++++---------- resources/views/main/highscore.blade.php | 228 ++++++++-------- routes/web.php | 12 +- 17 files changed, 753 insertions(+), 261 deletions(-) create mode 100644 app/Http/Controllers/Highscore/GuildHighscoreController.php create mode 100644 app/Http/Controllers/Highscore/HighscoreController.php create mode 100644 app/Models/Enums/CharacterClassEnum.php create mode 100644 app/Models/Enums/CharacterJobEnum.php create mode 100644 app/Models/Enums/EmpireEnum.php create mode 100644 app/Models/Game/Highscore/GuildHighscoreCache.php create mode 100644 app/Models/Game/Highscore/HighscoreCache.php create mode 100644 app/View/Composers/HighscoreComposer.php create mode 100644 lang/en/app/highscore.php create mode 100644 lang/en/app/names.php create mode 100644 lang/ro/app/highscore.php create mode 100644 lang/ro/app/names.php diff --git a/app/Http/Controllers/Highscore/GuildHighscoreController.php b/app/Http/Controllers/Highscore/GuildHighscoreController.php new file mode 100644 index 0000000..4fac177 --- /dev/null +++ b/app/Http/Controllers/Highscore/GuildHighscoreController.php @@ -0,0 +1,86 @@ +validate([ + 'guild-choice' => 'nullable', + 'guild-leader-choice' => 'nullable', + ]); + $guildChoice = $validated['guild-choice'] ?? null; + $guildLeaderChoice = $validated['guild-leader-choice'] ?? null; + + // If "guild-choice" was specified, find the guild with that name + if (!empty($guildChoice)) + $where[] = ['name', $guildChoice]; + + // If "guild-leader-choice" was specified, find the guild master with that name + if (!empty($guildLeaderChoice)) + $where[] = ['master', $guildLeaderChoice]; + + $highscore = GuildHighscoreCache::where($where)->paginate(self::RESULTS_PER_PAGE, page: $page); + + return view('main/guildhighscore', [ + 'highscore' => $highscore, + 'empireChoice' => $empireChoice, + 'guildChoice' => $guildChoice, + 'guildLeaderChoice' => $guildLeaderChoice, + ]); + } + + public function search(Request $request): View + { + $where = []; + + $validated = $request->validate([ + 'empire-choice' => 'required|int', + 'guild-choice' => 'nullable', + 'guild-leader-choice' => 'nullable', + ]); + + $empireChoice = (int) $validated['empire-choice']; + $guildChoice = $validated['guild-choice']; + $guildLeaderChoice = $validated['guild-leader-choice']; + + // If "empire-choice" is a valid empire, add it to the query + if (in_array($empireChoice, array_column(EmpireEnum::cases(), 'value'), true)) + $where[] = ['empire', $empireChoice]; + + // If "guild-choice" was specified, find the guild with that name + if (!empty($guildChoice)) + $where[] = ['name', $guildChoice]; + + // If "guild-leader-choice" was specified, find the guild master with that name + if (!empty($guildLeaderChoice)) + $where[] = ['master', $guildLeaderChoice]; + + $highscore = GuildHighscoreCache::where($where)->paginate(self::RESULTS_PER_PAGE); + + return view('main/guildhighscore', [ + 'highscore' => $highscore, + 'empireChoice' => $empireChoice, + 'guildChoice' => $guildChoice, + 'guildLeaderChoice' => $guildLeaderChoice, + ]); + } +} diff --git a/app/Http/Controllers/Highscore/HighscoreController.php b/app/Http/Controllers/Highscore/HighscoreController.php new file mode 100644 index 0000000..90686ff --- /dev/null +++ b/app/Http/Controllers/Highscore/HighscoreController.php @@ -0,0 +1,85 @@ +validate(['character-choice' => 'nullable']); + $characterChoice = $validated['character-choice'] ?? null; + + // If "character-choice" was specified, find the character with that name + if (!empty($characterChoice)) + $where[] = ['name', $characterChoice]; + + $highscore = HighscoreCache::where($where)->paginate(self::RESULTS_PER_PAGE, page: $page); + + return view('main/highscore', [ + 'highscore' => $highscore, + 'empireChoice' => $empireChoice, + 'classChoice' => $classChoice, + 'characterChoice' => $characterChoice, + ]); + } + + public function search(Request $request): View + { + $where = []; + + $validated = $request->validate([ + 'empire-choice' => 'required|int', + 'class-choice' => 'required|int', + 'character-choice' => 'nullable', + ]); + + $empireChoice = (int) $validated['empire-choice']; + $classChoice = (int) $validated['class-choice']; + $characterChoice = $validated['character-choice']; + + // If "empire-choice" is a valid empire, add it to the query + if (in_array($empireChoice, array_column(EmpireEnum::cases(), 'value'), true)) + $where[] = ['empire', $empireChoice]; + + // If "class-choice" is a valid character class, add it to the query + if (in_array($classChoice, array_column(CharacterClassEnum::cases(), 'value'), true)) + $where[] = ['job', $classChoice]; + + // If "character-choice" was specified, find the character with that name + if (!empty($characterChoice)) + $where[] = ['name', $characterChoice]; + + $highscore = HighscoreCache::where($where)->paginate(self::RESULTS_PER_PAGE); + + return view('main/highscore', [ + 'highscore' => $highscore, + 'empireChoice' => $empireChoice, + 'classChoice' => $classChoice, + 'characterChoice' => $characterChoice, + ]); + } +} diff --git a/app/Models/Enums/CharacterClassEnum.php b/app/Models/Enums/CharacterClassEnum.php new file mode 100644 index 0000000..f7ce990 --- /dev/null +++ b/app/Models/Enums/CharacterClassEnum.php @@ -0,0 +1,21 @@ + __('app/names.classes.warrior'), + self::NINJA => __('app/names.classes.ninja'), + self::SURA => __('app/names.classes.sura'), + self::SHAMAN => __('app/names.classes.shaman'), + }; + } +} diff --git a/app/Models/Enums/CharacterJobEnum.php b/app/Models/Enums/CharacterJobEnum.php new file mode 100644 index 0000000..7fda244 --- /dev/null +++ b/app/Models/Enums/CharacterJobEnum.php @@ -0,0 +1,25 @@ + __('app/names.classes.warrior'), + self::NINJA_M, self::NINJA_F => __('app/names.classes.ninja'), + self::SURA_M, self::SURA_F => __('app/names.classes.sura'), + self::SHAMAN_M, self::SHAMAN_F => __('app/names.classes.shaman'), + }; + } +} diff --git a/app/Models/Enums/EmpireEnum.php b/app/Models/Enums/EmpireEnum.php new file mode 100644 index 0000000..3393a40 --- /dev/null +++ b/app/Models/Enums/EmpireEnum.php @@ -0,0 +1,28 @@ + __('app/names.empires.shinsoo'), + self::CHUNJO => __('app/names.empires.chunjo'), + self::JINNO => __('app/names.empires.jinno'), + }; + } + + public function longName(): string + { + return match($this) { + self::SHINSOO => __('app/names.empires.shinsoo.long'), + self::CHUNJO => __('app/names.empires.chunjo.long'), + self::JINNO => __('app/names.empires.jinno.long'), + }; + } +} diff --git a/app/Models/Game/Highscore/GuildHighscoreCache.php b/app/Models/Game/Highscore/GuildHighscoreCache.php new file mode 100644 index 0000000..736a09d --- /dev/null +++ b/app/Models/Game/Highscore/GuildHighscoreCache.php @@ -0,0 +1,65 @@ + + */ + protected $fillable = [ + + ]; + + /** + * The attributes that should be hidden for serialization. + * + * @var array + */ + protected $hidden = [ + + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'empire' => EmpireEnum::class, + 'date' => 'datetime' + ]; +} diff --git a/app/Models/Game/Highscore/HighscoreCache.php b/app/Models/Game/Highscore/HighscoreCache.php new file mode 100644 index 0000000..06dcf80 --- /dev/null +++ b/app/Models/Game/Highscore/HighscoreCache.php @@ -0,0 +1,67 @@ + + */ + protected $fillable = [ + + ]; + + /** + * The attributes that should be hidden for serialization. + * + * @var array + */ + protected $hidden = [ + + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'job' => CharacterClassEnum::class, + 'empire' => EmpireEnum::class, + 'date' => 'datetime' + ]; +} diff --git a/app/Providers/ViewServiceProvider.php b/app/Providers/ViewServiceProvider.php index c3e2969..956a16f 100644 --- a/app/Providers/ViewServiceProvider.php +++ b/app/Providers/ViewServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use App\View\Composers\HighscoreComposer; use App\View\Composers\MallComposer; use App\View\Composers\ThemeComposer; use Illuminate\Support\Facades; @@ -24,5 +25,6 @@ public function boot(): void { Facades\View::composer('layouts.app', ThemeComposer::class); Facades\View::composer('layouts.mall', MallComposer::class); + Facades\View::composer('layouts.app', HighscoreComposer::class); } } diff --git a/app/View/Composers/HighscoreComposer.php b/app/View/Composers/HighscoreComposer.php new file mode 100644 index 0000000..51af545 --- /dev/null +++ b/app/View/Composers/HighscoreComposer.php @@ -0,0 +1,24 @@ +take(10)->get(); + $view->with('topHighscore', $topHighscore); + + // Fetch the top guild highscore + $topGuildHighscore = GuildHighscoreCache::orderBy('id')->take(10)->get(); + $view->with('topGuildHighscore', $topGuildHighscore); + } +} diff --git a/lang/en/app/highscore.php b/lang/en/app/highscore.php new file mode 100644 index 0000000..bb0a091 --- /dev/null +++ b/lang/en/app/highscore.php @@ -0,0 +1,30 @@ + 'Metin2 - Ranking', + + 'search.select-empire' => 'Select empire:', + 'search.all-empires' => '[All empires]', + 'search.select-class' => 'Select class:', + 'search.all-classes' => '[All classes]', + 'search.find-character' => 'Find character:', + 'search.find-guild' => 'Find guild:', + 'search.find-guild-leader' => 'Find guild leader:', + 'search' => 'Search', + + 'no-results' => 'The search returned no results.', + + 'pagination.prev' => 'previous :count ranks', + 'pagination.next' => 'next :count ranks', + + 'header.rank' => 'Rank', + 'header.character-name' => 'Character name', + 'header.guild-name' => 'Guild name', + 'header.guild-leader' => 'Guild leader', + 'header.empire' => 'Empire', + 'header.level' => 'Level', + 'header.exp' => 'EXP', + 'header.guild-points' => 'Points', + + 'update-time' => 'Updated at:' +]; diff --git a/lang/en/app/names.php b/lang/en/app/names.php new file mode 100644 index 0000000..949b315 --- /dev/null +++ b/lang/en/app/names.php @@ -0,0 +1,17 @@ + 'Shinsoo', + 'empires.shinsoo.long' => 'Shinsoo Empire', + 'empires.chunjo' => 'Chunjo', + 'empires.chunjo.long' => 'Chunjo Empire', + 'empires.jinno' => 'Jinno', + 'empires.jinno.long' => 'Jinno Empire', + + // Character class names + 'classes.warrior' => "Warrior", + 'classes.ninja' => "Ninja", + 'classes.sura' => "Sura", + 'classes.shaman' => "Shaman", +]; diff --git a/lang/ro/app/highscore.php b/lang/ro/app/highscore.php new file mode 100644 index 0000000..8509a91 --- /dev/null +++ b/lang/ro/app/highscore.php @@ -0,0 +1,30 @@ + 'Metin2 - Clasament', + + 'search.select-empire' => 'Alege regat:', + 'search.all-empires' => '[Toate regatele]', + 'search.select-class' => 'Alege categoria:', + 'search.all-classes' => '[Toate categoriile]', + 'search.find-character' => 'Caută caracter:', + 'search.find-guild' => 'Caută breaslă:', + 'search.find-guild-leader' => 'Caută lider breaslă:', + 'search' => 'Caută', + + 'no-results' => 'Căutarea nu a întors niciun rezultat.', + + 'pagination.prev' => 'anterioarele :count ranguri', + 'pagination.next' => 'următoarele :count ranguri', + + 'header.rank' => 'Rang', + 'header.character-name' => 'Numele caracterului', + 'header.guild-name' => 'Numele breslei', + 'header.guild-leader' => 'Lider breaslă', + 'header.empire' => 'Regat', + 'header.level' => 'Nivel', + 'header.exp' => 'EXP', + 'header.guild-points' => 'Puncte', + + 'update-time' => 'Actualizat la:' +]; diff --git a/lang/ro/app/names.php b/lang/ro/app/names.php new file mode 100644 index 0000000..9ab8321 --- /dev/null +++ b/lang/ro/app/names.php @@ -0,0 +1,17 @@ + 'Shinsoo', + 'empires.shinsoo.long' => 'Imperiul Shinsoo', + 'empires.chunjo' => 'Chunjo', + 'empires.chunjo.long' => 'Imperiul Chunjo', + 'empires.jinno' => 'Jinno', + 'empires.jinno.long' => 'Imperiul Jinno', + + // Character class names + 'classes.warrior' => "Războinic", + 'classes.ninja' => "Ninja", + 'classes.sura' => "Sura", + 'classes.shaman' => "Șaman", +]; diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 9aa99b8..fa67352 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -364,13 +364,43 @@ function () {

{{ __('app/main.ranking.players') }}

+
    + @foreach ($topHighscore as $entry) +
  • $loop->even])> +
    $entry->empire == \App\Models\Enums\EmpireEnum::SHINSOO, + 'empire2' => $entry->empire == \App\Models\Enums\EmpireEnum::CHUNJO, + 'empire3' => $entry->empire == \App\Models\Enums\EmpireEnum::JINNO + ]) + > + $entry->id < 10])>{{ $entry->id }} $loop->first])>{{ $entry->name }} +
    +
  • + @endforeach +
+
{{ __('app/main.ranking.btn_highscore') }}

{{ __('app/main.ranking.guilds') }}

+
    + @foreach ($topGuildHighscore as $entry) +
  • $loop->even])> +
    $entry->empire == \App\Models\Enums\EmpireEnum::SHINSOO, + 'empire2' => $entry->empire == \App\Models\Enums\EmpireEnum::CHUNJO, + 'empire3' => $entry->empire == \App\Models\Enums\EmpireEnum::JINNO + ]) + > + $entry->id < 10])>{{ $entry->id }} $loop->first])>{{ $entry->name }} +
    +
  • + @endforeach +
+
{{ __('app/main.ranking.btn_highscore') }} diff --git a/resources/views/main/guildhighscore.blade.php b/resources/views/main/guildhighscore.blade.php index f0b7761..b6811dc 100644 --- a/resources/views/main/guildhighscore.blade.php +++ b/resources/views/main/guildhighscore.blade.php @@ -6,153 +6,131 @@
-

Metin2 - Listarea rangurilor

+

{{ __('app/highscore.title') }}


-
+ + @csrf + + {{-- Temporarily disabled until multi-server support is implemented; added guild leader instead +
+ + +
+ --}} +
- - + + @foreach (\App\Models\Enums\EmpireEnum::cases() as $empire) + + @endforeach
- - -
-
- +
- + +
+
+
+ +
+
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RangBreaslaLider BreaslăRegatNivelPuncte
1InStyledivolitzaTaImperiul Chunjo20119494
2ISENGARDFlorin10Imperiul Jinno20113902
3TheRulersgabitza20Imperiul Chunjo2076941
4A55A55INIIAnA3634Imperiul Chunjo2075729
5TheElfsSorrcerreRImperiul Jinno2055547
6MAESTRIIpurMAESTRAiubyImperiul Jinno1550908
7NeBuNaTiCiiMANXLImperiul Chunjo2050164
8TheGoDsPaCaToaSaImperiul Shinsoo1248107
97UPKANNDYImperiul Chunjo2045964
10ReVoLuTioNTucsonImperiul Chunjo2042929
- + @if ($highscore->isEmpty()) +
{{ __("app/highscore.no-results") }}
+ @else + @if ($highscore->lastPage() > 1) + + + @endif - +
+ + + + + + + + + + + + + @foreach ($highscore as $entry) + $entry->id == 1, "zebra" => $loop->odd])> + + + + + + + + @endforeach + +
{{ __("app/highscore.header.rank") }}{{ __("app/highscore.header.guild-name") }}{{ __("app/highscore.header.guild-leader") }}{{ __("app/highscore.header.empire") }}{{ __("app/highscore.header.level") }}{{ __("app/highscore.header.guild-points") }}
$loop->odd, "guildrank-td-2-1" => $loop->even])> + {{ $entry->id }} + $loop->odd, "guildrank-td-2-2" => $loop->even])> + {{ $entry->name }} + $loop->odd, "guildrank-td-2-3" => $loop->even])> + {{ $entry->master }} + $loop->odd, "guildrank-td-2-4" => $loop->even])> + @if ($entry->empire == \App\Models\Enums\EmpireEnum::SHINSOO) + {{ $entry->empire->longName() }} + @elseif ($entry->empire == \App\Models\Enums\EmpireEnum::CHUNJO) + {{ $entry->empire->longName() }} + @elseif ($entry->empire == \App\Models\Enums\EmpireEnum::JINNO) + {{ $entry->empire->longName() }} + @endif + $loop->odd, "guildrank-td-2-5" => $loop->even])> + {{ $entry->level }} + $loop->odd, "guildrank-td-2-6" => $loop->even])> + {{ $entry->ladder_point }} +
-
-
Update: 21.06.2013 05:27:36
+ @if ($highscore->lastPage() > 1) + + + @endif + +
+
{{ __('app/highscore.update-time') }} {{ $highscore->max('date')->translatedFormat('d F Y H:i:s') }}
+ @endif
@@ -160,9 +138,4 @@
 
- @endsection diff --git a/resources/views/main/highscore.blade.php b/resources/views/main/highscore.blade.php index 908baf4..c0e8da3 100644 --- a/resources/views/main/highscore.blade.php +++ b/resources/views/main/highscore.blade.php @@ -6,143 +6,132 @@
-

Metin2 - Listarea rangurilor

+

{{ __('app/highscore.title') }}


-
+ + @csrf + + {{-- Temporarily disabled until multi-server support is implemented; added empire choice instead +
+ + +
+ --}} +
- - + + @foreach (\App\Models\Enums\EmpireEnum::cases() as $empire) + + @endforeach
- - + + @foreach (\App\Models\Enums\CharacterClassEnum::cases() as $class) + + @endforeach
- +
- +
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RangNumele CaracteruluiRegatNivelEXP
1picyu3Imperiul Chunjo1050
2XXXMEN77Imperiul Shinsoo1050
3SpydyImperiul Shinsoo1050
4beLeSeImperiul Jinno1050
5alexdenisImperiul Chunjo1050
6addygrygImperiul Jinno1050
7Pixie03Imperiul Jinno1050
8KingARAGORNImperiul Jinno1050
9pauldpv2001Imperiul Chunjo1050
10SCORPIO1Imperiul Shinsoo1050
- + @if ($highscore->isEmpty()) +
{{ __("app/highscore.no-results") }}
+ @else + @if ($highscore->lastPage() > 1) + + + @endif - +
+ + + + + + + + + + + + @foreach ($highscore as $entry) + $entry->id == 1, "zebra" => $loop->odd])> + + + + + + + @endforeach + +
{{ __("app/highscore.header.rank") }}{{ __("app/highscore.header.character-name") }}{{ __("app/highscore.header.empire") }}{{ __("app/highscore.header.level") }}{{ __("app/highscore.header.exp") }}
$loop->odd, "rank-td-2-1" => $loop->even])> + {{ $entry->id }} + $loop->odd, "rank-td-2-2" => $loop->even])> + {{ $entry->name }} + $loop->odd, "rank-td-2-3" => $loop->even])> + @if ($entry->empire == \App\Models\Enums\EmpireEnum::SHINSOO) + {{ $entry->empire->longName() }} + @elseif ($entry->empire == \App\Models\Enums\EmpireEnum::CHUNJO) + {{ $entry->empire->longName() }} + @elseif ($entry->empire == \App\Models\Enums\EmpireEnum::JINNO) + {{ $entry->empire->longName() }} + @endif + $loop->odd, "rank-td-2-4" => $loop->even])> + {{ $entry->level }} + $loop->odd, "rank-td-2-5" => $loop->even])> + {{ $entry->exp }} +
-
-
Update: 08.07.2013 14:57:16
+ @if ($highscore->lastPage() > 1) + + + @endif + +
+
{{ __('app/highscore.update-time') }} {{ $highscore->max('date')->translatedFormat('d F Y H:i:s') }}
+ @endif
@@ -150,9 +139,4 @@
 
- @endsection diff --git a/routes/web.php b/routes/web.php index 3f868ec..648f4ec 100644 --- a/routes/web.php +++ b/routes/web.php @@ -31,8 +31,16 @@ Route::get('/media', fn () => view('main/media')); Route::get('/news', fn () => view('main/news')); Route::get('/download', fn () => view('main/download')); - Route::get('/highscore', fn () => view('main/highscore')); - Route::get('/guildhighscore', fn () => view('main/guildhighscore')); + + # Highscore + Route::get('/highscore', [HighscoreController::class, 'show']); + Route::post('/highscore', [HighscoreController::class, 'search']); + Route::get('/highscore/{empireChoice}/{classChoice}/{page}', [HighscoreController::class, 'show'])->name('highscore-page'); + + # Guild highscore + Route::get('/guildhighscore', [GuildHighscoreController::class, 'show']); + Route::post('/guildhighscore', [GuildHighscoreController::class, 'search']); + Route::get('/guildhighscore/{empireChoice}/{page}', [GuildHighscoreController::class, 'show'])->name('guild-highscore-page'); # The game Route::get('/thegame', fn () => view('main/thegame/thegame'));