Skip to content

Commit

Permalink
Merge branch 'master' into conditional-aotw-gold-border
Browse files Browse the repository at this point in the history
  • Loading branch information
wescopeland authored Jan 22, 2025
2 parents 3db8977 + b02cbcd commit 6bbaf79
Show file tree
Hide file tree
Showing 7 changed files with 333 additions and 35 deletions.
4 changes: 2 additions & 2 deletions app/Connect/Actions/BuildClientPatchDataAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public function execute(
return $this->buildPatchData($game, null, $user, $flag);
}

$rootGameId = (new ResolveRootGameIdAction())->execute($gameHash, $game, $user);
$rootGameId = (new ResolveRootGameIdFromGameAndGameHashAction())->execute($gameHash, $game, $user);
$rootGame = Game::find($rootGameId);

// If multiset is disabled or there's no user, just use the game directly.
Expand All @@ -69,7 +69,7 @@ public function execute(
$richPresencePatch = $coreGame->RichPresencePatch;

// For specialty/exclusive sets, we use:
// - The root game's ID and achievements (already determined by ResolveRootGameIdAction).
// - The root game's ID and achievements (already determined by ResolveRootGameIdFromGameAndGameHashAction).
// - The core game's title and image.
// - The root game's RP if present, otherwise fall back to core game's RP.
if ($rootGameId === $gameHash->game->id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use App\Platform\Enums\AchievementSetType;
use InvalidArgumentException;

class ResolveRootGameIdAction
class ResolveRootGameIdFromGameAndGameHashAction
{
/**
* Resolves the root game ID for a given game hash and user combination.
Expand Down
46 changes: 46 additions & 0 deletions app/Connect/Actions/ResolveRootGameIdFromGameIdAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace App\Connect\Actions;

use App\Models\GameAchievementSet;
use App\Platform\Enums\AchievementSetType;

/**
* Note that this action is somewhat naive and does not take into
* account any hash loaded by a user or any user settings. It simply
* attempts to find what the ultimate "parent" game is.
*/
class ResolveRootGameIdFromGameIdAction
{
public function execute(int $gameId): int
{
// Get the game's achievement sets.
$sets = GameAchievementSet::whereGameId($gameId)->get();
if ($sets->isEmpty()) {
return $gameId;
}

// For each achievement set, look for other games that reference this set.
foreach ($sets as $set) {
// Find all games that reference this achievement set.
$linkedSets = GameAchievementSet::whereAchievementSetId($set->achievement_set_id)
->where('game_id', '!=', $gameId)
->get();

// Look for a game that uses this set as a non-core type.
$parentSet = $linkedSets->first(function ($linkedSet) {
return $linkedSet->type !== AchievementSetType::Core;
});

if ($parentSet) {
// We found a parent - return its game_id value.
return $parentSet->game_id;
}
}

// No parent found, this must be the root game.
return $gameId;
}
}
13 changes: 8 additions & 5 deletions app/Helpers/database/player-game.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,16 @@ function getUserAchievementUnlocksForGame(User|string $user, int $gameID, Achiev

$playerAchievements = $user
->playerAchievements()
->join('Achievements', 'Achievements.ID', '=', 'achievement_id')
->where('GameID', $gameID)
->join('Achievements', 'Achievements.ID', '=', 'player_achievements.achievement_id')
->join('achievement_set_achievements', 'Achievements.ID', '=', 'achievement_set_achievements.achievement_id')
->join('achievement_sets', 'achievement_sets.id', '=', 'achievement_set_achievements.achievement_set_id')
->join('game_achievement_sets', 'game_achievement_sets.achievement_set_id', '=', 'achievement_sets.id')
->where('game_achievement_sets.game_id', $gameID)
->where('Flags', $flag->value)
->get([
'achievement_id',
'unlocked_at',
'unlocked_hardcore_at',
'player_achievements.achievement_id',
'player_achievements.unlocked_at',
'player_achievements.unlocked_hardcore_at',
])
->mapWithKeys(function ($unlock, int $key) {
$result = [];
Expand Down
9 changes: 5 additions & 4 deletions public/dorequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
use App\Connect\Actions\BuildClientPatchDataAction;
use App\Connect\Actions\GetClientSupportLevelAction;
use App\Connect\Actions\InjectPatchClientSupportLevelDataAction;
use App\Connect\Actions\ResolveRootGameIdAction;
use App\Connect\Actions\ResolveRootGameIdFromGameAndGameHashAction;
use App\Connect\Actions\ResolveRootGameIdFromGameIdAction;
use App\Enums\ClientSupportLevel;
use App\Enums\Permissions;
use App\Models\Achievement;
Expand Down Expand Up @@ -335,7 +336,7 @@ function DoRequestError(string $error, ?int $status = 200, ?string $code = null)

// If multiset is enabled, resolve the root game ID.
if (config('feature.enable_multiset')) {
$rootGameId = (new ResolveRootGameIdAction())->execute($gameHash, $game, $user);
$rootGameId = (new ResolveRootGameIdFromGameAndGameHashAction())->execute($gameHash, $game, $user);
$game = Game::find($rootGameId);
}

Expand Down Expand Up @@ -622,7 +623,7 @@ function DoRequestError(string $error, ?int $status = 200, ?string $code = null)

$response['Success'] = true;
$userModel = User::whereName($username)->first();
$userUnlocks = getUserAchievementUnlocksForGame($userModel, $gameID);
$userUnlocks = getUserAchievementUnlocksForGame($userModel, (new ResolveRootGameIdFromGameIdAction())->execute($gameID));
$userUnlocks = reactivateUserEventAchievements($userModel, $userUnlocks);
foreach ($userUnlocks as $achId => $unlock) {
if (array_key_exists('DateEarnedHardcore', $unlock)) {
Expand Down Expand Up @@ -745,7 +746,7 @@ function DoRequestError(string $error, ?int $status = 200, ?string $code = null)
case "unlocks":
$hardcoreMode = (int) request()->input('h', 0) === UnlockMode::Hardcore;
$userModel = User::whereName($username)->first();
$userUnlocks = getUserAchievementUnlocksForGame($userModel, $gameID);
$userUnlocks = getUserAchievementUnlocksForGame($userModel, (new ResolveRootGameIdFromGameIdAction())->execute($gameID));
if ($hardcoreMode) {
$userUnlocks = reactivateUserEventAchievements($userModel, $userUnlocks);
$response['UserUnlocks'] = collect($userUnlocks)
Expand Down
Loading

0 comments on commit 6bbaf79

Please sign in to comment.