Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/RA_Integration.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="data\context\GameAssets.cpp" />
<ClCompile Include="api\ApiCall.cpp" />
<ClCompile Include="api\impl\ConnectedServer.cpp" />
<ClCompile Include="api\impl\DisconnectedServer.cpp" />
Expand Down Expand Up @@ -206,7 +205,6 @@
<ClInclude Include="api\UpdateRichPresence.hh" />
<ClInclude Include="api\UploadBadge.hh" />
<ClInclude Include="data\context\EmulatorContext.hh" />
<ClInclude Include="data\context\GameAssets.hh" />
<ClInclude Include="data\context\GameContext.hh" />
<ClInclude Include="data\context\SessionTracker.hh" />
<ClInclude Include="data\Types.hh" />
Expand Down
6 changes: 0 additions & 6 deletions src/RA_Integration.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,6 @@
<ClCompile Include="data\context\SessionTracker.cpp">
<Filter>Data\Context</Filter>
</ClCompile>
<ClCompile Include="data\context\GameAssets.cpp">
<Filter>Data\Context</Filter>
</ClCompile>
<ClCompile Include="ui\viewmodels\ProgressViewModel.cpp">
<Filter>UI\ViewModels</Filter>
</ClCompile>
Expand Down Expand Up @@ -791,9 +788,6 @@
<ClInclude Include="data\context\SessionTracker.hh">
<Filter>Data\Context</Filter>
</ClInclude>
<ClInclude Include="data\context\GameAssets.hh">
<Filter>Data\Context</Filter>
</ClInclude>
<ClInclude Include="ui\viewmodels\ProgressViewModel.hh">
<Filter>UI\ViewModels</Filter>
</ClInclude>
Expand Down
68 changes: 14 additions & 54 deletions src/data/context/GameContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ bool GameContext::BeginLoadGame(unsigned int nGameId, Mode nMode, bool& bWasPaus
// reset the GameContext
m_nMode = nMode;
m_sGameTitle.clear();
m_vSubsets.clear();
m_vAssets.ClearAchievementSets();
m_vAssets.ResetLocalId();

m_vAssets.BeginUpdate();
Expand Down Expand Up @@ -293,7 +293,7 @@ void GameContext::EndLoadGame(int nResult, bool bWasPaused, bool bShowSoftcoreWa
// activate rich presence (or remove if not defined)
if (pRichPresence && nResult == RC_OK)
{
pRichPresence->SetSubsetID(m_vSubsets.front().AchievementSetID());
pRichPresence->SetSubsetID(Assets().AchievementSets().GetItemAt(0)->GetID());

// if the server value differs from the local value, the model will appear as Unpublished
if (pRichPresence->GetChanges() != ra::data::models::AssetChanges::None)
Expand Down Expand Up @@ -501,11 +501,6 @@ void GameContext::InitializeFromAchievementRuntime(const std::map<uint32_t, std:

void GameContext::InitializeSubsets(const rc_api_fetch_game_sets_response_t* game_data_response)
{
Expects(game_data_response != nullptr);

std::lock_guard<std::mutex> lock(m_mLoadMutex);
m_vSubsets.clear();

// GameID dictates which game is loaded for purposes of local achievement storage and memory notes
m_nGameId = GetRealGameId(game_data_response->id);
// ActiveGameID dictates which game is running for purposes of rich presence and pings
Expand All @@ -516,69 +511,34 @@ void GameContext::InitializeSubsets(const rc_api_fetch_game_sets_response_t* gam
ra::services::ServiceLocator::GetMutable<ra::data::context::SessionTracker>().BeginSession(nActiveGameId);
}

for (uint32_t i = 0; i < game_data_response->num_sets; ++i)
{
const auto* pSet = &game_data_response->sets[i];
if (pSet->type == RC_ACHIEVEMENT_SET_TYPE_CORE)
{
// core subset should always be first
m_vSubsets.insert(m_vSubsets.begin(),
Subset(pSet->id, GetRealGameId(pSet->game_id),
ra::util::String::Widen(pSet->title), SubsetType::Core));
}
else
{
SubsetType nType = SubsetType::Bonus;
switch (pSet->type)
{
case RC_ACHIEVEMENT_SET_TYPE_EXCLUSIVE:
nType = SubsetType::Exclusive;
break;
case RC_ACHIEVEMENT_SET_TYPE_SPECIALTY:
nType = SubsetType::Specialty;
break;
default:
nType = SubsetType::Bonus;
break;
}
m_vSubsets.emplace_back(pSet->id, GetRealGameId(pSet->game_id),
ra::util::String::Widen(pSet->title), nType);
}
}
Assets().InitializeSubsets(game_data_response, m_nActiveGameId != m_nGameId);

// if subsets were found, migrate any SUBSET-User.txt files into the the GAME-User.txt file
if (m_vSubsets.size() > 1)
{
if (Assets().AchievementSets().Count() > 1)
MigrateSubsetUserFiles();
}
else if (m_nActiveGameId != m_nGameId)
{
m_vSubsets.front().SetTitle(ra::util::String::Printf(L"%s (%s)",
m_vSubsets.front().Title(), game_data_response->title));
}
}

void GameContext::MigrateSubsetUserFiles()
{
auto& pLocalStorage = ra::services::ServiceLocator::GetMutable<ra::services::ILocalStorage>();
std::unique_ptr<ra::services::TextWriter> pGameData;

for (size_t i = 1; i < m_vSubsets.size(); ++i)
for (const auto& pSubset : Assets().AchievementSets())
{
const auto& pSubset = m_vSubsets.at(i);
Expects(pSubset.GameID() != m_nGameId);
if (pSubset.GetBackingGameID() == m_nGameId)
continue;

auto pSubsetData = pLocalStorage.ReadText(ra::services::StorageItemType::UserAchievements,
std::to_wstring(pSubset.GameID()));
std::to_wstring(pSubset.GetBackingGameID()));
if (pSubsetData)
{
// replace ID with "0|SUBSETID" so new IDs will be generated
std::string sSubsetReplace = "0|" + std::to_string(pSubset.AchievementSetID());
std::string sSubsetReplace = "0|" + std::to_string(pSubset.GetID());

if (!pGameData)
{
pGameData = pLocalStorage.AppendText(ra::services::StorageItemType::UserAchievements,
std::to_wstring(m_nGameId));
std::to_wstring(m_nGameId));
if (!pGameData)
{
RA_LOG_ERR("Could not append to %u-User.txt", m_nGameId);
Expand Down Expand Up @@ -622,17 +582,17 @@ void GameContext::MigrateSubsetUserFiles()
// release the file so it can be deleted, then delete it.
pSubsetData.reset();
pLocalStorage.Delete(ra::services::StorageItemType::UserAchievements,
std::to_wstring(pSubset.GameID()));
std::to_wstring(pSubset.GetBackingGameID()));
}
}
}

uint32_t GameContext::GetGameId(uint32_t nSubsetId) const noexcept
{
for (const auto& pSubset : m_vSubsets)
for (const auto& pSubset : Assets().AchievementSets())
{
if (pSubset.ID() == nSubsetId)
return pSubset.GameID();
if (pSubset.GetID() == nSubsetId)
return pSubset.GetBackingGameID();
}

return GameId();
Expand Down
64 changes: 4 additions & 60 deletions src/data/context/GameContext.hh
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@

#include "context/IGameContext.hh"

#include "data/models/GameAssets.hh"
#include "data/models/LocalBadgesModel.hh"

#include "services/ServiceLocator.hh"

#include "GameAssets.hh"

#include <string>
#include <atomic>

Expand Down Expand Up @@ -56,11 +55,6 @@ public:
/// </summary>
bool IsGameLoading() const noexcept { return m_nLoadCount != 0; }

/// <summary>
/// Gets the title of the currently loaded game.
/// </summary>
const std::wstring& GameTitle() const noexcept { return m_sGameTitle; }

/// <summary>
/// Sets the game title.
/// </summary>
Expand Down Expand Up @@ -95,20 +89,6 @@ public:
}
}

/// <summary>
/// Determines if the provided game identifier is virtual
/// </summary>
/// <remarks>
/// IDs above 1 billion are incompatible. The 100 millions place indicates how.
/// Mask off the part above 100 million to get the actual game id.
/// </remarks>
static constexpr bool IsVirtualGameId(uint32_t nGameId) noexcept { return nGameId > 1000000000; }

/// <summary>
/// Gets the real game identifier from a virtual one
/// </summary>
static constexpr uint32_t GetRealGameId(uint32_t nGameId) noexcept { return nGameId % 100000000; }

enum HashCompatibility
{
Compatible = 0,
Expand All @@ -128,44 +108,11 @@ public:
/// <summary>
/// Gets the assets for the current game.
/// </summary>
GameAssets& Assets() noexcept { return m_vAssets; }
const GameAssets& Assets() const noexcept { return m_vAssets; }
ra::data::models::GameAssets& Assets() noexcept { return m_vAssets; }
const ra::data::models::GameAssets& Assets() const noexcept { return m_vAssets; }

void DoFrame();

enum SubsetType
{
Core,
Bonus,
Specialty,
Exclusive,
};

class Subset
{
public:
Subset(uint32_t nAchievementSetId, uint32_t nGameId, const std::wstring& sTitle, SubsetType nType) :
m_sTitle(sTitle), m_nType(nType), m_nAchievementSetId(nAchievementSetId), m_nGameId(nGameId)
{
}

const std::wstring& Title() const noexcept { return m_sTitle; }
SubsetType Type() const noexcept { return m_nType; }
uint32_t AchievementSetID() const noexcept { return m_nAchievementSetId; }
uint32_t GameID() const noexcept { return m_nGameId; }

// Core assets have SubsetId of 0
uint32_t ID() const noexcept { return (m_nType == SubsetType::Core) ? 0 : m_nAchievementSetId; }

void SetTitle(const std::wstring& sTitle) { m_sTitle = sTitle; }

private:
std::wstring m_sTitle;
SubsetType m_nType;
uint32_t m_nAchievementSetId;
uint32_t m_nGameId;
};
const std::vector<Subset>& Subsets() const noexcept { return m_vSubsets; }
void InitializeSubsets(const rc_api_fetch_game_sets_response_t* game_data_response);
uint32_t GetGameId(uint32_t nSubsetId) const noexcept;

Expand Down Expand Up @@ -207,14 +154,11 @@ protected:
void BeginLoad();
void EndLoad();

std::wstring m_sGameTitle;
std::string m_sGameHash;
Mode m_nMode{};

std::vector<Subset> m_vSubsets;

private:
GameAssets m_vAssets;
ra::data::models::GameAssets m_vAssets;

std::atomic<int> m_nLoadCount = 0;
int m_nMasteryPopupId = 0;
Expand Down
11 changes: 9 additions & 2 deletions src/devkit/RADevKit.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="context\impl\ConsoleContext.cpp" />
<ClCompile Include="context\impl\DevKitContext.cpp" />
<ClCompile Include="context\impl\EmulatorMemoryContext.cpp" />
<ClCompile Include="context\impl\RcClient.cpp" />
<ClCompile Include="data\CapturedMemoryBlock.cpp" />
Expand All @@ -68,15 +69,17 @@
<ClCompile Include="data\ModelProperty.cpp" />
<ClCompile Include="data\ModelPropertyContainer.cpp" />
<ClCompile Include="data\models\AchievementModel.cpp" />
<ClCompile Include="data\models\AchievementSetModel.cpp" />
<ClCompile Include="data\models\AssetModelBase.cpp" />
<ClCompile Include="data\models\GameAssets.cpp" />
<ClCompile Include="data\models\LeaderboardModel.cpp" />
<ClCompile Include="data\models\LocalBadgesModel.cpp" />
<ClCompile Include="data\models\MemoryNoteModel.cpp" />
<ClCompile Include="data\models\MemoryNotesModel.cpp" />
<ClCompile Include="data\models\MemoryRegionsModel.cpp" />
<ClCompile Include="data\models\RichPresenceModel.cpp" />
<ClCompile Include="data\models\TriggerValidation.cpp" />
<ClCompile Include="data\util\IndirectNoteResolver.cpp" />
<ClCompile Include="data\util\TriggerValidation.cpp" />
<ClCompile Include="data\Value.cpp" />
<ClCompile Include="services\Http.cpp" />
<ClCompile Include="ui\ImageReference.cpp" />
Expand All @@ -85,9 +88,11 @@
<ClCompile Include="util\Strings.cpp" />
<ClCompile Include="util\Tokenizer.cpp" />
<ClInclude Include="context\IConsoleContext.hh" />
<ClInclude Include="context\IDevKitContext.hh" />
<ClInclude Include="context\IEmulatorMemoryContext.hh" />
<ClInclude Include="context\IGameContext.hh" />
<ClInclude Include="context\impl\ConsoleContext.hh" />
<ClInclude Include="context\impl\DevKitContext.hh" />
<ClInclude Include="context\impl\EmulatorMemoryContext.hh" />
<ClInclude Include="context\impl\RcClient.hh" />
<ClInclude Include="context\IRcClient.hh" />
Expand All @@ -103,16 +108,18 @@
<ClInclude Include="data\ModelProperty.hh" />
<ClInclude Include="data\ModelPropertyContainer.hh" />
<ClInclude Include="data\models\AchievementModel.hh" />
<ClInclude Include="data\models\AchievementSetModel.hh" />
<ClInclude Include="data\models\AssetModelBase.hh" />
<ClInclude Include="data\models\GameAssets.hh" />
<ClInclude Include="data\models\LeaderboardModel.hh" />
<ClInclude Include="data\models\LocalBadgesModel.hh" />
<ClInclude Include="data\models\MemoryNoteModel.hh" />
<ClInclude Include="data\models\MemoryNotesModel.hh" />
<ClInclude Include="data\models\MemoryRegionsModel.hh" />
<ClInclude Include="data\models\RichPresenceModel.hh" />
<ClInclude Include="data\models\TriggerValidation.hh" />
<ClInclude Include="data\NotifyTargetSet.hh" />
<ClInclude Include="data\util\IndirectNoteResolver.hh" />
<ClInclude Include="data\util\TriggerValidation.hh" />
<ClInclude Include="data\Value.hh" />
<ClInclude Include="services\Http.hh" />
<ClInclude Include="services\IClock.hh" />
Expand Down
33 changes: 27 additions & 6 deletions src/devkit/RADevKit.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,6 @@
<ClInclude Include="data\models\MemoryNotesModel.hh">
<Filter>data\models</Filter>
</ClInclude>
<ClInclude Include="data\models\TriggerValidation.hh">
<Filter>data\models</Filter>
</ClInclude>
<ClInclude Include="ui\IImageRepository.hh">
<Filter>ui</Filter>
</ClInclude>
Expand All @@ -207,6 +204,21 @@
<ClInclude Include="data\util\IndirectNoteResolver.hh">
<Filter>data\util</Filter>
</ClInclude>
<ClInclude Include="data\util\TriggerValidation.hh">
<Filter>data\util</Filter>
</ClInclude>
<ClInclude Include="context\impl\DevKitContext.hh">
<Filter>context\impl</Filter>
</ClInclude>
<ClInclude Include="context\IDevKitContext.hh">
<Filter>context</Filter>
</ClInclude>
<ClInclude Include="data\models\GameAssets.hh">
<Filter>data\models</Filter>
</ClInclude>
<ClInclude Include="data\models\AchievementSetModel.hh">
<Filter>data\models</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="util\GSL.cpp">
Expand Down Expand Up @@ -275,9 +287,6 @@
<ClCompile Include="data\models\MemoryNotesModel.cpp">
<Filter>data\models</Filter>
</ClCompile>
<ClCompile Include="data\models\TriggerValidation.cpp">
<Filter>data\models</Filter>
</ClCompile>
<ClCompile Include="ui\ImageReference.cpp">
<Filter>ui</Filter>
</ClCompile>
Expand All @@ -293,5 +302,17 @@
<ClCompile Include="data\util\IndirectNoteResolver.cpp">
<Filter>data\util</Filter>
</ClCompile>
<ClCompile Include="data\util\TriggerValidation.cpp">
<Filter>data\util</Filter>
</ClCompile>
<ClCompile Include="context\impl\DevKitContext.cpp">
<Filter>context\impl</Filter>
</ClCompile>
<ClCompile Include="data\models\GameAssets.cpp">
<Filter>data\models</Filter>
</ClCompile>
<ClCompile Include="data\models\AchievementSetModel.cpp">
<Filter>data\models</Filter>
</ClCompile>
</ItemGroup>
</Project>
Loading
Loading