Skip to content
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

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

LillyJadeKatrin
Copy link
Contributor

This PR sets up the Achievements whitelist for patches to also support Gecko codes.

@LillyJadeKatrin LillyJadeKatrin force-pushed the retroachievements-gecko branch 2 times, most recently from 774e6a8 to 2f1eaf5 Compare July 25, 2024 13:28
@JosJuice
Copy link
Member

I recommend also supporting Action Replay codes.

@LillyJadeKatrin
Copy link
Contributor Author

I can add that as well, but thought one step at a time, and the requests have overwhelmingly been for Gecko next.

@JosJuice
Copy link
Member

Okay, I suppose we can do one at a time.

@JosJuice
Copy link
Member

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".

@LillyJadeKatrin LillyJadeKatrin force-pushed the retroachievements-gecko branch 2 times, most recently from b79f789 to f10a618 Compare August 9, 2024 01:07
JosJuice
JosJuice previously approved these changes Aug 11, 2024
@Tilka
Copy link
Member

Tilka commented Aug 11, 2024

Smoke-tested?

@AdmiralCurtiss
Copy link
Contributor

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.

@JosJuice
Copy link
Member

I missed something in my review: The unit test (PatchAllowlistTest.cpp) is still only checking patches, not Gecko codes.

@LillyJadeKatrin LillyJadeKatrin marked this pull request as draft August 16, 2024 00:16
@LillyJadeKatrin
Copy link
Contributor Author

Decided to add a couple things anyways so I'm drafting this until it's ready.

@LillyJadeKatrin LillyJadeKatrin force-pushed the retroachievements-gecko branch 5 times, most recently from 16f958b to afb9862 Compare September 12, 2024 23:52
@LillyJadeKatrin
Copy link
Contributor Author

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'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.

@LillyJadeKatrin LillyJadeKatrin marked this pull request as ready for review October 5, 2024 03:07
@AdmiralCurtiss
Copy link
Contributor

What I mean is, this seems like a perfectly plausible code path that I'm not sure how you're preventing:

GeckoCodeWidget constructor
  calls GeckoCodeWidget::LoadCodes()
   calls Gecko::LoadCodes(game_ini_default, game_ini_local)
     filters codes, removes any unapproved
   filtered codes are stored in m_gecko_codes

later:

GeckoCodeWidget::SaveCodes() is called for any reason
  calls Gecko::SaveCodes(game_ini_local, m_gecko_codes) with the filtered codes
    calls inifile.SetLines("Gecko", lines) with filtered codes
      overwrites any pre-existing codes in the ini
  saves modified ini without the unapproved codes to disk

@LillyJadeKatrin
Copy link
Contributor Author

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.

@LillyJadeKatrin LillyJadeKatrin force-pushed the retroachievements-gecko branch 4 times, most recently from 8644e1f to 6458d6e Compare October 6, 2024 22:31
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.
@LillyJadeKatrin LillyJadeKatrin marked this pull request as ready for review October 15, 2024 02:03
@dolphin-ci
Copy link

dolphin-ci bot commented Oct 15, 2024

FifoCI detected that this change impacts graphical rendering. Here are the behavior differences detected by the system:

  • sw3-dt on ogl-lin-mesa: diff

automated-fifoci-reporter

@JosJuice JosJuice dismissed their stale review October 15, 2024 07:58

Re-reviewing after the new changes

@@ -312,4 +328,4 @@
"title": "Gormiti: The Lords of Nature!",
"6F8CD59D897338CA90939149E1A62588620C6D88": "Fix black screen"
}
}
}
Copy link
Member

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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// 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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
INFO_LOG_FMT(ACHIEVEMENTS, "Verifying patch {}", patch_itr->name);
INFO_LOG_FMT(ACHIEVEMENTS, "Verifying code {}", patch_itr->name);

Comment on lines +202 to +204
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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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()};
Copy link
Member

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;

Copy link
Member

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."));
Copy link
Member

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:

Suggested change
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);
Copy link
Member

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;
Copy link
Member

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.

@JosJuice
Copy link
Member

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?

@JosJuice
Copy link
Member

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants