diff --git a/Library/GameMode.cpp b/Library/GameMode.cpp index 8495072e2..0dac0d9e6 100644 --- a/Library/GameMode.cpp +++ b/Library/GameMode.cpp @@ -221,6 +221,34 @@ void GameMode::ValidateActions() } } +bool GameMode::HasBangOverride(LPCWSTR str) +{ + std::wstring tmp = str; + std::wstring::size_type pos = tmp.find_first_of('!'); + if (pos != std::wstring::npos) + { + tmp = tmp.substr(pos + 1).c_str(); + for (const auto item : GetBangOverrideList()) + { + if (_wcsicmp(tmp.c_str(), item) == 0) + { + return true; + } + } + } + + return false; +} + +const std::vector& GameMode::GetBangOverrideList() +{ + static const std::vector s_BangOverrideList = + { + L"Quit" + }; + return s_BangOverrideList; +} + void GameMode::StartTimer() { OnTimerEvent(s_TimerEventID); // Don't wait for the first interval diff --git a/Library/GameMode.h b/Library/GameMode.h index d5498ad26..27d2ecccb 100644 --- a/Library/GameMode.h +++ b/Library/GameMode.h @@ -44,6 +44,10 @@ class GameMode void ValidateActions(); + bool HasBangOverride(LPCWSTR str); + + static const std::vector& GetBangOverrideList(); + private: enum class State : UINT { diff --git a/Library/Rainmeter.cpp b/Library/Rainmeter.cpp index df3cd7ac0..859085aa3 100644 --- a/Library/Rainmeter.cpp +++ b/Library/Rainmeter.cpp @@ -710,12 +710,16 @@ LRESULT CALLBACK Rainmeter::MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPA case WM_COPYDATA: { COPYDATASTRUCT* cds = (COPYDATASTRUCT*)lParam; - if (cds && !GetGameMode().IsEnabled()) // Disallow any bangs in manual "Game mode" + if (cds) { const WCHAR* data = (const WCHAR*)cds->lpData; if (cds->dwData == 1 && (cds->cbData > 0)) { - GetRainmeter().DelayedExecuteCommand(data); + // Disallow any bangs in manual "Game mode" except any overrides. See GameMode::GetBangOverrideList + if (!GetGameMode().IsEnabled() || GetGameMode().HasBangOverride(data)) + { + GetRainmeter().DelayedExecuteCommand(data); + } } } }