diff --git a/code/components/steam/component.lua b/code/components/steam/component.lua index e69de29bb2..0228009c14 100644 --- a/code/components/steam/component.lua +++ b/code/components/steam/component.lua @@ -0,0 +1,3 @@ +return function() + add_dependencies { "vendor:utfcpp" } +end \ No newline at end of file diff --git a/code/components/steam/src/SteamComponent.cpp b/code/components/steam/src/SteamComponent.cpp index a990cef575..f19c04aeb9 100644 --- a/code/components/steam/src/SteamComponent.cpp +++ b/code/components/steam/src/SteamComponent.cpp @@ -19,13 +19,14 @@ #include #include +#include + struct CfxPresenceState { char gameName[512]; - volatile bool needRefresh; + int childPid = 0; CfxPresenceState() - : needRefresh(0) { memset(gameName, 0, sizeof(gameName)); } @@ -389,22 +390,32 @@ void SteamComponent::InitializePresence() if (GetFileAttributes(namePath.c_str()) != INVALID_FILE_ATTRIBUTES) { - std::wifstream nameFile(namePath); - std::wstringstream nameStream; + std::ifstream nameFile(namePath); + std::stringstream nameStream; nameStream << nameFile.rdbuf(); nameFile.close(); - productName = ToNarrow(nameStream.str()); + productName = nameStream.str(); } static HostSharedData gameData("PresenceState"); - gameData->needRefresh = false; if (gameData->gameName[0]) { productName += fmt::sprintf(": %s", gameData->gameName); } + // Steam requires the name to fit in a 64-byte buffer, so we try to make sure there's no unfinished UTF-8 sequences in that case + if (productName.length() >= 64) + { + productName = productName.substr(0, 63); + + if (auto invalidPos = utf8::find_invalid(productName); invalidPos != std::string::npos) + { + productName = productName.substr(0, invalidPos); + } + } + // set our pipe appid InterfaceMapper steamUtils(m_clientEngine->GetIClientUtils(m_steamPipe, "CLIENTUTILS_INTERFACE_VERSION001")); @@ -492,6 +503,11 @@ bool SteamComponent::RunPresenceDummy() trace("game parent PID: %d\n", parentPid); + HostSharedData gameData("PresenceState"); + + auto currentPid = GetCurrentProcessId(); + gameData->childPid = currentPid; + // open a handle to the parent process with SYNCHRONIZE rights HANDLE processHandle = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION, FALSE, parentPid); @@ -512,9 +528,7 @@ bool SteamComponent::RunPresenceDummy() break; } - static HostSharedData gameData("PresenceState"); - - if (gameData->needRefresh) + if (gameData->childPid != currentPid) { return true; } @@ -651,9 +665,11 @@ void SteamComponent::SetRichPresenceValue(int idx, const std::string& value) if (updateGameName) { static HostSharedData gameData("PresenceState"); - gameData->needRefresh = true; strcpy_s(gameData->gameName, value.c_str()); + // reset the child PID to make the current process exit early if it can + gameData->childPid = 0; + RunChildLauncher(); } } diff --git a/vendor/utfcpp b/vendor/utfcpp index 60c490b89f..aed58281cf 160000 --- a/vendor/utfcpp +++ b/vendor/utfcpp @@ -1 +1 @@ -Subproject commit 60c490b89fadc8f4e8dc0497500348572aee4b18 +Subproject commit aed58281cf45838bdb7296e3109bd5a633d677ed