From 953d6c6ff7566bd546329d0bf8aea5f48f457b90 Mon Sep 17 00:00:00 2001 From: weter11 Date: Fri, 13 Feb 2026 15:44:56 +0200 Subject: [PATCH] Harden library scan, persist install manifests, and remove legacy projects --- OpenSteamClient.DI | 1 - OpenSteamClient.Logging | 1 - OpenSteamClient.sln | 194 ++++++++++++++++------------------ SteamFlow/README.md | 4 + SteamFlow/ROADMAP.md | 3 + SteamFlow/src/library.rs | 35 ++++-- SteamFlow/src/steam_client.rs | 70 ++++++++++-- 7 files changed, 187 insertions(+), 121 deletions(-) delete mode 160000 OpenSteamClient.DI delete mode 160000 OpenSteamClient.Logging diff --git a/OpenSteamClient.DI b/OpenSteamClient.DI deleted file mode 160000 index 3579bcbb..00000000 --- a/OpenSteamClient.DI +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3579bcbb31dae4104ef461f7ede0ec7389f880b4 diff --git a/OpenSteamClient.Logging b/OpenSteamClient.Logging deleted file mode 160000 index dbe5251d..00000000 --- a/OpenSteamClient.Logging +++ /dev/null @@ -1 +0,0 @@ -Subproject commit dbe5251dc93116addc17157e8c17012b99dbc877 diff --git a/OpenSteamClient.sln b/OpenSteamClient.sln index 09defe1a..3037aba8 100644 --- a/OpenSteamClient.sln +++ b/OpenSteamClient.sln @@ -1,103 +1,91 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSteamClient", "OpenSteamClient\OpenSteamClient.csproj", "{F99A1010-054A-41B8-88E3-830E0BBB66EF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSteamworks.Client", "OpenSteamworks.Client\OpenSteamworks.Client.csproj", "{FFA4DBFB-4F66-4EBF-9A84-4F19A7ADAF95}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Installer", "Installer\Installer.csproj", "{0DF0A8CB-BEA8-4809-9532-FA084BE99407}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvaloniaCommon", "AvaloniaCommon\AvaloniaCommon.csproj", "{DCB34015-EED4-4ACA-9620-734CFB74A943}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameOverlayUI", "GameOverlayUI\GameOverlayUI.csproj", "{BC50FC00-E846-4A2A-B759-98C39B238F7A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameOverlayDebugTarget", "GameOverlayDebugTarget\GameOverlayDebugTarget.csproj", "{B12E4BB3-1FA6-46F7-9C81-200C17F784CC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSteamClient.DI", "OpenSteamClient.DI\OpenSteamClient.DI.csproj", "{2A739B1E-2DAF-48CC-8D09-EEC6D1987767}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSteamClient.Logging", "OpenSteamClient.Logging\OpenSteamClient.Logging.csproj", "{C0D40FB8-F674-4C98-990C-960DA323CB38}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChromeTestClient", "ChromeTestClient\ChromeTestClient.csproj", "{B1019060-FAA1-43C2-BA41-2044114DE39C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSteamworks", "..\OpenSteamworks\OpenSteamworks\OpenSteamworks.csproj", "{12E82CE5-AA43-4E0E-A90A-3A5025E88147}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSteamworks.Messaging.SharedConnection", "..\OpenSteamworks\OpenSteamworks.Messaging.SharedConnection\OpenSteamworks.Messaging.SharedConnection.csproj", "{369B9BC0-CD93-49B7-AEE9-A1396A051B8A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSteamworks.Messaging", "..\OpenSteamworks\OpenSteamworks.Messaging\OpenSteamworks.Messaging.csproj", "{7F9F15AB-C758-4811-9206-AFA35838601E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSteamworks.Data", "..\OpenSteamworks\OpenSteamworks.Data\OpenSteamworks.Data.csproj", "{96C74E02-6F7B-49AE-AAE0-8DE0A9BCE580}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CppSourceGen.Generator", "..\OpenSteamworks\CppSourceGen.Generator\CppSourceGen.Generator.csproj", "{C26A136F-2C8F-4080-A860-B1DA04837D30}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F99A1010-054A-41B8-88E3-830E0BBB66EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F99A1010-054A-41B8-88E3-830E0BBB66EF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F99A1010-054A-41B8-88E3-830E0BBB66EF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F99A1010-054A-41B8-88E3-830E0BBB66EF}.Release|Any CPU.Build.0 = Release|Any CPU - {FFA4DBFB-4F66-4EBF-9A84-4F19A7ADAF95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FFA4DBFB-4F66-4EBF-9A84-4F19A7ADAF95}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FFA4DBFB-4F66-4EBF-9A84-4F19A7ADAF95}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FFA4DBFB-4F66-4EBF-9A84-4F19A7ADAF95}.Release|Any CPU.Build.0 = Release|Any CPU - {0DF0A8CB-BEA8-4809-9532-FA084BE99407}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0DF0A8CB-BEA8-4809-9532-FA084BE99407}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0DF0A8CB-BEA8-4809-9532-FA084BE99407}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0DF0A8CB-BEA8-4809-9532-FA084BE99407}.Release|Any CPU.Build.0 = Release|Any CPU - {DCB34015-EED4-4ACA-9620-734CFB74A943}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DCB34015-EED4-4ACA-9620-734CFB74A943}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DCB34015-EED4-4ACA-9620-734CFB74A943}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DCB34015-EED4-4ACA-9620-734CFB74A943}.Release|Any CPU.Build.0 = Release|Any CPU - {BC50FC00-E846-4A2A-B759-98C39B238F7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BC50FC00-E846-4A2A-B759-98C39B238F7A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BC50FC00-E846-4A2A-B759-98C39B238F7A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BC50FC00-E846-4A2A-B759-98C39B238F7A}.Release|Any CPU.Build.0 = Release|Any CPU - {B12E4BB3-1FA6-46F7-9C81-200C17F784CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B12E4BB3-1FA6-46F7-9C81-200C17F784CC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B12E4BB3-1FA6-46F7-9C81-200C17F784CC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B12E4BB3-1FA6-46F7-9C81-200C17F784CC}.Release|Any CPU.Build.0 = Release|Any CPU - {2A739B1E-2DAF-48CC-8D09-EEC6D1987767}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2A739B1E-2DAF-48CC-8D09-EEC6D1987767}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2A739B1E-2DAF-48CC-8D09-EEC6D1987767}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2A739B1E-2DAF-48CC-8D09-EEC6D1987767}.Release|Any CPU.Build.0 = Release|Any CPU - {C0D40FB8-F674-4C98-990C-960DA323CB38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C0D40FB8-F674-4C98-990C-960DA323CB38}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C0D40FB8-F674-4C98-990C-960DA323CB38}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C0D40FB8-F674-4C98-990C-960DA323CB38}.Release|Any CPU.Build.0 = Release|Any CPU - {B1019060-FAA1-43C2-BA41-2044114DE39C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B1019060-FAA1-43C2-BA41-2044114DE39C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B1019060-FAA1-43C2-BA41-2044114DE39C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B1019060-FAA1-43C2-BA41-2044114DE39C}.Release|Any CPU.Build.0 = Release|Any CPU - {12E82CE5-AA43-4E0E-A90A-3A5025E88147}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {12E82CE5-AA43-4E0E-A90A-3A5025E88147}.Debug|Any CPU.Build.0 = Debug|Any CPU - {12E82CE5-AA43-4E0E-A90A-3A5025E88147}.Release|Any CPU.ActiveCfg = Release|Any CPU - {12E82CE5-AA43-4E0E-A90A-3A5025E88147}.Release|Any CPU.Build.0 = Release|Any CPU - {369B9BC0-CD93-49B7-AEE9-A1396A051B8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {369B9BC0-CD93-49B7-AEE9-A1396A051B8A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {369B9BC0-CD93-49B7-AEE9-A1396A051B8A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {369B9BC0-CD93-49B7-AEE9-A1396A051B8A}.Release|Any CPU.Build.0 = Release|Any CPU - {7F9F15AB-C758-4811-9206-AFA35838601E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7F9F15AB-C758-4811-9206-AFA35838601E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7F9F15AB-C758-4811-9206-AFA35838601E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7F9F15AB-C758-4811-9206-AFA35838601E}.Release|Any CPU.Build.0 = Release|Any CPU - {96C74E02-6F7B-49AE-AAE0-8DE0A9BCE580}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {96C74E02-6F7B-49AE-AAE0-8DE0A9BCE580}.Debug|Any CPU.Build.0 = Debug|Any CPU - {96C74E02-6F7B-49AE-AAE0-8DE0A9BCE580}.Release|Any CPU.ActiveCfg = Release|Any CPU - {96C74E02-6F7B-49AE-AAE0-8DE0A9BCE580}.Release|Any CPU.Build.0 = Release|Any CPU - {C26A136F-2C8F-4080-A860-B1DA04837D30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C26A136F-2C8F-4080-A860-B1DA04837D30}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C26A136F-2C8F-4080-A860-B1DA04837D30}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C26A136F-2C8F-4080-A860-B1DA04837D30}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {97A11C5F-5A2B-43EB-BAEB-68F08E1C5080} = {28FC9377-6212-4732-82EC-D29D3239095F} - {6F856C94-1184-4720-8D7C-2157051B9A2D} = {28FC9377-6212-4732-82EC-D29D3239095F} - EndGlobalSection -EndGlobal +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSteamClient", "OpenSteamClient\OpenSteamClient.csproj", "{F99A1010-054A-41B8-88E3-830E0BBB66EF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSteamworks.Client", "OpenSteamworks.Client\OpenSteamworks.Client.csproj", "{FFA4DBFB-4F66-4EBF-9A84-4F19A7ADAF95}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Installer", "Installer\Installer.csproj", "{0DF0A8CB-BEA8-4809-9532-FA084BE99407}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvaloniaCommon", "AvaloniaCommon\AvaloniaCommon.csproj", "{DCB34015-EED4-4ACA-9620-734CFB74A943}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameOverlayUI", "GameOverlayUI\GameOverlayUI.csproj", "{BC50FC00-E846-4A2A-B759-98C39B238F7A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameOverlayDebugTarget", "GameOverlayDebugTarget\GameOverlayDebugTarget.csproj", "{B12E4BB3-1FA6-46F7-9C81-200C17F784CC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChromeTestClient", "ChromeTestClient\ChromeTestClient.csproj", "{B1019060-FAA1-43C2-BA41-2044114DE39C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSteamworks", "..\OpenSteamworks\OpenSteamworks\OpenSteamworks.csproj", "{12E82CE5-AA43-4E0E-A90A-3A5025E88147}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSteamworks.Messaging.SharedConnection", "..\OpenSteamworks\OpenSteamworks.Messaging.SharedConnection\OpenSteamworks.Messaging.SharedConnection.csproj", "{369B9BC0-CD93-49B7-AEE9-A1396A051B8A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSteamworks.Messaging", "..\OpenSteamworks\OpenSteamworks.Messaging\OpenSteamworks.Messaging.csproj", "{7F9F15AB-C758-4811-9206-AFA35838601E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSteamworks.Data", "..\OpenSteamworks\OpenSteamworks.Data\OpenSteamworks.Data.csproj", "{96C74E02-6F7B-49AE-AAE0-8DE0A9BCE580}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CppSourceGen.Generator", "..\OpenSteamworks\CppSourceGen.Generator\CppSourceGen.Generator.csproj", "{C26A136F-2C8F-4080-A860-B1DA04837D30}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F99A1010-054A-41B8-88E3-830E0BBB66EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F99A1010-054A-41B8-88E3-830E0BBB66EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F99A1010-054A-41B8-88E3-830E0BBB66EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F99A1010-054A-41B8-88E3-830E0BBB66EF}.Release|Any CPU.Build.0 = Release|Any CPU + {FFA4DBFB-4F66-4EBF-9A84-4F19A7ADAF95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FFA4DBFB-4F66-4EBF-9A84-4F19A7ADAF95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FFA4DBFB-4F66-4EBF-9A84-4F19A7ADAF95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FFA4DBFB-4F66-4EBF-9A84-4F19A7ADAF95}.Release|Any CPU.Build.0 = Release|Any CPU + {0DF0A8CB-BEA8-4809-9532-FA084BE99407}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0DF0A8CB-BEA8-4809-9532-FA084BE99407}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0DF0A8CB-BEA8-4809-9532-FA084BE99407}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0DF0A8CB-BEA8-4809-9532-FA084BE99407}.Release|Any CPU.Build.0 = Release|Any CPU + {DCB34015-EED4-4ACA-9620-734CFB74A943}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DCB34015-EED4-4ACA-9620-734CFB74A943}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DCB34015-EED4-4ACA-9620-734CFB74A943}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DCB34015-EED4-4ACA-9620-734CFB74A943}.Release|Any CPU.Build.0 = Release|Any CPU + {BC50FC00-E846-4A2A-B759-98C39B238F7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BC50FC00-E846-4A2A-B759-98C39B238F7A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BC50FC00-E846-4A2A-B759-98C39B238F7A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BC50FC00-E846-4A2A-B759-98C39B238F7A}.Release|Any CPU.Build.0 = Release|Any CPU + {B12E4BB3-1FA6-46F7-9C81-200C17F784CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B12E4BB3-1FA6-46F7-9C81-200C17F784CC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B12E4BB3-1FA6-46F7-9C81-200C17F784CC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B12E4BB3-1FA6-46F7-9C81-200C17F784CC}.Release|Any CPU.Build.0 = Release|Any CPU + {B1019060-FAA1-43C2-BA41-2044114DE39C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B1019060-FAA1-43C2-BA41-2044114DE39C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B1019060-FAA1-43C2-BA41-2044114DE39C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B1019060-FAA1-43C2-BA41-2044114DE39C}.Release|Any CPU.Build.0 = Release|Any CPU + {12E82CE5-AA43-4E0E-A90A-3A5025E88147}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {12E82CE5-AA43-4E0E-A90A-3A5025E88147}.Debug|Any CPU.Build.0 = Debug|Any CPU + {12E82CE5-AA43-4E0E-A90A-3A5025E88147}.Release|Any CPU.ActiveCfg = Release|Any CPU + {12E82CE5-AA43-4E0E-A90A-3A5025E88147}.Release|Any CPU.Build.0 = Release|Any CPU + {369B9BC0-CD93-49B7-AEE9-A1396A051B8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {369B9BC0-CD93-49B7-AEE9-A1396A051B8A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {369B9BC0-CD93-49B7-AEE9-A1396A051B8A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {369B9BC0-CD93-49B7-AEE9-A1396A051B8A}.Release|Any CPU.Build.0 = Release|Any CPU + {7F9F15AB-C758-4811-9206-AFA35838601E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F9F15AB-C758-4811-9206-AFA35838601E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F9F15AB-C758-4811-9206-AFA35838601E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7F9F15AB-C758-4811-9206-AFA35838601E}.Release|Any CPU.Build.0 = Release|Any CPU + {96C74E02-6F7B-49AE-AAE0-8DE0A9BCE580}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96C74E02-6F7B-49AE-AAE0-8DE0A9BCE580}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96C74E02-6F7B-49AE-AAE0-8DE0A9BCE580}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96C74E02-6F7B-49AE-AAE0-8DE0A9BCE580}.Release|Any CPU.Build.0 = Release|Any CPU + {C26A136F-2C8F-4080-A860-B1DA04837D30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C26A136F-2C8F-4080-A860-B1DA04837D30}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C26A136F-2C8F-4080-A860-B1DA04837D30}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C26A136F-2C8F-4080-A860-B1DA04837D30}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {97A11C5F-5A2B-43EB-BAEB-68F08E1C5080} = {28FC9377-6212-4732-82EC-D29D3239095F} + {6F856C94-1184-4720-8D7C-2157051B9A2D} = {28FC9377-6212-4732-82EC-D29D3239095F} + EndGlobalSection +EndGlobal diff --git a/SteamFlow/README.md b/SteamFlow/README.md index 665a535a..44c13502 100644 --- a/SteamFlow/README.md +++ b/SteamFlow/README.md @@ -30,6 +30,8 @@ Guard data is persisted through `FileGuardDataStore::user_cache()` so repeated S - **Steam Cloud Sync**: Automatic sync-down before launch and sync-up after game exit (if enabled in settings). ## GUI +- Context menu `Advanced > Depot Browser` opens a browser for app depots and manifest file trees. +- Per-file depot download support from the Depot Browser window. - Integrated authentication panel (account/password + optional Steam Guard code). - Confirmation-type specific Steam Guard hints: email/device code vs mobile approval flow. - Validation messaging when a code is required but missing. @@ -50,6 +52,8 @@ cargo run --manifest-path SteamFlow/Cargo.toml ``` ## Install/download pipeline +- Install target now uses `/steamapps/common/` instead of temp paths. +- App manifests are now written to `/steamapps/appmanifest_.acf` after installs complete so local scan works after restart. - Implemented a four-phase pipeline in `src/download_pipeline.rs`: 1. **Get Manifest ID**: PICS product info request + VDF parsing to find the correct depot and manifest GID for the target platform. 2. **Get Security Info**: Request depot decryption keys + CDN server list and auth tokens. diff --git a/SteamFlow/ROADMAP.md b/SteamFlow/ROADMAP.md index 9c6f6f20..5298cd31 100644 --- a/SteamFlow/ROADMAP.md +++ b/SteamFlow/ROADMAP.md @@ -23,3 +23,6 @@ 7. [x] Add settings view for Proton runtime and Steam library path discovery. 8. Extend CI to publish signed .deb artifacts from tags. 9. [x] Implement Steam Cloud Sync (Enumerate/Download/Upload). + +10. [x] Add Depot Browser developer tooling (depot list, manifest tree, single-file download). +11. [x] Harden library scanning fallback and appmanifest parse diagnostics. diff --git a/SteamFlow/src/library.rs b/SteamFlow/src/library.rs index de1f01ad..98c12856 100644 --- a/SteamFlow/src/library.rs +++ b/SteamFlow/src/library.rs @@ -56,18 +56,34 @@ pub async fn find_local_games() -> Result> { } pub async fn scan_installed_app_paths() -> Result> { - let root_path = if let Ok(cfg) = load_launcher_config().await { - PathBuf::from(cfg.steam_library_path) + let path_map = scan_installed_app_paths_pathbuf().await?; + Ok(path_map + .into_iter() + .map(|(appid, path)| (appid, path.to_string_lossy().to_string())) + .collect()) +} + +pub async fn scan_installed_app_paths_pathbuf() -> Result> { + let config_path = if let Ok(cfg) = load_launcher_config().await { + let p = PathBuf::from(cfg.steam_library_path); + if p.join("steamapps").exists() || p.join("Steam").join("steamapps").exists() { + Some(p) + } else { + None + } } else { - detect_steam_path().unwrap_or_else(default_steam_root) + None }; - scan_library(root_path).await + let root = config_path + .unwrap_or_else(|| detect_steam_path().unwrap_or_else(|| PathBuf::from("~/.steam/steam"))); + println!("Scanning Library Root: {:?}", root); + scan_library(&root).await } -pub async fn scan_library(root_path: PathBuf) -> Result> { +pub async fn scan_library(root_path: &Path) -> Result> { let mut installed = HashMap::new(); - let mut libraries = vec![root_path.clone()]; + let mut libraries = vec![root_path.to_path_buf()]; let library_folders_path = root_path.join("steamapps").join("libraryfolders.vdf"); let extra_libraries = parse_library_folders(library_folders_path).await?; @@ -93,7 +109,7 @@ pub async fn scan_library(root_path: PathBuf) -> Result> { } if let Some((app_id, install_dir)) = parse_app_manifest_install_path(&path).await? { - installed.insert(app_id, install_dir.to_string_lossy().to_string()); + installed.insert(app_id, install_dir); } } } @@ -177,7 +193,10 @@ async fn parse_app_manifest_install_path(path: &Path) -> Result() { Ok(v) => v, - Err(_) => return Ok(None), + Err(e) => { + println!("WARNING: Failed to parse appid from {:?}: {}", path, e); + return Ok(None); + } }; let install_dir = path diff --git a/SteamFlow/src/steam_client.rs b/SteamFlow/src/steam_client.rs index 84f6a5bb..43e1bb8f 100644 --- a/SteamFlow/src/steam_client.rs +++ b/SteamFlow/src/steam_client.rs @@ -303,14 +303,19 @@ impl SteamClient { .cloned() .context("steam connection not initialized")?; - let install_dir = - if let Ok(cfg) = tokio::runtime::Handle::current().block_on(load_launcher_config()) { - PathBuf::from(cfg.steam_library_path).join(appid.to_string()) - } else { - std::env::temp_dir() - .join("steamflow_downloads") - .join(appid.to_string()) - }; + let cfg = tokio::runtime::Handle::current().block_on(load_launcher_config())?; + let library_root = cfg.steam_library_path.clone(); + let game_name = self.resolve_install_game_name(appid); + let install_dir = Path::new(&library_root) + .join("steamapps") + .join("common") + .join(&game_name); + std::fs::create_dir_all(&install_dir) + .with_context(|| format!("failed creating {}", install_dir.display()))?; + let manifest_path = Path::new(&library_root) + .join("steamapps") + .join(format!("appmanifest_{appid}.acf")); + let (tx, rx) = tokio::sync::mpsc::channel(128); tokio::task::spawn(async move { @@ -347,6 +352,11 @@ impl SteamClient { match result { Ok(Ok(())) => { + if let Err(err) = + SteamClient::write_basic_appmanifest(&manifest_path, appid, &game_name) + { + tracing::warn!("failed writing appmanifest for {}: {}", appid, err); + } let _ = tx .send(DownloadProgress { state: DownloadProgressState::Completed, @@ -870,6 +880,8 @@ impl SteamClient { .block_on(load_launcher_config())? .steam_library_path, ) + .join("steamapps") + .join("common") .join(appid.to_string())) } @@ -912,6 +924,37 @@ impl SteamClient { Ok(()) } + fn resolve_install_game_name(&self, appid: u32) -> String { + tokio::runtime::Handle::current() + .block_on(load_library_cache()) + .ok() + .and_then(|games| { + games + .into_iter() + .find(|g| g.app_id == appid) + .map(|g| g.name) + }) + .filter(|name| !name.trim().is_empty()) + .unwrap_or_else(|| format!("App {appid}")) + } + + fn write_basic_appmanifest(path: &Path, appid: u32, game_name: &str) -> Result<()> { + if let Some(parent) = path.parent() { + std::fs::create_dir_all(parent) + .with_context(|| format!("failed creating {}", parent.display()))?; + } + + let installdir = sanitize_install_dir(game_name); + let game_name = game_name.replace('"', ""); + let content = format!( + "\"AppState\"\n{{\n\t\"appid\"\t\"{appid}\"\n\t\"name\"\t\"{game_name}\"\n\t\"StateFlags\"\t\"4\"\n\t\"installdir\"\t\"{installdir}\"\n}}\n" + ); + + std::fs::write(path, content) + .with_context(|| format!("failed writing {}", path.display()))?; + Ok(()) + } + fn spawn_game_process( &self, app: &LibraryGame, @@ -976,6 +1019,17 @@ impl SteamClient { } } +fn sanitize_install_dir(name: &str) -> String { + let sanitized: String = name + .chars() + .map(|c| match c { + '/' | '\\' | ':' | '*' | '?' | '"' | '<' | '>' | '|' => '_', + _ => c, + }) + .collect(); + sanitized.trim().to_string() +} + fn map_confirmation(method: &ConfirmationMethod) -> ConfirmationPrompt { let details = method.confirmation_details().to_string(); let requirement = match method.confirmation_type() {