diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 414e430164..1e670b195e 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -248,7 +248,7 @@ protected function schedule(Schedule $schedule): void } // Ensure redis remains healthy - $schedule->command('redis:clearidlekeys', ['seconds' => 3600 * 12])->hourly(); + $schedule->command('redis:clearidlekeys', ['seconds' => 900])->everyFifteenMinutes(); // Aggregate all metrics so they're nice and snappy to load $schedule->command('metric:aggregate')->everyFiveMinutes(); diff --git a/app/Http/Controllers/Ajax/AjaxDungeonRouteController.php b/app/Http/Controllers/Ajax/AjaxDungeonRouteController.php index 6ad24ca310..3a79f3c7f8 100644 --- a/app/Http/Controllers/Ajax/AjaxDungeonRouteController.php +++ b/app/Http/Controllers/Ajax/AjaxDungeonRouteController.php @@ -238,9 +238,12 @@ public function htmlsearch(AjaxDungeonRouteSearchFormRequest $request, Expansion 'ratings', 'routeattributes', 'dungeon', 'dungeon.activeFloors', 'mappingVersion']) ->join('dungeons', 'dungeon_routes.dungeon_id', 'dungeons.id') ->join('mapping_versions', 'mapping_versions.dungeon_id', 'dungeons.id') - ->when($expansion !== null, static fn(Builder $builder) => $builder->where('dungeons.expansion_id', $expansion->id)) - ->when($season !== null, static fn(Builder $builder) => $builder->join('season_dungeons', 'season_dungeons.dungeon_id', '=', 'dungeon_routes.dungeon_id') - ->where('season_dungeons.season_id', $season->id)) + ->when($expansion !== null, static fn(Builder $builder) => + $builder->where('dungeons.expansion_id', $expansion->id) + ) + ->when($season !== null, static fn(Builder $builder) => + $builder->where('season_id', $season->id) + ) // Only non-try routes, combine both where() and whereNull(), there are inconsistencies where one or the // other may work, this covers all bases for both dev and live ->where(static function ($query) { diff --git a/app/Logic/Datatables/ColumnHandler/DungeonRoutes/DungeonColumnHandler.php b/app/Logic/Datatables/ColumnHandler/DungeonRoutes/DungeonColumnHandler.php index ca5b894da0..38e95b866b 100644 --- a/app/Logic/Datatables/ColumnHandler/DungeonRoutes/DungeonColumnHandler.php +++ b/app/Logic/Datatables/ColumnHandler/DungeonRoutes/DungeonColumnHandler.php @@ -33,9 +33,7 @@ protected function applyFilter(Builder $subBuilder, $columnData, $order, $genera if ($explode[0] === 'season') { $seasonId = $explode[1]; // Joins need to be added to the main builder - $this->getDtHandler()->getBuilder() - ->join('season_dungeons', 'season_dungeons.season_id', '=', DB::raw($seasonId)); - $subBuilder->whereColumn('dungeon_routes.dungeon_id', '=', 'season_dungeons.dungeon_id'); + $subBuilder->where('dungeon_routes.season_id', $seasonId); } else if ($explode[0] === 'expansion') { $subBuilder->where('dungeons.expansion_id', $explode[1]); } else { diff --git a/app/Models/Expansion.php b/app/Models/Expansion.php index a5d4137805..61724ec409 100644 --- a/app/Models/Expansion.php +++ b/app/Models/Expansion.php @@ -29,7 +29,7 @@ * @property Carbon $updated_at * * @property Collection $dungeons - * @property TimewalkingEvent|null $timewalkingevent + * @property TimewalkingEvent|null $timewalkingEvent * * @method static Builder active() * @@ -45,7 +45,7 @@ class Expansion extends CacheModel public $hidden = ['id', 'icon_file_id', 'created_at', 'updated_at']; - public $with = ['timewalkingevent']; + public $with = ['timewalkingEvent']; protected $dates = [ // 'released_at', @@ -111,7 +111,7 @@ public function seasons(): HasMany return $this->hasMany(Season::class); } - public function timewalkingevent(): HasOne + public function timewalkingEvent(): HasOne { return $this->hasOne(TimewalkingEvent::class); } @@ -183,7 +183,7 @@ public function scopeInactive(Builder $query): Builder public function hasTimewalkingEvent(): bool { - return $this->timewalkingevent instanceof TimewalkingEvent; + return $this->timewalkingEvent instanceof TimewalkingEvent; } public function hasDungeonForGameVersion(GameVersion $gameVersion): bool diff --git a/app/Service/Cache/CacheService.php b/app/Service/Cache/CacheService.php index f2f83cce16..78baf950c1 100644 --- a/app/Service/Cache/CacheService.php +++ b/app/Service/Cache/CacheService.php @@ -157,11 +157,11 @@ public function clearIdleKeys(?int $seconds = null): int sprintf('/%s[a-zA-Z0-9]{40}(?::[a-z0-9]{40})*/', $prefix), ]; + $deletedKeysCountTotal = $deletedKeysCount = 0; try { $this->log->clearIdleKeysStart($seconds); - $i = 0; - $nextKey = 0; - $deletedKeysCount = 0; + $i = 0; + $nextKey = 0; do { $result = Redis::command('SCAN', [$nextKey]); @@ -205,12 +205,13 @@ public function clearIdleKeys(?int $seconds = null): int $i++; if ($i % 1000 === 0) { + $deletedKeysCountTotal += $deletedKeysCount; $this->log->clearIdleKeysProgress($i, $deletedKeysCount); $deletedKeysCount = 0; } } while ($nextKey > 0); } finally { - $this->log->clearIdleKeysEnd(); + $this->log->clearIdleKeysEnd($deletedKeysCountTotal); } return $deletedKeysCount; diff --git a/app/Service/Cache/Logging/CacheServiceLogging.php b/app/Service/Cache/Logging/CacheServiceLogging.php index 6196012b54..6869960633 100644 --- a/app/Service/Cache/Logging/CacheServiceLogging.php +++ b/app/Service/Cache/Logging/CacheServiceLogging.php @@ -28,8 +28,8 @@ public function clearIdleKeysProgress(int $index, int $deletedKeysCount): void $this->debug(__METHOD__, get_defined_vars()); } - public function clearIdleKeysEnd(): void + public function clearIdleKeysEnd(int $deletedKeysCount): void { - $this->end(__METHOD__); + $this->end(__METHOD__, get_defined_vars()); } } diff --git a/app/Service/Cache/Logging/CacheServiceLoggingInterface.php b/app/Service/Cache/Logging/CacheServiceLoggingInterface.php index daf3064842..1d4dd0f096 100644 --- a/app/Service/Cache/Logging/CacheServiceLoggingInterface.php +++ b/app/Service/Cache/Logging/CacheServiceLoggingInterface.php @@ -13,5 +13,5 @@ public function clearIdleKeysFailedToDeleteAllKeys(int $amount, int $total): voi public function clearIdleKeysProgress(int $index, int $deletedKeysCount): void; - public function clearIdleKeysEnd(): void; + public function clearIdleKeysEnd(int $deletedKeysCount): void; } diff --git a/app/Service/MDT/MDTExportStringService.php b/app/Service/MDT/MDTExportStringService.php index d1407a66f1..2ce9867427 100644 --- a/app/Service/MDT/MDTExportStringService.php +++ b/app/Service/MDT/MDTExportStringService.php @@ -248,13 +248,15 @@ public function getEncodedString(Collection $warnings): string { // $lua = $this->_getLua(); + $affixes = $this->dungeonRoute->affixes; + $mdtObject = [ // 'objects' => $this->extractObjects($warnings), // M+ level 'difficulty' => $this->dungeonRoute->level_min, - 'week' => $this->dungeonRoute->affixGroups->isEmpty() ? 1 : - Conversion::convertAffixGroupToWeek($this->dungeonRoute->affixes->first()), + 'week' => $this->dungeonRoute->affixGroups->isEmpty() || $affixes->isEmpty() ? 1 : + Conversion::convertAffixGroupToWeek($affixes->first()), 'value' => [ 'currentDungeonIdx' => $this->dungeonRoute->dungeon->mdt_id, 'selection' => [], diff --git a/config/horizon.php b/config/horizon.php index bd5095da38..3b1c74eb2b 100644 --- a/config/horizon.php +++ b/config/horizon.php @@ -159,7 +159,7 @@ 'connection' => 'redis', 'queue' => [sprintf('%s-production-thumbnail', env('APP_TYPE'))], 'balance' => 'simple', - 'processes' => 6, + 'processes' => 3, 'tries' => 1, ], 'supervisor-thumbnail-api' => [ diff --git a/config/keystoneguru.php b/config/keystoneguru.php index 7c20b149c1..e81f3e367b 100644 --- a/config/keystoneguru.php +++ b/config/keystoneguru.php @@ -173,12 +173,12 @@ 'refresh_min' => 30, /** - * The amount of days where the thumbnail gets refreshed anyways regardless of other rules. + * The amount of days when the thumbnail gets refreshed anyways regardless of other rules. */ 'refresh_anyways_days' => 30, /** - * The amount of hours where a thumbnail refresh must be in the queue for before it is re-queued + * The amount of hours when a thumbnail refresh must be in the queue for before it is re-queued */ 'refresh_requeue_hours' => 12, @@ -190,7 +190,7 @@ /** * The maximum amount of thumbnails that will be queued in a single run. */ - 'refresh_outdated_count' => 300, + 'refresh_outdated_count' => 150, ], /** diff --git a/database/migrations/2024_09_18_200905_change_default_locale_column_in_users_table.php b/database/migrations/2024_09_18_200905_change_default_locale_column_in_users_table.php new file mode 100644 index 0000000000..c8463b33b8 --- /dev/null +++ b/database/migrations/2024_09_18_200905_change_default_locale_column_in_users_table.php @@ -0,0 +1,32 @@ +string('locale')->default('en_US')->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->string('locale')->default('en-US')->change(); + }); + } +}; diff --git a/database/migrations/2024_09_18_204619_add_indices_to_team_users_table.php b/database/migrations/2024_09_18_204619_add_indices_to_team_users_table.php new file mode 100644 index 0000000000..78e2054e42 --- /dev/null +++ b/database/migrations/2024_09_18_204619_add_indices_to_team_users_table.php @@ -0,0 +1,33 @@ +dropIndex(['user_id']); + + $table->index(['user_id', 'role']); + $table->index('role'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('team_users', function (Blueprint $table) { + $table->index('user_id'); + + $table->dropIndex(['user_id', 'role']); + $table->dropIndex('role'); + }); + } +}; diff --git a/database/migrations/2024_09_18_204906_add_indices_to_releases_table.php b/database/migrations/2024_09_18_204906_add_indices_to_releases_table.php new file mode 100644 index 0000000000..323e3ce5b9 --- /dev/null +++ b/database/migrations/2024_09_18_204906_add_indices_to_releases_table.php @@ -0,0 +1,29 @@ +index(['spotlight', 'created_at']); + $table->index(['created_at']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('releases', function (Blueprint $table) { + $table->dropIndex(['created_at']); + }); + } +}; diff --git a/database/migrations/2024_09_18_205343_add_indices_to_floors_table.php b/database/migrations/2024_09_18_205343_add_indices_to_floors_table.php new file mode 100644 index 0000000000..e4b006c48d --- /dev/null +++ b/database/migrations/2024_09_18_205343_add_indices_to_floors_table.php @@ -0,0 +1,28 @@ +index(['index']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('floors', function (Blueprint $table) { + $table->dropIndex(['index']); + }); + } +}; diff --git a/database/migrations/2024_09_18_210656_add_indices_to_metrics_table.php b/database/migrations/2024_09_18_210656_add_indices_to_metrics_table.php new file mode 100644 index 0000000000..9d05e293d0 --- /dev/null +++ b/database/migrations/2024_09_18_210656_add_indices_to_metrics_table.php @@ -0,0 +1,29 @@ +dropIndex(['model_id', 'model_class']); + $table->index(['model_id', 'model_class', 'category', 'tag'], 'compound'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('metrics', function (Blueprint $table) { + $table->dropIndex('compound'); + $table->index(['model_id', 'model_class']); + }); + } +}; diff --git a/database/seeders/dungeondata/shadowlands/necroticwake_a/1/enemies.json b/database/seeders/dungeondata/shadowlands/necroticwake_a/1/enemies.json index 98db338d78..effb9d9d37 100644 --- a/database/seeders/dungeondata/shadowlands/necroticwake_a/1/enemies.json +++ b/database/seeders/dungeondata/shadowlands/necroticwake_a/1/enemies.json @@ -9763,8 +9763,8 @@ "enemy_forces_override": null, "enemy_forces_override_teeming": null, "dungeon_difficulty": null, - "lat": -121.21005656785624, - "lng": 120.47619144231928, + "lat": -121.21005656786, + "lng": 120.47619144232, "kill_priority": 0 }, { @@ -9835,8 +9835,8 @@ "enemy_forces_override": null, "enemy_forces_override_teeming": null, "dungeon_difficulty": null, - "lat": -124.51244963277261, - "lng": 124.63476048702877, + "lat": -124.51244963277, + "lng": 124.63476048703, "kill_priority": 0 }, { @@ -9859,8 +9859,8 @@ "enemy_forces_override": null, "enemy_forces_override_teeming": null, "dungeon_difficulty": null, - "lat": -113.62678360397422, - "lng": 119.1307720455015, + "lat": -113.62678360397, + "lng": 119.1307720455, "kill_priority": 0 }, { @@ -10003,8 +10003,8 @@ "enemy_forces_override": null, "enemy_forces_override_teeming": null, "dungeon_difficulty": null, - "lat": -117.41842008591523, - "lng": 115.70606812632897, + "lat": -117.41842008592, + "lng": 115.70606812633, "kill_priority": 0 }, { @@ -10027,8 +10027,8 @@ "enemy_forces_override": null, "enemy_forces_override_teeming": null, "dungeon_difficulty": null, - "lat": -128.0594644062013, - "lng": 119.98694802529464, + "lat": -128.0594644062, + "lng": 119.98694802529, "kill_priority": 0 }, { @@ -10243,8 +10243,8 @@ "enemy_forces_override": null, "enemy_forces_override_teeming": null, "dungeon_difficulty": null, - "lat": -61.522359690849335, - "lng": 79.99129868352975, + "lat": -61.522359690849, + "lng": 79.99129868353, "kill_priority": 0 }, { @@ -10267,8 +10267,8 @@ "enemy_forces_override": null, "enemy_forces_override_teeming": null, "dungeon_difficulty": null, - "lat": -121.33236742211241, - "lng": 128.42639696896978, + "lat": -121.33236742211, + "lng": 128.42639696897, "kill_priority": 0 }, { @@ -10291,8 +10291,8 @@ "enemy_forces_override": null, "enemy_forces_override_teeming": null, "dungeon_difficulty": null, - "lat": -121.21005656785624, - "lng": 112.64829676992493, + "lat": -121.21005656786, + "lng": 112.64829676992, "kill_priority": 0 }, { diff --git a/database/seeders/releases/v11.3.1.json b/database/seeders/releases/v11.3.1.json new file mode 100644 index 0000000000..7588324652 --- /dev/null +++ b/database/seeders/releases/v11.3.1.json @@ -0,0 +1,35 @@ +{ + "id": 248, + "release_changelog_id": 255, + "version": "v11.3.1", + "title": "Performance optimizations and bugfixes", + "silent": 0, + "spotlight": 0, + "created_at": "2024-09-19T15:26:17+00:00", + "updated_at": "2024-09-19T15:26:17+00:00", + "changelog": { + "id": 255, + "release_id": 248, + "description": null, + "changes": [ + { + "release_changelog_id": 255, + "release_changelog_category_id": 1, + "ticket_id": 2495, + "change": "Various performance optimizations. This is still ongoing." + }, + { + "release_changelog_id": 255, + "release_changelog_category_id": 5, + "ticket_id": 2493, + "change": "Route season filter no longer just looks for any routes that are for a dungeon part of the current season, but for actual routes created during the selected season. BFA routes for Siege of Boralus, for example, will no longer show up with this filter." + }, + { + "release_changelog_id": 255, + "release_changelog_category_id": 5, + "ticket_id": 2494, + "change": "Dungeons that have support for combined floors now show a thumbnail again." + } + ] + } +} diff --git a/resources/assets/images/affixes/xal_ataths_bargain_ascendant.jpg b/resources/assets/images/affixes/xalataths_bargain_ascendant.jpg similarity index 100% rename from resources/assets/images/affixes/xal_ataths_bargain_ascendant.jpg rename to resources/assets/images/affixes/xalataths_bargain_ascendant.jpg diff --git a/resources/assets/images/affixes/xal_ataths_bargain_devour.jpg b/resources/assets/images/affixes/xalataths_bargain_devour.jpg similarity index 100% rename from resources/assets/images/affixes/xal_ataths_bargain_devour.jpg rename to resources/assets/images/affixes/xalataths_bargain_devour.jpg diff --git a/resources/assets/images/affixes/xal_ataths_bargain_frenzied.jpg b/resources/assets/images/affixes/xalataths_bargain_frenzied.jpg similarity index 100% rename from resources/assets/images/affixes/xal_ataths_bargain_frenzied.jpg rename to resources/assets/images/affixes/xalataths_bargain_frenzied.jpg diff --git a/resources/assets/images/affixes/xal_ataths_bargain_oblivion.jpg b/resources/assets/images/affixes/xalataths_bargain_oblivion.jpg similarity index 100% rename from resources/assets/images/affixes/xal_ataths_bargain_oblivion.jpg rename to resources/assets/images/affixes/xalataths_bargain_oblivion.jpg diff --git a/resources/assets/images/affixes/xal_ataths_bargain_voidbound.jpg b/resources/assets/images/affixes/xalataths_bargain_voidbound.jpg similarity index 100% rename from resources/assets/images/affixes/xal_ataths_bargain_voidbound.jpg rename to resources/assets/images/affixes/xalataths_bargain_voidbound.jpg diff --git a/resources/assets/images/affixes/xal_ataths_guile.jpg b/resources/assets/images/affixes/xalataths_guile.jpg similarity index 100% rename from resources/assets/images/affixes/xal_ataths_guile.jpg rename to resources/assets/images/affixes/xalataths_guile.jpg diff --git a/resources/views/common/dungeonroute/cardhorizontal.blade.php b/resources/views/common/dungeonroute/cardhorizontal.blade.php index 2fa9f27845..7504c5e895 100644 --- a/resources/views/common/dungeonroute/cardhorizontal.blade.php +++ b/resources/views/common/dungeonroute/cardhorizontal.blade.php @@ -49,7 +49,7 @@ ob_start(); ?>
+ class="row no-gutters m-xl-1 mx-0 my-3 card_dungeonroute horizontal {{ $showDungeonImage ? 'dungeon_image' : '' }}">
    @@ -72,7 +72,7 @@ class="row no-gutters m-xl-1 mx-0 my-3 card_dungeonroute horizontal {{ $showDung
    @@ -96,7 +96,7 @@ class="row no-gutters m-xl-1 mx-0 my-3 card_dungeonroute horizontal {{ $showDung ?> @foreach($dungeonroute->affixes as $affixgroup)
    + class="row no-gutters {{ isset($currentAffixGroup) && $currentAffixGroup->id === $affixgroup->id ? 'current' : '' }}"> @include('common.affixgroup.affixgroup', [ 'affixgroup' => $affixgroup, 'showText' => false, @@ -118,7 +118,7 @@ class="row no-gutters {{ isset($currentAffixGroup) && $currentAffixGroup->id === @if($seasonalAffix !== null)
    Dominant affix
    @endif @@ -214,12 +214,13 @@ class="btn btn-sm menu_actions_btn py-1" }; // Temp fix due to cached cards containing translations - and I don't want to show Russian translations to others at this time -$cache = false; +$cache = true; if ($cache) { + $currentUserLocale = Auth::check() ? Auth::user()->locale : 'en_US'; // Echo the result of this function echo $cacheService->remember( - sprintf('view:dungeonroute_card_%d_%d_%d', (int)$showAffixes, (int)$showDungeonImage, $dungeonroute->id), + sprintf('view:dungeonroute_card:horizontal:%s:%d_%d_%d', $currentUserLocale, (int)$showAffixes, (int)$showDungeonImage, $dungeonroute->id), $cacheFn, config('keystoneguru.view.common.dungeonroute.card.cache.ttl') ); diff --git a/resources/views/common/dungeonroute/cardvertical.blade.php b/resources/views/common/dungeonroute/cardvertical.blade.php index 5ae036383e..c9e69a3076 100644 --- a/resources/views/common/dungeonroute/cardvertical.blade.php +++ b/resources/views/common/dungeonroute/cardvertical.blade.php @@ -124,7 +124,7 @@ class="row no-gutters {{ isset($currentAffixGroup) && $currentAffixGroup->id === @if($seasonalAffix !== null)
    Dominant affix
    @endif @@ -228,12 +228,13 @@ class="btn btn-sm menu_actions_btn py-1" }; // Temp fix due to cached cards containing translations - and I don't want to show Russian translations to others at this time -$cache = false; +$cache = true; if ($cache) { + $currentUserLocale = Auth::check() ? Auth::user()->locale : 'en_US'; // Echo the result of this function echo $cacheService->remember( - sprintf('view:dungeonroute_card_%d_%d_%d', (int)$showAffixes, (int)$showDungeonImage, $dungeonroute->id), + sprintf('view:dungeonroute_card:vertical:%s:%d_%d_%d', $currentUserLocale, (int)$showAffixes, (int)$showDungeonImage, $dungeonroute->id), $cacheFn, config('keystoneguru.view.common.dungeonroute.card.cache.ttl') ); diff --git a/resources/views/common/handlebars/affixgroups.blade.php b/resources/views/common/handlebars/affixgroups.blade.php index 8338d79423..a56ebf1d30 100644 --- a/resources/views/common/handlebars/affixgroups.blade.php +++ b/resources/views/common/handlebars/affixgroups.blade.php @@ -33,7 +33,7 @@ function handlebarsAffixGroupsParse(data) { affixes.push({ title: lang.get(affix.name), name: lang.get(affix.name), - class: affix.key.toLowerCase() + class: _.kebabCase(affix.key).replaceAll('-', '_') }); } } diff --git a/resources/views/common/handlebars/thumbnailcarousel.blade.php b/resources/views/common/handlebars/thumbnailcarousel.blade.php index 2cae1fe910..d0195644c0 100644 --- a/resources/views/common/handlebars/thumbnailcarousel.blade.php +++ b/resources/views/common/handlebars/thumbnailcarousel.blade.php @@ -9,9 +9,10 @@ function handlebarsThumbnailCarouselParse(row) { let items = []; if (row.has_thumbnail) { + let facadeEnabled = row.dungeon.floors[row.dungeon.floors.length - 1].facade; for (let index in row.dungeon.floors) { let floor = row.dungeon.floors[index]; - if (!floor.active || ((row.dungeon.facade_enabled && !floor.facade) || (!row.dungeon.facade_enabled && floor.facade))) { + if (!floor.active || ((facadeEnabled && !floor.facade) || (!facadeEnabled && floor.facade))) { continue; } diff --git a/resources/views/vendor/language/flags.blade.php b/resources/views/vendor/language/flags.blade.php index 8391ac4691..ec81b513e1 100644 --- a/resources/views/vendor/language/flags.blade.php +++ b/resources/views/vendor/language/flags.blade.php @@ -1,7 +1,7 @@ locale : 'en-US'; +$currentUserLocale = Auth::check() ? Auth::user()->locale : 'en_US'; $currentUserLocaleName = language()->getName($currentUserLocale); ?>