Skip to content

Commit

Permalink
Merge pull request #2520 from RaiderIO/development
Browse files Browse the repository at this point in the history
Release v11.3.4 - The Stonevault enemy placement - MDT import/export affixes
  • Loading branch information
Wotuu authored Sep 29, 2024
2 parents ee46b2c + 46a881c commit 352eb0e
Show file tree
Hide file tree
Showing 246 changed files with 720 additions and 176 deletions.
10 changes: 10 additions & 0 deletions app/Http/Controllers/AdminToolsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use App\Models\DungeonRoute\DungeonRoute;
use App\Models\Floor\Floor;
use App\Models\Mapping\MappingVersion;
use App\Models\MDTImport;
use App\Models\Npc\Npc;
use App\Models\Npc\NpcClassification;
use App\Models\Npc\NpcEnemyForces;
Expand Down Expand Up @@ -438,6 +439,15 @@ public function mdtviewasdungeonroute(): View
return view('admin.tools.mdt.string', ['asDungeonroute' => true]);
}

public function mdtImportList(): View
{
return view('admin.tools.mdt.list', [
'mdtImports' => MDTImport::whereNotNull('error')
->orderByDesc('created_at')
->paginate(50),
]);
}

/**
* @return never|void
*
Expand Down
72 changes: 30 additions & 42 deletions app/Http/Controllers/MDTImportController.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,41 +34,35 @@ public function details(
$validated = $request->validated();
$string = $validated['import_string'];

// try {
$warnings = collect();
$errors = collect();

return $mdtImportStringService
->setEncodedString($string)
->getDetails($warnings, $errors);
// } catch (MDTStringParseException $ex) {
// return abort(StatusCode::INTERNAL_SERVER_ERROR, __('controller.mdtimport.error.mdt_string_parsing_failed'));
// } catch (InvalidMDTStringException $ex) {
// return abort(StatusCode::BAD_REQUEST, __('controller.mdtimport.error.mdt_string_format_not_recognized'));
// } catch (Exception $ex) {
// // Different message based on our deployment settings
// if (config('app.debug')) {
// $message = sprintf(__('controller.mdtimport.error.invalid_mdt_string_exception'), $ex->getMessage());
// } else {
// $message = __('controller.admintools.error.invalid_mdt_string');
// }
//
// // We're not interested if the string was 100% not an MDT string - it will never work then
// if (isValidBase64($string)) {
// report($ex);
// }
//
// Log::error($ex->getMessage());
//
// return abort(StatusCode::BAD_REQUEST, $message);
// } catch (Throwable $error) {
// if ($error->getMessage() === "Class 'Lua' not found") {
// return abort(StatusCode::INTERNAL_SERVER_ERROR, __('controller.mdtimport.error.mdt_importer_not_configured_properly'));
// }
// Log::error($error->getMessage());
//
// throw $error;
// }
try {
$warnings = collect();
$errors = collect();

return $mdtImportStringService
->setEncodedString($string)
->getDetails($warnings, $errors);
} catch (MDTStringParseException $ex) {
return abort(StatusCode::BAD_REQUEST, __('controller.mdtimport.error.mdt_string_parsing_failed'));
} catch (InvalidMDTStringException $ex) {
return abort(StatusCode::BAD_REQUEST, __('controller.mdtimport.error.mdt_string_format_not_recognized'));
} catch (Exception $ex) {
// Different message based on our deployment settings
if (config('app.debug')) {
$message = sprintf(__('controller.mdtimport.error.invalid_mdt_string_exception'), $ex->getMessage());
} else {
$message = __('controller.admintools.error.invalid_mdt_string');
}

return abort(StatusCode::BAD_REQUEST, $message);
} catch (Throwable $error) {
Log::error($error->getMessage());

if ($error->getMessage() === "Class 'Lua' not found") {
return abort(StatusCode::INTERNAL_SERVER_ERROR, __('controller.mdtimport.error.mdt_importer_not_configured_properly'));
}

throw $error;
}
}

/**
Expand Down Expand Up @@ -97,14 +91,8 @@ public function import(ImportStringFormRequest $request, MDTImportStringServiceI
$dungeonRoute->team_id = $validated['team_id'] ?? null;
$dungeonRoute->save();
}

// Keep track of the import
MDTImport::create([
'dungeon_route_id' => $dungeonRoute->id,
'import_string' => $string,
]);
} catch (MDTStringParseException) {
return abort(StatusCode::INTERNAL_SERVER_ERROR, __('controller.mdtimport.error.mdt_string_parsing_failed'));
return abort(StatusCode::BAD_REQUEST, __('controller.mdtimport.error.mdt_string_parsing_failed'));
} catch (InvalidMDTStringException) {
return abort(StatusCode::BAD_REQUEST, __('controller.mdtimport.error.mdt_string_format_not_recognized'));
} catch (Exception $ex) {
Expand Down
24 changes: 21 additions & 3 deletions app/Logic/MDT/Conversion.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use App\Models\Dungeon;
use App\Models\Expansion;
use App\Models\Floor\Floor;
use App\Models\Season;
use App\Service\Season\SeasonService;
use Exception;

Expand Down Expand Up @@ -295,18 +296,30 @@ public static function convertLatLngToMDTCoordinate(LatLng $latLng): array
*/
public static function convertWeekToAffixGroup(SeasonService $seasonService, Dungeon $dungeon, int $mdtWeek): ?AffixGroup
{
$season = $dungeon->getActiveSeason($seasonService);
if (!$dungeon->gameVersion->has_seasons) {
return null;
}

$season = $seasonService->getUpcomingSeasonForDungeon($dungeon) ??
$seasonService->getMostRecentSeasonForDungeon($dungeon);

if ($season === null) {
logger()->error(sprintf('Unable to find season for dungeon %s', __($dungeon->name)));

return null;
}

$affixGroup = $season->affixGroups->get(($season->start_affix_group_index + ($mdtWeek - 1)) % $season->affixGroups->count());
// For each season this is different
if ($season->id === Season::SEASON_TWW_S1) {
$affixGroup = $season->affixGroups->get(($season->start_affix_group_index + $mdtWeek) % $season->affixGroups->count());
} else {
$affixGroup = $season->affixGroups->get(($season->start_affix_group_index + ($mdtWeek - 1)) % $season->affixGroups->count());
}

// $affixGroup = $season->affixgroups->get(($season->start_affix_group_index - ($mdtWeek - 1)));
if ($affixGroup === null) {
logger()->error('Unable to find affix group for mdtWeek - returning current affix group instead', [
'$mdtWeek' => $mdtWeek,
'mdtWeek' => $mdtWeek,
]);

$affixGroup = $season->getCurrentAffixGroup();
Expand All @@ -317,6 +330,11 @@ public static function convertWeekToAffixGroup(SeasonService $seasonService, Dun

public static function convertAffixGroupToWeek(AffixGroup $affixGroup): int
{
// For each season this is different
if ($affixGroup->season_id === Season::SEASON_TWW_S1) {
return ($affixGroup->id - 2) % $affixGroup->season->affix_group_count;
}

// We need to figure out which week it is in the rotation
return ($affixGroup->id - 1) % $affixGroup->season->affix_group_count;
}
Expand Down
3 changes: 2 additions & 1 deletion app/Models/DungeonRoute/DungeonRoute.php
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,8 @@ public function saveFromRequest(
// If it was empty just set Unspecified instead
$this->faction_id = empty($this->faction_id) ? 1 : $this->faction_id;

$activeSeason = $seasonService->getMostRecentSeasonForDungeon($this->dungeon);
$activeSeason = $seasonService->getUpcomingSeasonForDungeon($this->dungeon) ??
$seasonService->getMostRecentSeasonForDungeon($this->dungeon);
// Can still be null if there are no seasons for this dungeon, like in Classic
$this->season_id = $activeSeason->id ?? null;

Expand Down
5 changes: 5 additions & 0 deletions app/Models/Expansion.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,11 @@ public function showDiscoverRoutesCardDungeonImage(): bool
return !in_array($this->shortname, [Expansion::EXPANSION_SHADOWLANDS]);
}

public function getWallpaperUrl(): string
{
return url(sprintf('/images/dungeons/%s/wallpaper.jpg', $this->shortname));
}

/**
* Saves an expansion with the data from a Request.
*
Expand Down
15 changes: 11 additions & 4 deletions app/Models/MDTImport.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@
namespace App\Models;

use App\Models\DungeonRoute\DungeonRoute;
use Carbon\Carbon;
use Eloquent;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
* @property int $id
* @property int $dungeon_route_id
* @property string $import_string
* @property int $id
* @property int|null $dungeon_route_id
* @property string|null $error
* @property string $import_string
*
* @property DungeonRoute $dungeonRoute
* @property Carbon $created_at
* @property Carbon $updated_at
*
* @mixin Eloquent
*/
Expand All @@ -21,13 +27,14 @@ class MDTImport extends Model

protected $fillable = [
'dungeon_route_id',
'error',
'import_string',
];

/**
* Get the dungeon route that this import created.
*/
public function dungeonroute(): BelongsTo
public function dungeonRoute(): BelongsTo
{
return $this->belongsTo(DungeonRoute::class);
}
Expand Down
2 changes: 1 addition & 1 deletion app/Providers/KeystoneGuruServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ static function (View $view) use ($globalViewVariables) {
$view->with('nextSeason', $regionViewVariables['nextSeason']);
$view->with('selectedSeason', $selectedSeason);
$view->with('currentAffixGroup', $selectedSeason->getCurrentAffixGroup());
$view->with('affixgroups', $selectedSeason->affixGroups);
$view->with('affixGroups', $selectedSeason->affixGroups);
$view->with('dungeons', $selectedSeason->dungeons);
});

Expand Down
16 changes: 11 additions & 5 deletions app/Service/DungeonRoute/CoverageService.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,9 @@ public function getForUser(User $user, Season $season): Collection
return DungeonRoute::with(['affixes'])
->selectRaw('dungeon_routes.*, IF(dungeon_routes.enemy_forces < mapping_versions.enemy_forces_required, 0, 1) as has_enemy_forces')
->join('dungeons', 'dungeons.id', 'dungeon_routes.dungeon_id')
->join('dungeon_route_affix_groups', 'dungeon_route_affix_groups.dungeon_route_id', 'dungeon_routes.id')
->join('affix_groups', 'affix_groups.id', 'dungeon_route_affix_groups.affix_group_id')
->join('season_dungeons', 'season_dungeons.dungeon_id', 'dungeons.id')
->join('mapping_versions', 'mapping_versions.id', 'dungeon_routes.mapping_version_id')
->where('dungeon_routes.author_id', $user->id)
->where('affix_groups.season_id', $season->id)
->where('season_dungeons.season_id', $season->id)
->where('dungeon_routes.season_id', $season->id)
->whereNull('expires_at')
->groupBy('dungeon_routes.id')
->get()
Expand All @@ -42,5 +38,15 @@ public function getForUser(User $user, Season $season): Collection
// and `season_dungeons`.`season_id` = 9
// and `expires_at` is null
// group by `dungeon_routes`.`id`


// select dungeon_routes.*, IF(mapping_versions.enemy_forces_required > dungeon_routes.enemy_forces, 0, 1) as has_enemy_forces
// from `dungeon_routes`
// inner join `mapping_versions` on `mapping_versions`.`id` = `dungeon_routes`.`mapping_version_id`
// where `dungeon_routes`.`author_id` = 20265
// and `dungeon_routes`.`season_id` = 14
// and `expires_at` is null
// group by `dungeon_routes`.`id`
// ORDER BY `dungeon_routes`.`dungeon_id` ASC
}
}
22 changes: 11 additions & 11 deletions app/Service/MDT/MDTExportStringService.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,9 @@ private function extractPulls(MappingVersion $mappingVersion, Collection $warnin
NpcClassification::ALL[NpcClassification::NPC_CLASSIFICATION_BOSS],
NpcClassification::ALL[NpcClassification::NPC_CLASSIFICATION_FINAL_BOSS]]
)) {
$warnings->push(new ImportWarning(sprintf(__('logic.mdt.io.export_string.category.pull'), $pullIndex),
sprintf(__('logic.mdt.io.export_string.unable_to_find_mdt_enemy_for_kg_enemy'), $enemy->npc->name, $enemy->id, $enemy->getMdtNpcId()),
['details' => __('logic.mdt.io.export_string.unable_to_find_mdt_enemy_for_kg_enemy_details')]
$warnings->push(new ImportWarning(sprintf(__('services.mdt.io.export_string.category.pull'), $pullIndex),
sprintf(__('services.mdt.io.export_string.unable_to_find_mdt_enemy_for_kg_enemy'), $enemy->npc->name, $enemy->id, $enemy->getMdtNpcId()),
['details' => __('services.mdt.io.export_string.unable_to_find_mdt_enemy_for_kg_enemy_details')]
));
}

Expand All @@ -224,8 +224,8 @@ private function extractPulls(MappingVersion $mappingVersion, Collection $warnin

// Do not add an empty pull if the killed enemy in our killzone was removed because it didn't exist in MDT, and that caused the pull to be empty
if ($killZoneEnemies->count() !== 0 && $enemiesAdded === 0) {
$warnings->push(new ImportWarning(sprintf(__('logic.mdt.io.export_string.category.pull'), $pullIndex),
__('logic.mdt.io.export_string.unable_to_find_mdt_enemy_for_kg_caused_empty_pull'),
$warnings->push(new ImportWarning(sprintf(__('services.mdt.io.export_string.category.pull'), $pullIndex),
__('services.mdt.io.export_string.unable_to_find_mdt_enemy_for_kg_caused_empty_pull'),
));

continue;
Expand Down Expand Up @@ -289,9 +289,9 @@ public function getEncodedString(Collection $warnings): string
// If stripping ascii characters worked in changing the title somehow
if ($asciiTitle !== $this->dungeonRoute->title) {
$warnings->push(
new ImportWarning(__('logic.mdt.io.export_string.category.title'),
__('logic.mdt.io.export_string.route_title_contains_non_ascii_char_bug'),
['details' => sprintf(__('logic.mdt.io.export_string.route_title_contains_non_ascii_char_bug_details'), $this->dungeonRoute->title, $asciiTitle)]
new ImportWarning(__('services.mdt.io.export_string.category.title'),
__('services.mdt.io.export_string.route_title_contains_non_ascii_char_bug'),
['details' => sprintf(__('services.mdt.io.export_string.route_title_contains_non_ascii_char_bug_details'), $this->dungeonRoute->title, $asciiTitle)]
)
);
$this->dungeonRoute->title = $asciiTitle;
Expand All @@ -304,9 +304,9 @@ public function getEncodedString(Collection $warnings): string
$asciiComment = preg_replace('/[[:^print:]]/', '', $mapicon->comment ?? '');
if ($asciiComment !== $mapicon->comment) {
$warnings->push(
new ImportWarning(__('logic.mdt.io.export_string.category.map_icon'),
__('logic.mdt.io.export_string.map_icon_contains_non_ascii_char_bug'),
['details' => sprintf(__('logic.mdt.io.export_string.map_icon_contains_non_ascii_char_bug_details'), $asciiComment, $mapicon->comment)]
new ImportWarning(__('services.mdt.io.export_string.category.map_icon'),
__('services.mdt.io.export_string.map_icon_contains_non_ascii_char_bug'),
['details' => sprintf(__('services.mdt.io.export_string.map_icon_contains_non_ascii_char_bug_details'), $asciiComment, $mapicon->comment)]
)
);
$mapicon->comment = $asciiComment;
Expand Down
Loading

0 comments on commit 352eb0e

Please sign in to comment.