-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Support for Gecko Codes to Achievements Whitelist #12955
base: master
Are you sure you want to change the base?
Add Support for Gecko Codes to Achievements Whitelist #12955
Conversation
774e6a8
to
2f1eaf5
Compare
I recommend also supporting Action Replay codes. |
I can add that as well, but thought one step at a time, and the requests have overwhelmingly been for Gecko next. |
Okay, I suppose we can do one at a time. |
The message "Failed to verify patch {} from file {}." currently mentions patches specifically. It should either mention the specific type of code (i.e. Gecko code or patch), or it could say just "code" instead of "patch". |
b79f789
to
f10a618
Compare
Smoke-tested? |
In particular, please test if there is any way to cause this to discard 'unapproved' codes from the user's local game INI. It's unclear to me whether that is possible from the code. |
I missed something in my review: The unit test (PatchAllowlistTest.cpp) is still only checking patches, not Gecko codes. |
Decided to add a couple things anyways so I'm drafting this until it's ready. |
16f958b
to
afb9862
Compare
afb9862
to
b508ab4
Compare
I'm not entirely certain I follow what you mean here @AdmiralCurtiss , I'm not aware of anything that causes codes to be removed from the INI files but I don't know what I don't know. I'm definitely not calling it on purpose; the functionality should simply be filtering out active codes. I think. |
96a8a0e
to
4c1bff9
Compare
What I mean is, this seems like a perfectly plausible code path that I'm not sure how you're preventing:
later:
|
While I'm looking into other questions brought up by this investigation, I can tell you that it appears that no code path within Dolphin is modifying ini files from the Sys folder, aka codes from the repo. What to do with user codes is a different question I'm evaluating in the Discord server currently. |
8644e1f
to
6458d6e
Compare
6458d6e
to
d68e897
Compare
d68e897
to
164580a
Compare
Now that patches and codes are enabled on a case by case basis, remove patcher code blocking codes entirely in hardcore mode, and reword the warning to be more accurate.
Due to a strange compatibility bug with creator name on Gecko codes, this also adds the SSL patch on all versions of the Nintendo Channel.
164580a
to
4f3e3d2
Compare
FifoCI detected that this change impacts graphical rendering. Here are the behavior differences detected by the system:
automated-fifoci-reporter |
@@ -312,4 +328,4 @@ | |||
"title": "Gormiti: The Lords of Nature!", | |||
"6F8CD59D897338CA90939149E1A62588620C6D88": "Fix black screen" | |||
} | |||
} | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add trailing newlines to all files that lack them.
void AchievementManager::FilterApprovedPatches(std::vector<PatchEngine::Patch>& patches, | ||
const std::string& game_ini_id) const | ||
template <typename T> | ||
void AchievementManager::FilterApprovedIni(std::vector<T>& patches, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void AchievementManager::FilterApprovedIni(std::vector<T>& patches, | |
void AchievementManager::FilterApprovedIni(std::vector<T>& codes, |
@@ -387,46 +390,100 @@ void AchievementManager::FilterApprovedPatches(std::vector<PatchEngine::Patch>& | |||
if (!IsHardcoreModeActive()) | |||
return; | |||
|
|||
// Approved patches list failed to hash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Approved patches list failed to hash | |
// Approved codes list failed to hash |
INFO_LOG_FMT(ACHIEVEMENTS, "Verifying patch {}", patch_itr->name); | ||
if (patch_itr->enabled) | ||
{ | ||
INFO_LOG_FMT(ACHIEVEMENTS, "Verifying patch {}", patch_itr->name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
INFO_LOG_FMT(ACHIEVEMENTS, "Verifying patch {}", patch_itr->name); | |
INFO_LOG_FMT(ACHIEVEMENTS, "Verifying code {}", patch_itr->name); |
Common::SHA1::Digest GetPatchHash(const PatchEngine::Patch& patch) const; | ||
Common::SHA1::Digest GetPatchHash(const Gecko::GeckoCode& patch) const; | ||
Common::SHA1::Digest GetPatchHash(const ActionReplay::ARCode& patch) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Common::SHA1::Digest GetPatchHash(const PatchEngine::Patch& patch) const; | |
Common::SHA1::Digest GetPatchHash(const Gecko::GeckoCode& patch) const; | |
Common::SHA1::Digest GetPatchHash(const ActionReplay::ARCode& patch) const; | |
Common::SHA1::Digest GetCodeHash(const PatchEngine::Patch& code) const; | |
Common::SHA1::Digest GetCodeHash(const Gecko::GeckoCode& code) const; | |
Common::SHA1::Digest GetCodeHash(const ActionReplay::ARCode& code) const; |
auto ar_codes = ActionReplay::LoadCodes(globalIni, localIni); | ||
#ifdef USE_RETRO_ACHIEVEMENTS | ||
{ | ||
std::lock_guard lg{AchievementManager::GetInstance().GetLock()}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant locking.
@@ -524,9 +524,6 @@ static bool MemoryMatchesAt(const Core::CPUThreadGuard& guard, u32 offset, | |||
static void ApplyMemoryPatch(const Core::CPUThreadGuard& guard, u32 offset, | |||
std::span<const u8> value, std::span<const u8> original) | |||
{ | |||
if (AchievementManager::GetInstance().IsHardcoreModeActive()) | |||
return; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure you want to remove this? You have no filtering for Riivolution memory patches.
@@ -35,7 +35,7 @@ void HardcoreWarningWidget::CreateWidgets() | |||
auto* icon = new QLabel; | |||
icon->setPixmap(warning_icon); | |||
|
|||
m_text = new QLabel(tr("This feature is disabled in hardcore mode.")); | |||
m_text = new QLabel(tr("Unapproved codes will not be applied in hardcore mode.")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion, this would be clearer without the double negative:
m_text = new QLabel(tr("Unapproved codes will not be applied in hardcore mode.")); | |
m_text = new QLabel(tr("In hardcore mode, only approved codes will be applied.")); |
But this is only a suggestion.
#ifdef USE_RETRO_ACHIEVEMENTS | ||
{ | ||
std::lock_guard lg{AchievementManager::GetInstance().GetLock()}; | ||
AchievementManager::GetInstance().FilterApprovedARCodes(m_ar_codes, m_game_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doing filtering in ARCodeWidget and GeckoCodeWidget looks a lot to me like it would cause the problem AdmiralCurtiss mentioned. Look just a few lines below and you'll see a call to SaveCodes.
@@ -67,12 +70,22 @@ TEST(PatchAllowlist, VerifyHashes) | |||
Common::IniFile ini_file; | |||
ini_file.Load(file.physicalName, true); | |||
std::string game_id = file.virtualName.substr(0, file.virtualName.find_first_of('.')); | |||
std::map<std::string /*hash*/, std::string /*name*/> hashes; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be a bit more efficient to, instead of having an std::map
where you store all hashes, have a "check hash" function that you can call from the patches loop, the AR codes loop and the Gecko loop. That way, instead of having to store the hash from each loop iteration in the std::map
, you can discard the hash at the end of each loop iteration, like the code was doing before this PR.
The description of the last commit mentions "a strange compatibility bug with creator name on Gecko codes". Could you explain why this means you should allowlist the SSL patch for the Nintendo Channel? |
Also, have you checked what happens if you use netplay code syncing when the person hosting isn't using hardcore mode but the person joining is? |
This PR sets up the Achievements whitelist for patches to also support Gecko codes.