diff --git a/src/client/component/steam_proxy.cpp b/src/client/component/steam_proxy.cpp index 85dc8aca..194cb735 100644 --- a/src/client/component/steam_proxy.cpp +++ b/src/client/component/steam_proxy.cpp @@ -7,8 +7,6 @@ #include #include -#include "game/utils.hpp" - #include "steam/interface.hpp" #include "steam/steam.hpp" @@ -22,8 +20,8 @@ namespace steam_proxy utils::nt::library steam_client_module{}; utils::nt::library steam_overlay_module{}; - void* steam_pipe = nullptr; - void* global_user = nullptr; + steam::HSteamPipe steam_pipe = 0; + steam::HSteamUser global_user = 0; steam::interface client_engine{}; steam::interface client_user{}; @@ -31,6 +29,9 @@ namespace steam_proxy steam::interface client_friends{}; steam::interface client_ugc{}; + steam::client* steam_client{}; + steam::ugc* steam_ugc{}; + utils::concurrency::container subscribed_items; enum class ownership_state @@ -64,6 +65,8 @@ namespace steam_proxy void load_client() { + SetEnvironmentVariableA("SteamAppId", std::to_string(steam::SteamUtils()->GetAppID()).data()); + const std::filesystem::path steam_path = steam::SteamAPI_GetSteamInstallPath(); if (steam_path.empty()) return; @@ -76,8 +79,8 @@ namespace steam_proxy client_engine = load_client_engine(); if (!client_engine) return; - steam_pipe = steam_client_module.invoke("Steam_CreateSteamPipe"); - global_user = steam_client_module.invoke( + steam_pipe = steam_client_module.invoke("Steam_CreateSteamPipe"); + global_user = steam_client_module.invoke( "Steam_ConnectToGlobalUser", steam_pipe); client_user = client_engine.invoke(8, global_user, steam_pipe); @@ -94,19 +97,21 @@ namespace steam_proxy client_friends = nullptr; client_ugc = nullptr; - steam_pipe = nullptr; - global_user = nullptr; + steam_pipe = 0; + global_user = 0; - steam_client_module = utils::nt::library{nullptr}; + steam_client = nullptr; + steam_ugc = nullptr; } bool perform_cleanup_if_needed() { + if (steam_client) return true; + if (steam_client_module && steam_pipe && global_user - && steam_client_module.invoke("Steam_BConnected", global_user, - steam_pipe) + && steam_client_module.invoke("Steam_BConnected", global_user, steam_pipe) && steam_client_module.invoke("Steam_BLoggedOn", global_user, steam_pipe) ) { @@ -224,7 +229,16 @@ namespace steam_proxy void pre_destroy() override { - if (steam_client_module && steam_pipe) + if (steam_client) + { + if (global_user) + { + steam_client->ReleaseUser(steam_pipe, global_user); + } + + steam_client->BReleaseSteamPipe(steam_pipe); + } + else if (steam_client_module && steam_pipe) { if (global_user) { @@ -232,7 +246,7 @@ namespace steam_proxy global_user); } - steam_client_module.invoke("Steam_BReleaseSteamPipe", steam_pipe); + (void)steam_client_module.invoke("Steam_BReleaseSteamPipe", steam_pipe); } } @@ -257,6 +271,87 @@ namespace steam_proxy return ""; } + void initialize() + { + if (client_engine || !steam_client_module) return; + + steam_client = steam_client_module.invoke("CreateInterface", "SteamClient017", nullptr); + if (!steam_client) return; + + steam_pipe = steam_client->CreateSteamPipe(); + global_user = steam_client->ConnectToGlobalUser(steam_pipe); + } + + void create_ugc() + { + if (!steam_client) return; + + auto* ugc = steam_client->GetISteamUGC(global_user, steam_pipe, "STEAMUGC_INTERFACE_VERSION008"); + steam_ugc = static_cast(ugc); + } + + void update_map_client(subscribed_item_map& map) + { + const auto app_id = steam::SteamUtils()->GetAppID(); + const auto num_items = client_ugc.invoke("GetNumSubscribedItems", app_id); + + if (!num_items) + { + return; + } + + std::vector ids; + ids.resize(num_items); + + auto result = client_ugc.invoke("GetSubscribedItems", app_id, ids.data(), + num_items); + result = std::min(num_items, result); + + for (uint32_t i = 0; i < result; ++i) + { + char buffer[0x1000] = {0}; + subscribed_item item{}; + + item.state = client_ugc.invoke("GetItemState", app_id, ids[i]); + item.available = client_ugc.invoke("GetItemInstallInfo", app_id, ids[i], + &item.size_on_disk, + buffer, + sizeof(buffer), &item.time_stamp); + item.path = buffer; + + map[ids[i]] = std::move(item); + } + } + + void update_map_steam(subscribed_item_map& map) + { + const auto num_items = steam_ugc->GetNumSubscribedItems(); + + if (!num_items) + { + return; + } + + std::vector ids; + ids.resize(num_items); + + auto result = steam_ugc->GetSubscribedItems(ids.data(), num_items); + result = std::min(num_items, result); + + for (uint32_t i = 0; i < result; ++i) + { + char buffer[0x1000] = {0}; + subscribed_item item{}; + + item.state = steam_ugc->GetItemState(ids[i]); + item.available = steam_ugc->GetItemInstallInfo(ids[i], &item.size_on_disk, buffer, sizeof(buffer), + &item.time_stamp); + item.path = buffer; + + map[ids[i]] = std::move(item); + } + } + void update_subscribed_items() { subscribed_item_map map{}; @@ -269,41 +364,15 @@ namespace steam_proxy }); }); - if (!client_ugc) - { - return; - } - try { - const auto app_id = steam::SteamUtils()->GetAppID(); - const auto num_items = client_ugc.invoke("GetNumSubscribedItems", app_id); - - if (!num_items) + if (client_ugc) { - return; + update_map_client(map); } - - std::vector ids; - ids.resize(num_items); - - auto result = client_ugc.invoke("GetSubscribedItems", app_id, ids.data(), - num_items); - result = std::min(num_items, result); - - for (uint32_t i = 0; i < result; ++i) + else if (steam_ugc) { - char buffer[0x1000] = {0}; - subscribed_item item{}; - - item.state = client_ugc.invoke("GetItemState", app_id, ids[i]); - item.available = client_ugc.invoke("GetItemInstallInfo", app_id, ids[i], - &item.size_on_disk, - buffer, - sizeof(buffer), &item.time_stamp); - item.path = buffer; - - map[ids[i]] = std::move(item); + update_map_steam(map); } } catch (...) diff --git a/src/client/component/steam_proxy.hpp b/src/client/component/steam_proxy.hpp index fb1a3f63..4c117bac 100644 --- a/src/client/component/steam_proxy.hpp +++ b/src/client/component/steam_proxy.hpp @@ -18,6 +18,9 @@ namespace steam_proxy using subscribed_item_map = std::unordered_map; + void initialize(); + void create_ugc(); + void update_subscribed_items(); void access_subscribed_items(const std::function& callback); } diff --git a/src/client/steam/interfaces/client.cpp b/src/client/steam/interfaces/client.cpp index 9ea1419a..282fba1a 100644 --- a/src/client/steam/interfaces/client.cpp +++ b/src/client/steam/interfaces/client.cpp @@ -1,5 +1,6 @@ #include #include "../steam.hpp" +#include "../../component/steam_proxy.hpp" namespace steam { @@ -225,6 +226,13 @@ namespace steam void* client::GetISteamUGC(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion) { + static auto x = [] + { + steam_proxy::create_ugc(); + return 0; + }(); + (void)x; + static ugc u; return &u; } diff --git a/src/client/steam/steam.cpp b/src/client/steam/steam.cpp index 135aa348..1777ec2c 100644 --- a/src/client/steam/steam.cpp +++ b/src/client/steam/steam.cpp @@ -4,7 +4,7 @@ #include #include -#include "loader/component_loader.hpp" +#include "../component/steam_proxy.hpp" namespace steam { @@ -118,6 +118,9 @@ namespace steam ::utils::nt::library::load(steam_path / "vstdlib_s64.dll"); ::utils::nt::library::load(steam_path / "gameoverlayrenderer64.dll"); ::utils::nt::library::load(steam_path / "steamclient64.dll"); + + steam_proxy::initialize(); + return true; }