#include "STDInclude.hpp" namespace Steam { ::Utils::Library Proxy::Client; ::Utils::Library Proxy::Overlay; ISteamClient008* Proxy::SteamClient = nullptr; IClientEngine* Proxy::ClientEngine = nullptr; IClientUser* Proxy::ClientUser = nullptr; void* Proxy::SteamPipe = nullptr; void* Proxy::SteamUser = nullptr; Friends15* Proxy::SteamFriends = nullptr; Friends2* Proxy::SteamLegacyFriends = nullptr; Utils* Proxy::SteamUtils = nullptr; uint32_t Proxy::AppId = 0; std::recursive_mutex Proxy::CallMutex; std::vector Proxy::Calls; std::unordered_map Proxy::Callbacks; std::function Proxy::SteamBGetCallback; std::function Proxy::SteamFreeLastCallback; std::function Proxy::SteamGetAPICallResult; void Proxy::SetGame(uint32_t appId) { Proxy::AppId = appId; // if (!Components::Flags::HasFlag("nosteam")) // { // SetEnvironmentVariableA("SteamAppId", ::Utils::String::VA("%lu", appId)); // SetEnvironmentVariableA("SteamGameId", ::Utils::String::VA("%llu", appId & 0xFFFFFF)); // // ::Utils::IO::WriteFile("steam_appid.txt", ::Utils::String::VA("%lu", appId), false); // } remove("steam_appid.txt"); } void Proxy::RegisterCall(int32_t callId, uint32_t size, uint64_t call) { std::lock_guard _(Proxy::CallMutex); Proxy::CallContainer contianer; contianer.call = call; contianer.dataSize = size; contianer.callId = callId; contianer.handled = false; Proxy::Calls.push_back(contianer); } void Proxy::UnregisterCalls() { std::lock_guard _(Proxy::CallMutex); for(auto i = Proxy::Calls.begin(); i != Proxy::Calls.end(); ++i) { if(i->handled) { i = Proxy::Calls.erase(i); } else { ++i; } } } void Proxy::RegisterCallback(int32_t callId, void* callback) { std::lock_guard _(Proxy::CallMutex); Proxy::Callbacks[callId] = callback; } void Proxy::UnregisterCallback(int32_t callId) { std::lock_guard _(Proxy::CallMutex); Proxy::Callbacks.erase(callId); } void Proxy::RunCallback(int32_t callId, void* data, size_t /*size*/) { std::lock_guard _(Proxy::CallMutex); auto callback = Proxy::Callbacks.find(callId); if (callback != Proxy::Callbacks.end()) { ::Utils::Hook::Call(callback->second)(data); } } void Proxy::RunFrame() { std::lock_guard _(Proxy::CallMutex); if (Proxy::SteamUtils) { Proxy::SteamUtils->RunFrame(); } Proxy::CallbackMsg message; while (Proxy::SteamBGetCallback && Proxy::SteamFreeLastCallback && Proxy::SteamBGetCallback(Proxy::SteamPipe, &message)) { #ifdef DEBUG printf("Callback dispatched: %d\n", message.m_iCallback); #endif Steam::Callbacks::RunCallback(message.m_iCallback, message.m_pubParam); Proxy::RunCallback(message.m_iCallback, message.m_pubParam, message.m_cubParam); Proxy::SteamFreeLastCallback(Proxy::SteamPipe); } if (Proxy::SteamUtils) { for (auto &call : Proxy::Calls) { bool failed = false; if (Proxy::SteamUtils->IsAPICallCompleted(call.call, &failed)) { ::Utils::Memory::Allocator allocator; #ifdef DEBUG printf("Handling call: %d\n", call.callId); #endif call.handled = true; if (failed) { #ifdef DEBUG auto error = Proxy::SteamUtils->GetAPICallFailureReason(call.call); printf("API call failed: %X Handle: %llX\n", error, call.call); #endif continue; } char* buffer = allocator.allocateArray(call.dataSize); Proxy::SteamUtils->GetAPICallResult(call.call, buffer, call.dataSize, call.callId, &failed); if (failed) { #ifdef DEBUG auto error = Proxy::SteamUtils->GetAPICallFailureReason(call.call); printf("GetAPICallResult failed: %X Handle: %llX\n", error, call.call); #endif continue; } Proxy::RunCallback(call.callId, buffer, call.dataSize); } } } Proxy::UnregisterCalls(); } bool Proxy::Inititalize() { std::string directoy = Proxy::GetSteamDirectory(); if (directoy.empty()) return false; SetDllDirectoryA(Proxy::GetSteamDirectory().data()); if (!Components::Dedicated::IsEnabled() || !Components::ZoneBuilder::IsEnabled()) { Proxy::Overlay = ::Utils::Library(GAMEOVERLAY_LIB, false); if (!Proxy::Overlay.valid()) return false; } Proxy::Client = ::Utils::Library(STEAMCLIENT_LIB, false); if (!Proxy::Client.valid()) return false; Proxy::SteamClient = Proxy::Client.get("CreateInterface")("SteamClient008", nullptr); if(!Proxy::SteamClient) return false; Proxy::SteamBGetCallback = Proxy::Client.get("Steam_BGetCallback"); if (!Proxy::SteamBGetCallback) return false; Proxy::SteamFreeLastCallback = Proxy::Client.get("Steam_FreeLastCallback"); if (!Proxy::SteamFreeLastCallback) return false; Proxy::SteamGetAPICallResult = Proxy::Client.get("Steam_GetAPICallResult"); if (!Proxy::SteamGetAPICallResult) return false; Proxy::SteamClient = Proxy::Client.get("CreateInterface")("SteamClient008", nullptr); if (!Proxy::SteamClient) return false; Proxy::SteamPipe = Proxy::SteamClient->CreateSteamPipe(); if (!Proxy::SteamPipe) return false; Proxy::SteamUser = Proxy::SteamClient->ConnectToGlobalUser(Proxy::SteamPipe); if (!Proxy::SteamUser) return false; Proxy::ClientEngine = Proxy::Client.get("CreateInterface")("CLIENTENGINE_INTERFACE_VERSION004", nullptr); if (!Proxy::ClientEngine) return false; Proxy::ClientUser = Proxy::ClientEngine->GetIClientUser(Proxy::SteamUser, Proxy::SteamPipe, "CLIENTUSER_INTERFACE_VERSION001"); if (!Proxy::ClientUser) return false; Proxy::SteamFriends = reinterpret_cast(Proxy::SteamClient->GetISteamFriends(Proxy::SteamUser, Proxy::SteamPipe, "SteamFriends015")); if (!Proxy::SteamFriends) return false; Proxy::SteamLegacyFriends = reinterpret_cast(Proxy::SteamClient->GetISteamFriends(Proxy::SteamUser, Proxy::SteamPipe, "SteamFriends002")); if (!Proxy::SteamLegacyFriends) return false; Proxy::SteamUtils = reinterpret_cast(Proxy::SteamClient->GetISteamFriends(Proxy::SteamUser, Proxy::SteamPipe, "SteamUtils005")); if (!Proxy::SteamUtils) return false; return true; } void Proxy::Uninititalize() { if (Proxy::SteamClient && Proxy::SteamPipe) { if (Proxy::SteamUser) { //Proxy::SteamClient->ReleaseUser(Proxy::SteamPipe, Proxy::SteamUser); } //Proxy::SteamClient->ReleaseSteamPipe(Proxy::SteamPipe); } Proxy::Client = ::Utils::Library(); Proxy::Overlay = ::Utils::Library(); } std::string Proxy::GetSteamDirectory() { HKEY hRegKey; char SteamPath[MAX_PATH]; if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, STEAM_REGISTRY_PATH, 0, KEY_QUERY_VALUE, &hRegKey) == ERROR_SUCCESS) { DWORD dwLength = sizeof(SteamPath); RegQueryValueExA(hRegKey, "InstallPath", nullptr, nullptr, reinterpret_cast(SteamPath), &dwLength); RegCloseKey(hRegKey); return SteamPath; } return ""; } void Proxy::SetOverlayNotificationPosition(uint32_t eNotificationPosition) { if (Proxy::Overlay.valid()) { Proxy::Overlay.get("SetNotificationPosition")(eNotificationPosition); } } bool Proxy::IsOverlayEnabled() { if (Proxy::Overlay.valid()) { return Proxy::Overlay.get("IsOverlayEnabled")(); } return false; } bool Proxy::BOverlayNeedsPresent() { if (Proxy::Overlay.valid()) { return Proxy::Overlay.get("BOverlayNeedsPresent")(); } return false; } }