mirror of
https://github.com/acidicoala/SmokeAPI.git
synced 2025-12-05 21:15:39 -05:00
Reworked logging
This commit is contained in:
@@ -10,4 +10,7 @@ IndentWidth: 4
|
|||||||
ContinuationIndentWidth: 4
|
ContinuationIndentWidth: 4
|
||||||
NamespaceIndentation: All
|
NamespaceIndentation: All
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
PointerAlignment: Left
|
PointerAlignment: Left
|
||||||
|
SortIncludes: true
|
||||||
|
AllowShortFunctionsOnASingleLine: Empty
|
||||||
|
FixNamespaceComments: false
|
||||||
72
.clang-tidy
Normal file
72
.clang-tidy
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
# Generated from CLion Inspection settings
|
||||||
|
---
|
||||||
|
Checks: '-*,
|
||||||
|
cppcoreguidelines-interfaces-global-init,
|
||||||
|
cppcoreguidelines-narrowing-conversions,
|
||||||
|
cppcoreguidelines-pro-type-member-init,
|
||||||
|
cppcoreguidelines-pro-type-static-cast-downcast,
|
||||||
|
cppcoreguidelines-slicing,
|
||||||
|
google-default-arguments,
|
||||||
|
google-explicit-constructor,
|
||||||
|
google-runtime-operator,
|
||||||
|
hicpp-exception-baseclass,
|
||||||
|
hicpp-multiway-paths-covered,
|
||||||
|
modernize-avoid-bind,
|
||||||
|
modernize-concat-nested-namespaces,
|
||||||
|
modernize-deprecated-headers,
|
||||||
|
modernize-deprecated-ios-base-aliases,
|
||||||
|
modernize-loop-convert,
|
||||||
|
modernize-make-shared,
|
||||||
|
modernize-make-unique,
|
||||||
|
modernize-pass-by-value,
|
||||||
|
modernize-raw-string-literal,
|
||||||
|
modernize-redundant-void-arg,
|
||||||
|
modernize-replace-auto-ptr,
|
||||||
|
modernize-replace-disallow-copy-and-assign-macro,
|
||||||
|
modernize-replace-random-shuffle,
|
||||||
|
modernize-return-braced-init-list,
|
||||||
|
modernize-shrink-to-fit,
|
||||||
|
modernize-unary-static-assert,
|
||||||
|
modernize-use-auto,
|
||||||
|
modernize-use-bool-literals,
|
||||||
|
modernize-use-emplace,
|
||||||
|
modernize-use-equals-default,
|
||||||
|
modernize-use-equals-delete,
|
||||||
|
modernize-use-nodiscard,
|
||||||
|
modernize-use-noexcept,
|
||||||
|
modernize-use-nullptr,
|
||||||
|
modernize-use-override,
|
||||||
|
modernize-use-transparent-functors,
|
||||||
|
modernize-use-uncaught-exceptions,
|
||||||
|
mpi-buffer-deref,
|
||||||
|
mpi-type-mismatch,
|
||||||
|
openmp-use-default-none,
|
||||||
|
performance-faster-string-find,
|
||||||
|
performance-for-range-copy,
|
||||||
|
performance-implicit-conversion-in-loop,
|
||||||
|
performance-inefficient-algorithm,
|
||||||
|
performance-inefficient-string-concatenation,
|
||||||
|
performance-inefficient-vector-operation,
|
||||||
|
performance-move-const-arg,
|
||||||
|
performance-move-constructor-init,
|
||||||
|
performance-no-automatic-move,
|
||||||
|
performance-noexcept-move-constructor,
|
||||||
|
performance-trivially-destructible,
|
||||||
|
performance-type-promotion-in-math-fn,
|
||||||
|
performance-unnecessary-copy-initialization,
|
||||||
|
performance-unnecessary-value-param,
|
||||||
|
portability-simd-intrinsics,
|
||||||
|
bugprone-*,
|
||||||
|
abseil-*,
|
||||||
|
cert-*,
|
||||||
|
objc-*,
|
||||||
|
readability-*,
|
||||||
|
clang-analyzer-*,
|
||||||
|
misc-*,
|
||||||
|
-readability-magic-numbers,
|
||||||
|
-bugprone-easily-swappable-parameters,
|
||||||
|
-readability-implicit-bool-conversion,
|
||||||
|
-readability-identifier-length,
|
||||||
|
-readability-named-parameter,
|
||||||
|
-readability-function-cognitive-complexity,
|
||||||
|
-misc-include-cleaner'
|
||||||
9
.idea/codeStyles/Project.xml
generated
9
.idea/codeStyles/Project.xml
generated
@@ -16,6 +16,12 @@
|
|||||||
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
||||||
<option name="SPACE_BETWEEN_ADJACENT_BRACKETS" value="true" />
|
<option name="SPACE_BETWEEN_ADJACENT_BRACKETS" value="true" />
|
||||||
</Objective-C>
|
</Objective-C>
|
||||||
|
<RiderCodeStyleSettings>
|
||||||
|
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="true" type="bool" />
|
||||||
|
</RiderCodeStyleSettings>
|
||||||
|
<clangFormatSettings>
|
||||||
|
<option name="ENABLED" value="true" />
|
||||||
|
</clangFormatSettings>
|
||||||
<editorconfig>
|
<editorconfig>
|
||||||
<option name="ENABLED" value="false" />
|
<option name="ENABLED" value="false" />
|
||||||
</editorconfig>
|
</editorconfig>
|
||||||
@@ -27,6 +33,9 @@
|
|||||||
</extensions>
|
</extensions>
|
||||||
</files>
|
</files>
|
||||||
<codeStyleSettings language="CMake">
|
<codeStyleSettings language="CMake">
|
||||||
|
<option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
|
||||||
|
<option name="SPACE_BEFORE_WHILE_PARENTHESES" value="false" />
|
||||||
|
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
|
||||||
<indentOptions>
|
<indentOptions>
|
||||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
</indentOptions>
|
</indentOptions>
|
||||||
|
|||||||
1
.idea/dictionaries/project.xml
generated
1
.idea/dictionaries/project.xml
generated
@@ -1,6 +1,7 @@
|
|||||||
<component name="ProjectDictionaryState">
|
<component name="ProjectDictionaryState">
|
||||||
<dictionary name="project">
|
<dictionary name="project">
|
||||||
<words>
|
<words>
|
||||||
|
<w>abcdefghijklmnopqrstuvwxyz</w>
|
||||||
<w>koalabox</w>
|
<w>koalabox</w>
|
||||||
<w>koaloader</w>
|
<w>koaloader</w>
|
||||||
</words>
|
</words>
|
||||||
|
|||||||
2
KoalaBox
2
KoalaBox
Submodule KoalaBox updated: 7c88436113...f08d46d4c4
2
docs/building_from_source.md
Normal file
2
docs/building_from_source.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
- Rework Koalabox integration: Remove submodule, add conditional include (local filesystem and CPM)
|
||||||
|
- Write up documentation
|
||||||
1
docs/steamworks_support.md
Normal file
1
docs/steamworks_support.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#
|
||||||
0
docs/tools.md
Normal file
0
docs/tools.md
Normal file
@@ -9,7 +9,7 @@ AppDlcNameMap get_cached_apps() noexcept {
|
|||||||
try {
|
try {
|
||||||
return koalabox::cache::get(KEY_APPS).get<AppDlcNameMap>();
|
return koalabox::cache::get(KEY_APPS).get<AppDlcNameMap>();
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_WARN("Failed to get cached apps: {}", e.what())
|
LOG_WARN("Failed to get cached apps: {}", e.what());
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,13 +18,13 @@ namespace smoke_api::app_cache {
|
|||||||
|
|
||||||
Vector<DLC> get_dlcs(AppId_t app_id) noexcept {
|
Vector<DLC> get_dlcs(AppId_t app_id) noexcept {
|
||||||
try {
|
try {
|
||||||
LOG_DEBUG("Reading cached DLC IDs for the app: {}", app_id)
|
LOG_DEBUG("Reading cached DLC IDs for the app: {}", app_id);
|
||||||
|
|
||||||
const auto apps = get_cached_apps();
|
const auto apps = get_cached_apps();
|
||||||
|
|
||||||
return DLC::get_dlcs_from_apps(apps, app_id);
|
return DLC::get_dlcs_from_apps(apps, app_id);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("Error reading DLCs from disk cache: ", e.what())
|
LOG_ERROR("Error reading DLCs from disk cache: ", e.what());
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ namespace smoke_api::app_cache {
|
|||||||
|
|
||||||
bool save_dlcs(AppId_t app_id, const Vector<DLC>& dlcs) noexcept {
|
bool save_dlcs(AppId_t app_id, const Vector<DLC>& dlcs) noexcept {
|
||||||
try {
|
try {
|
||||||
LOG_DEBUG("Caching DLC IDs for the app: {}", app_id)
|
LOG_DEBUG("Caching DLC IDs for the app: {}", app_id);
|
||||||
|
|
||||||
auto apps = get_cached_apps();
|
auto apps = get_cached_apps();
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ namespace smoke_api::app_cache {
|
|||||||
|
|
||||||
return koalabox::cache::put(KEY_APPS, Json(apps));
|
return koalabox::cache::put(KEY_APPS, Json(apps));
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("Error saving DLCs to disk cache: {}", e.what())
|
LOG_ERROR("Error saving DLCs to disk cache: {}", e.what());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace api {
|
|||||||
|
|
||||||
return DLC::get_dlcs_from_apps(response, app_id);
|
return DLC::get_dlcs_from_apps(response, app_id);
|
||||||
} catch (const Json::exception& e) {
|
} catch (const Json::exception& e) {
|
||||||
LOG_ERROR("Failed to fetch dlc list from GitHub: {}", e.what())
|
LOG_ERROR("Failed to fetch dlc list from GitHub: {}", e.what());
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ namespace api {
|
|||||||
|
|
||||||
return response.dlcs;
|
return response.dlcs;
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("Failed to fetch dlc list from Steam: {}", e.what())
|
LOG_ERROR("Failed to fetch dlc list from Steam: {}", e.what());
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ DLL_EXPORT(bool) SteamAPI_RestartAppIfNecessary(
|
|||||||
[[maybe_unused]] const uint32_t unOwnAppID
|
[[maybe_unused]] const uint32_t unOwnAppID
|
||||||
) {
|
) {
|
||||||
if (smoke_api::config::instance.override_app_id != 0) {
|
if (smoke_api::config::instance.override_app_id != 0) {
|
||||||
LOG_DEBUG("{} -> Preventing app restart", __func__)
|
LOG_DEBUG("{} -> Preventing app restart", __func__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ DLL_EXPORT(bool) SteamAPI_RestartAppIfNecessary(
|
|||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT(void) SteamAPI_Shutdown() {
|
DLL_EXPORT(void) SteamAPI_Shutdown() {
|
||||||
LOG_INFO("{} -> Game requested shutdown", __func__)
|
LOG_INFO("{} -> Game requested shutdown", __func__);
|
||||||
|
|
||||||
ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_Shutdown)();
|
ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_Shutdown)();
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(void* self, AppId_t dlcID)
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsDlcInstalled(void* self, AppId_t dlcID)
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ DLL_EXPORT(int) SteamAPI_ISteamApps_GetDLCCount(void* self) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamApps_BGetDLCDataByIndex(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ DLL_EXPORT(void*) SteamAPI_ISteamClient_GetISteamGenericInterface(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ DLL_EXPORT(EUserHasLicenseForAppResult) SteamAPI_ISteamUser_UserHasLicenseForApp
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
return k_EUserHasLicenseResultDoesNotHaveLicense;
|
return k_EUserHasLicenseResultDoesNotHaveLicense;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ String get_versioned_interface(const String& version_prefix, const String& fallb
|
|||||||
LOG_ERROR(
|
LOG_ERROR(
|
||||||
"Failed to get versioned interface: {}."
|
"Failed to get versioned interface: {}."
|
||||||
"Falling back to version {}", ex.what(), fallback
|
"Falling back to version {}", ex.what(), fallback
|
||||||
)
|
);
|
||||||
|
|
||||||
version_map[version_prefix] = version_prefix + fallback;
|
version_map[version_prefix] = version_prefix + fallback;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ VIRTUAL(bool) ISteamApps_BIsSubscribedApp(PARAMS(AppId_t dlc_id)) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@ VIRTUAL(bool) ISteamApps_BIsDlcInstalled(PARAMS(AppId_t dlc_id)) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@ VIRTUAL(int) ISteamApps_GetDLCCount(PARAMS()) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ VIRTUAL(bool) ISteamApps_BGetDLCDataByIndex(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ VIRTUAL(void*) ISteamClient_GetISteamApps(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ VIRTUAL(void*) ISteamClient_GetISteamUser(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ VIRTUAL(void*) ISteamClient_GetISteamGenericInterface(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,7 @@ VIRTUAL(void*) ISteamClient_GetISteamInventory(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp(PARAMS(CSte
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||||
return k_EUserHasLicenseResultDoesNotHaveLicense;
|
return k_EUserHasLicenseResultDoesNotHaveLicense;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
#include <Windows.h>
|
||||||
#include <smoke_api/smoke_api.hpp>
|
#include <smoke_api/smoke_api.hpp>
|
||||||
|
|
||||||
// This header will be populated at build time
|
// This header will be populated at build time
|
||||||
#include <linker_exports.h>
|
#include <linker_exports.h>
|
||||||
|
|
||||||
EXTERN_C [[maybe_unused]] BOOL WINAPI DllMain(HMODULE module_handle, DWORD reason, LPVOID) {
|
EXTERN_C [[maybe_unused]] BOOL WINAPI
|
||||||
|
DllMain(const HMODULE module_handle, const DWORD reason, LPVOID) {
|
||||||
if (reason == DLL_PROCESS_ATTACH) {
|
if (reason == DLL_PROCESS_ATTACH) {
|
||||||
smoke_api::init(module_handle);
|
smoke_api::init(module_handle);
|
||||||
} else if (reason == DLL_PROCESS_DETACH) {
|
} else if (reason == DLL_PROCESS_DETACH) {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace smoke_api::config {
|
|||||||
|
|
||||||
instance = Json::parse(config_str).get<Config>();
|
instance = Json::parse(config_str).get<Config>();
|
||||||
|
|
||||||
LOG_DEBUG("Parsed config:\n{}", Json(instance).dump(2))
|
LOG_DEBUG("Parsed config:\n{}", Json(instance).dump(2));
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
const auto message = fmt::format("Error parsing config file: {}", e.what());
|
const auto message = fmt::format("Error parsing config file: {}", e.what());
|
||||||
koalabox::util::error_box("SmokeAPI Error", message);
|
koalabox::util::error_box("SmokeAPI Error", message);
|
||||||
@@ -59,13 +59,13 @@ namespace smoke_api::config {
|
|||||||
LOG_TRACE(
|
LOG_TRACE(
|
||||||
"App ID: {}, DLC ID: {}, Status: {}, Original: {}, Unlocked: {}",
|
"App ID: {}, DLC ID: {}, Status: {}, Original: {}, Unlocked: {}",
|
||||||
app_id_str, dlc_id_str, Json(status).dump(), original_function(), is_unlocked
|
app_id_str, dlc_id_str, Json(status).dump(), original_function(), is_unlocked
|
||||||
)
|
);
|
||||||
|
|
||||||
return is_unlocked;
|
return is_unlocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLL_EXPORT(void) ReloadConfig() {
|
DLL_EXPORT(void) ReloadConfig() {
|
||||||
LOG_INFO("Reloading config")
|
LOG_INFO("Reloading config");
|
||||||
|
|
||||||
init_config();
|
init_config();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
#include <smoke_api/smoke_api.hpp>
|
#include "koalabox/paths.hpp"
|
||||||
#include <build_config.h>
|
|
||||||
#include <smoke_api/config.hpp>
|
|
||||||
#include <core/globals.hpp>
|
|
||||||
#include <core/paths.hpp>
|
|
||||||
#include <common/steamclient_exports.hpp>
|
|
||||||
#include <koalabox/globals.hpp>
|
|
||||||
#include <koalabox/dll_monitor.hpp>
|
#include <koalabox/dll_monitor.hpp>
|
||||||
#include <koalabox/logger.hpp>
|
#include <koalabox/globals.hpp>
|
||||||
#include <koalabox/hook.hpp>
|
#include <koalabox/hook.hpp>
|
||||||
#include <koalabox/loader.hpp>
|
#include <koalabox/loader.hpp>
|
||||||
#include <koalabox/win_util.hpp>
|
#include <koalabox/logger.hpp>
|
||||||
#include <koalabox/util.hpp>
|
#include <koalabox/util.hpp>
|
||||||
|
#include <koalabox/win_util.hpp>
|
||||||
|
|
||||||
|
#include <build_config.h>
|
||||||
|
#include <common/steamclient_exports.hpp>
|
||||||
|
#include <core/globals.hpp>
|
||||||
|
#include <core/paths.hpp>
|
||||||
|
#include <smoke_api/config.hpp>
|
||||||
|
#include <smoke_api/smoke_api.hpp>
|
||||||
|
|
||||||
#if COMPILE_STORE_MODE
|
#if COMPILE_STORE_MODE
|
||||||
#include <store_mode/store.hpp>
|
#include <store_mode/store.hpp>
|
||||||
@@ -34,69 +37,62 @@
|
|||||||
// Given that hooking steam_api has no apparent benefits, but has inherent flaws,
|
// Given that hooking steam_api has no apparent benefits, but has inherent flaws,
|
||||||
// the support for it has been dropped from this project.
|
// the support for it has been dropped from this project.
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void override_app_id() {
|
||||||
|
const auto override_app_id = smoke_api::config::instance.override_app_id;
|
||||||
|
if (override_app_id == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
void override_app_id() {
|
spdlog::default_logger_raw();
|
||||||
const auto override_app_id = smoke_api::config::instance.override_app_id;
|
LOG_DEBUG("Overriding app id to {}", override_app_id);
|
||||||
if (override_app_id == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
LOG_DEBUG("Overriding app id to {}", override_app_id);
|
SetEnvironmentVariable(TEXT("SteamAppId"), std::to_wstring(override_app_id).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
SetEnvironmentVariable(
|
void init_proxy_mode() {
|
||||||
TEXT("SteamAppId"),
|
LOG_INFO("Detected proxy mode");
|
||||||
std::to_wstring(override_app_id).c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_proxy_mode() {
|
override_app_id();
|
||||||
LOG_INFO("🔀 Detected proxy mode")
|
|
||||||
|
|
||||||
override_app_id();
|
globals::steamapi_module =
|
||||||
|
koalabox::loader::load_original_library(paths::get_self_path(), STEAMAPI_DLL);
|
||||||
|
}
|
||||||
|
|
||||||
globals::steamapi_module = koalabox::loader::load_original_library(
|
void init_hook_mode() {
|
||||||
paths::get_self_path(),
|
LOG_INFO("🪝 Detected hook mode");
|
||||||
STEAMAPI_DLL
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_hook_mode() {
|
override_app_id();
|
||||||
LOG_INFO("🪝 Detected hook mode")
|
|
||||||
|
|
||||||
override_app_id();
|
koalabox::dll_monitor::init_listener(STEAMCLIENT_DLL, [](const HMODULE& library) {
|
||||||
|
|
||||||
koalabox::dll_monitor::init_listener(
|
|
||||||
STEAMCLIENT_DLL,
|
|
||||||
[](const HMODULE &library) {
|
|
||||||
globals::steamclient_module = library;
|
globals::steamclient_module = library;
|
||||||
|
|
||||||
DETOUR_STEAMCLIENT(CreateInterface)
|
DETOUR_STEAMCLIENT(CreateInterface)
|
||||||
|
|
||||||
koalabox::dll_monitor::shutdown_listener();
|
koalabox::dll_monitor::shutdown_listener();
|
||||||
}
|
});
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
bool is_valve_steam(const String& exe_name) noexcept {
|
||||||
|
try {
|
||||||
|
if (exe_name < not_equals > "steam.exe") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that it's steam from valve, and not some other executable coincidentally named
|
||||||
|
// steam
|
||||||
|
|
||||||
|
const HMODULE steam_handle = koalabox::win_util::get_module_handle_or_throw(nullptr);
|
||||||
|
const auto manifest = koalabox::win_util::get_module_manifest(steam_handle);
|
||||||
|
|
||||||
|
// Steam.exe manifest is expected to contain this string
|
||||||
|
return manifest < contains > "valvesoftware.steam.steam";
|
||||||
|
} catch (const Exception& e) {
|
||||||
|
LOG_ERROR("{} -> {}", __func__, e.what());
|
||||||
|
|
||||||
bool is_valve_steam(const String &exe_name) noexcept {
|
|
||||||
try {
|
|
||||||
if (exe_name < not_equals > "steam.exe") {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that it's steam from valve, and not some other executable coincidentally named steam
|
|
||||||
|
|
||||||
const HMODULE steam_handle = koalabox::win_util::get_module_handle_or_throw(nullptr);
|
|
||||||
const auto manifest = koalabox::win_util::get_module_manifest(
|
|
||||||
steam_handle);
|
|
||||||
|
|
||||||
// Steam.exe manifest is expected to contain this string
|
|
||||||
return manifest < contains > "valvesoftware.steam.steam";
|
|
||||||
} catch (const Exception &e) {
|
|
||||||
LOG_ERROR("{} -> {}", __func__, e.what())
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace smoke_api {
|
namespace smoke_api {
|
||||||
void init(const HMODULE module_handle) {
|
void init(const HMODULE module_handle) {
|
||||||
// FIXME: IMPORTANT! Non ascii paths in directories will result in init errors
|
// FIXME: IMPORTANT! Non ascii paths in directories will result in init errors
|
||||||
@@ -110,33 +106,27 @@ namespace smoke_api {
|
|||||||
config::init_config();
|
config::init_config();
|
||||||
|
|
||||||
if (config::instance.logging) {
|
if (config::instance.logging) {
|
||||||
koalabox::logger::init_file_logger();
|
koalabox::logger::init_file_logger(koalabox::paths::get_log_path());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This kind of timestamp is reliable only for CI builds, as it will reflect the compilation
|
// This kind of timestamp is reliable only for CI builds, as it will reflect the
|
||||||
// time stamp only when this file gets recompiled.
|
// compilation time stamp only when this file gets recompiled.
|
||||||
LOG_INFO(
|
LOG_INFO("{} v{} | Compiled at '{}'", PROJECT_NAME, PROJECT_VERSION, __TIMESTAMP__);
|
||||||
"🐨 {} v{} | Compiled at '{}'", PROJECT_NAME,
|
|
||||||
PROJECT_VERSION,
|
|
||||||
__TIMESTAMP__
|
|
||||||
)
|
|
||||||
|
|
||||||
const Path exe_path = koalabox::win_util::get_module_file_name_or_throw(nullptr);
|
const Path exe_path = koalabox::win_util::get_module_file_name_or_throw(nullptr);
|
||||||
const auto exe_name = exe_path.filename().string();
|
const auto exe_name = exe_path.filename().string();
|
||||||
|
|
||||||
LOG_DEBUG("Process name: '{}' [{}-bit]", exe_name, BITNESS)
|
LOG_DEBUG("Process name: '{}' [{}-bit]", exe_name, BITNESS);
|
||||||
|
|
||||||
const bool is_hook_mode = koalabox::hook::is_hook_mode(
|
const bool is_hook_mode =
|
||||||
globals::smokeapi_handle,
|
koalabox::hook::is_hook_mode(globals::smokeapi_handle, STEAMAPI_DLL);
|
||||||
STEAMAPI_DLL
|
|
||||||
);
|
|
||||||
|
|
||||||
if (is_hook_mode) {
|
if (is_hook_mode) {
|
||||||
koalabox::hook::init(true);
|
koalabox::hook::init(true);
|
||||||
|
|
||||||
if (is_valve_steam(exe_name)) {
|
if (is_valve_steam(exe_name)) {
|
||||||
#if COMPILE_STORE_MODE
|
#if COMPILE_STORE_MODE
|
||||||
LOG_INFO("🛍️ Detected Store mode")
|
LOG_INFO("Detected Store mode");
|
||||||
store::init_store_mode();
|
store::init_store_mode();
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@@ -146,11 +136,9 @@ namespace smoke_api {
|
|||||||
init_proxy_mode();
|
init_proxy_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("🚀 Initialization complete")
|
LOG_INFO("Initialization complete");
|
||||||
} catch (const Exception &ex) {
|
} catch (const Exception& ex) {
|
||||||
koalabox::util::panic(
|
koalabox::util::panic(fmt::format("Initialization error: {}", ex.what()));
|
||||||
fmt::format("Initialization error: {}", ex.what())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,9 +148,11 @@ namespace smoke_api {
|
|||||||
koalabox::win_util::free_library(globals::steamapi_module);
|
koalabox::win_util::free_library(globals::steamapi_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("💀 Shutdown complete")
|
LOG_INFO("Shutdown complete");
|
||||||
} catch (const Exception &ex) {
|
} catch (const Exception& ex) {
|
||||||
LOG_ERROR("Shutdown error: {}", ex.what())
|
LOG_ERROR("Shutdown error: {}", ex.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
koalabox::logger::shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <steam_impl/steam_apps.hpp>
|
#include <steam_impl/steam_apps.hpp>
|
||||||
#include <steam_impl/steam_impl.hpp>
|
|
||||||
#include <common/app_cache.hpp>
|
#include <common/app_cache.hpp>
|
||||||
#include <smoke_api/config.hpp>
|
#include <smoke_api/config.hpp>
|
||||||
#include <koalabox/logger.hpp>
|
#include <koalabox/logger.hpp>
|
||||||
@@ -29,7 +28,7 @@ namespace steam_apps {
|
|||||||
const MutexLockGuard guard(mutex);
|
const MutexLockGuard guard(mutex);
|
||||||
|
|
||||||
if (app_id == 0) {
|
if (app_id == 0) {
|
||||||
LOG_ERROR("{} -> App ID is 0", __func__)
|
LOG_ERROR("{} -> App ID is 0", __func__);
|
||||||
app_dlcs[app_id] = {}; // Dummy value to avoid checking for presence on each access
|
app_dlcs[app_id] = {}; // Dummy value to avoid checking for presence on each access
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -45,7 +44,7 @@ namespace steam_apps {
|
|||||||
Vector<DLC> aggregated_dlcs;
|
Vector<DLC> aggregated_dlcs;
|
||||||
|
|
||||||
const auto append_dlcs = [&](const Vector<DLC>& source, const String& source_name) {
|
const auto append_dlcs = [&](const Vector<DLC>& source, const String& source_name) {
|
||||||
LOG_DEBUG("App ID {} has {} DLCs defined in {}", app_id, source.size(), source_name)
|
LOG_DEBUG("App ID {} has {} DLCs defined in {}", app_id, source.size(), source_name);
|
||||||
aggregated_dlcs < append > source;
|
aggregated_dlcs < append > source;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -82,11 +81,11 @@ namespace steam_apps {
|
|||||||
try {
|
try {
|
||||||
const auto unlocked = smoke_api::config::is_dlc_unlocked(app_id, dlc_id, original_function);
|
const auto unlocked = smoke_api::config::is_dlc_unlocked(app_id, dlc_id, original_function);
|
||||||
|
|
||||||
LOG_INFO("{} -> {}DLC ID: {:>8}, Unlocked: {}", function_name, get_app_id_log(app_id), dlc_id, unlocked)
|
LOG_INFO("{} -> {}DLC ID: {:>8}, Unlocked: {}", function_name, get_app_id_log(app_id), dlc_id, unlocked);
|
||||||
|
|
||||||
return unlocked;
|
return unlocked;
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("Uncaught exception: {}", e.what())
|
LOG_ERROR("Uncaught exception: {}", e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,28 +93,28 @@ namespace steam_apps {
|
|||||||
int GetDLCCount(const String& function_name, const AppId_t app_id, const Function<int()>& original_function) {
|
int GetDLCCount(const String& function_name, const AppId_t app_id, const Function<int()>& original_function) {
|
||||||
try {
|
try {
|
||||||
const auto total_count = [&](int count) {
|
const auto total_count = [&](int count) {
|
||||||
LOG_INFO("{} -> Responding with DLC count: {}", function_name, count)
|
LOG_INFO("{} -> Responding with DLC count: {}", function_name, count);
|
||||||
return count;
|
return count;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (app_id != 0) {
|
if (app_id != 0) {
|
||||||
LOG_DEBUG("{} -> App ID: {}", function_name, app_id)
|
LOG_DEBUG("{} -> App ID: {}", function_name, app_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto original_count = original_function();
|
const auto original_count = original_function();
|
||||||
LOG_DEBUG("{} -> Original DLC count: {}", function_name, original_count)
|
LOG_DEBUG("{} -> Original DLC count: {}", function_name, original_count);
|
||||||
|
|
||||||
if (original_count < MAX_DLC) {
|
if (original_count < MAX_DLC) {
|
||||||
return total_count(original_count);
|
return total_count(original_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("Game has {} or more DLCs. Fetching DLCs from remote sources.", original_count)
|
LOG_DEBUG("Game has {} or more DLCs. Fetching DLCs from remote sources.", original_count);
|
||||||
|
|
||||||
fetch_and_cache_dlcs(app_id);
|
fetch_and_cache_dlcs(app_id);
|
||||||
|
|
||||||
return total_count(static_cast<int>(app_dlcs[app_id].size()));
|
return total_count(static_cast<int>(app_dlcs[app_id].size()));
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR(" Uncaught exception: {}", function_name, e.what())
|
LOG_ERROR(" Uncaught exception: {}", function_name, e.what());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,13 +131,13 @@ namespace steam_apps {
|
|||||||
const Function<bool(AppId_t)>& is_originally_unlocked
|
const Function<bool(AppId_t)>& is_originally_unlocked
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
LOG_DEBUG("{} -> {}index: {:>3}", function_name, get_app_id_log(app_id), iDLC)
|
LOG_DEBUG("{} -> {}index: {:>3}", function_name, get_app_id_log(app_id), iDLC);
|
||||||
|
|
||||||
const auto print_dlc_info = [&](const String& tag) {
|
const auto print_dlc_info = [&](const String& tag) {
|
||||||
LOG_INFO(
|
LOG_INFO(
|
||||||
R"({} -> [{:^12}] {}index: {:>3}, DLC ID: {:>8}, available: {:5}, name: "{}")",
|
R"({} -> [{:^12}] {}index: {:>3}, DLC ID: {:>8}, available: {:5}, name: "{}")",
|
||||||
function_name, tag, get_app_id_log(app_id), iDLC, *pDlcId, *pbAvailable, pchName
|
function_name, tag, get_app_id_log(app_id), iDLC, *pDlcId, *pbAvailable, pchName
|
||||||
)
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto inject_dlc = [&](const DLC& dlc) {
|
const auto inject_dlc = [&](const DLC& dlc) {
|
||||||
@@ -164,7 +163,7 @@ namespace steam_apps {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_WARN("{} -> Out of bounds DLC index: {}", function_name, iDLC)
|
LOG_WARN("{} -> Out of bounds DLC index: {}", function_name, iDLC);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,12 +175,12 @@ namespace steam_apps {
|
|||||||
);
|
);
|
||||||
print_dlc_info("original");
|
print_dlc_info("original");
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("{} -> original call failed for index: {}", function_name, iDLC)
|
LOG_WARN("{} -> original call failed for index: {}", function_name, iDLC);
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
LOG_ERROR("{} -> Uncaught exception: {}", function_name, e.what())
|
LOG_ERROR("{} -> Uncaught exception: {}", function_name, e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace steam_client {
|
|||||||
) {
|
) {
|
||||||
auto* const interface = original_function();
|
auto* const interface = original_function();
|
||||||
|
|
||||||
LOG_DEBUG("{} -> '{}' @ {}", function_name, interface_version, interface)
|
LOG_DEBUG("{} -> '{}' @ {}", function_name, interface_version, interface);
|
||||||
|
|
||||||
steam_impl::hook_virtuals(interface, interface_version);
|
steam_impl::hook_virtuals(interface, interface_version);
|
||||||
|
|
||||||
|
|||||||
@@ -91,20 +91,20 @@ namespace steam_impl {
|
|||||||
const int min_version,
|
const int min_version,
|
||||||
const int max_version
|
const int max_version
|
||||||
) {
|
) {
|
||||||
LOG_DEBUG("Hooking interface '{}'", version_string)
|
LOG_DEBUG("Hooking interface '{}'", version_string);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const auto version_number = stoi(version_string.substr(prefix.length()));
|
const auto version_number = stoi(version_string.substr(prefix.length()));
|
||||||
|
|
||||||
if (version_number < min_version) {
|
if (version_number < min_version) {
|
||||||
LOG_WARN("Legacy version of {}: {}", version_string, version_number)
|
LOG_WARN("Legacy version of {}: {}", version_string, version_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version_number > max_version) {
|
if (version_number > max_version) {
|
||||||
LOG_WARN(
|
LOG_WARN(
|
||||||
"Unsupported new version of {}: {}. Fallback version {} will be used",
|
"Unsupported new version of {}: {}. Fallback version {} will be used",
|
||||||
version_string, version_number, max_version
|
version_string, version_number, max_version
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return version_number;
|
return version_number;
|
||||||
@@ -157,7 +157,7 @@ namespace steam_impl {
|
|||||||
static Set<void*> hooked_interfaces;
|
static Set<void*> hooked_interfaces;
|
||||||
|
|
||||||
if (hooked_interfaces.contains(interface)) {
|
if (hooked_interfaces.contains(interface)) {
|
||||||
LOG_DEBUG("Interface {} at {} has already been hooked.", version_string, interface)
|
LOG_DEBUG("Interface {} at {} has already been hooked.", version_string, interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Mutex section;
|
static Mutex section;
|
||||||
@@ -230,7 +230,7 @@ namespace steam_impl {
|
|||||||
GetHSteamPipe_address = (void*)koalabox::win_util::get_proc_address_or_throw(
|
GetHSteamPipe_address = (void*)koalabox::win_util::get_proc_address_or_throw(
|
||||||
steam_api_module, "SteamAPI_GetHSteamPipe"
|
steam_api_module, "SteamAPI_GetHSteamPipe"
|
||||||
);
|
);
|
||||||
} catch (const Exception& ex) {
|
} catch (...) {
|
||||||
GetHSteamPipe_address = (void*)koalabox::win_util::get_proc_address_or_throw(
|
GetHSteamPipe_address = (void*)koalabox::win_util::get_proc_address_or_throw(
|
||||||
steam_api_module, "GetHSteamPipe"
|
steam_api_module, "GetHSteamPipe"
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace steam_inventory {
|
|||||||
) {
|
) {
|
||||||
const auto status = original_function();
|
const auto status = original_function();
|
||||||
|
|
||||||
LOG_DEBUG("{} -> handle: {}, status: {}", function_name, resultHandle, (int) status)
|
LOG_DEBUG("{} -> handle: {}, status: {}", function_name, resultHandle, (int) status);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -33,23 +33,23 @@ namespace steam_inventory {
|
|||||||
LOG_DEBUG(
|
LOG_DEBUG(
|
||||||
" [{}] definitionId: {}, itemId: {}, quantity: {}, flags: {}",
|
" [{}] definitionId: {}, itemId: {}, quantity: {}, flags: {}",
|
||||||
tag, item.m_iDefinition, item.m_itemId, item.m_unQuantity, item.m_unFlags
|
tag, item.m_iDefinition, item.m_itemId, item.m_unQuantity, item.m_unFlags
|
||||||
)
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (not success) {
|
if (not success) {
|
||||||
LOG_DEBUG("{} -> original result is false", function_name)
|
LOG_DEBUG("{} -> original result is false", function_name);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (punOutItemsArraySize == nullptr) {
|
if (punOutItemsArraySize == nullptr) {
|
||||||
LOG_ERROR("{} -> arraySize pointer is null", function_name)
|
LOG_ERROR("{} -> arraySize pointer is null", function_name);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG(
|
LOG_DEBUG(
|
||||||
"{} -> handle: {}, pOutItemsArray: {}, arraySize: {}",
|
"{} -> handle: {}, pOutItemsArray: {}, arraySize: {}",
|
||||||
function_name, resultHandle, fmt::ptr(pOutItemsArray), *punOutItemsArraySize
|
function_name, resultHandle, fmt::ptr(pOutItemsArray), *punOutItemsArraySize
|
||||||
)
|
);
|
||||||
|
|
||||||
static uint32_t original_count = 0;
|
static uint32_t original_count = 0;
|
||||||
const auto injected_count = smoke_api::config::instance.extra_inventory_items.size();
|
const auto injected_count = smoke_api::config::instance.extra_inventory_items.size();
|
||||||
@@ -75,7 +75,7 @@ namespace steam_inventory {
|
|||||||
LOG_DEBUG(
|
LOG_DEBUG(
|
||||||
"{} -> Original count: {}, Total count: {}",
|
"{} -> Original count: {}, Total count: {}",
|
||||||
function_name, original_count, *punOutItemsArraySize
|
function_name, original_count, *punOutItemsArraySize
|
||||||
)
|
);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, we modify the array
|
// Otherwise, we modify the array
|
||||||
for (int i = 0; i < original_count; i++) {
|
for (int i = 0; i < original_count; i++) {
|
||||||
@@ -129,11 +129,11 @@ namespace steam_inventory {
|
|||||||
const auto success = original_function();
|
const auto success = original_function();
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
LOG_WARN("{}, Result is false", common_info)
|
LOG_WARN("{}, Result is false", common_info);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("{}, Buffer: '{}'", common_info, String(pchValueBuffer, *punValueBufferSizeOut - 1))
|
LOG_DEBUG("{}, Buffer: '{}'", common_info, String(pchValueBuffer, *punValueBufferSizeOut - 1));
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@@ -145,7 +145,7 @@ namespace steam_inventory {
|
|||||||
) {
|
) {
|
||||||
const auto success = original_function();
|
const auto success = original_function();
|
||||||
|
|
||||||
LOG_DEBUG("{} -> Handle: {}", function_name, fmt::ptr(pResultHandle))
|
LOG_DEBUG("{} -> Handle: {}", function_name, fmt::ptr(pResultHandle));
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@@ -160,11 +160,11 @@ namespace steam_inventory {
|
|||||||
) {
|
) {
|
||||||
const auto success = original_function();
|
const auto success = original_function();
|
||||||
|
|
||||||
LOG_DEBUG("{} -> Handle: {}", function_name, fmt::ptr(pResultHandle))
|
LOG_DEBUG("{} -> Handle: {}", function_name, fmt::ptr(pResultHandle));
|
||||||
|
|
||||||
if (success && pInstanceIDs != nullptr) {
|
if (success && pInstanceIDs != nullptr) {
|
||||||
for (int i = 0; i < unCountInstanceIDs; i++) {
|
for (int i = 0; i < unCountInstanceIDs; i++) {
|
||||||
LOG_DEBUG(" Index: {}, ItemId: {}", i, pInstanceIDs[i])
|
LOG_DEBUG(" Index: {}, ItemId: {}", i, pInstanceIDs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,9 +182,9 @@ namespace steam_inventory {
|
|||||||
|
|
||||||
if (pOutBuffer != nullptr) {
|
if (pOutBuffer != nullptr) {
|
||||||
String buffer((char*) pOutBuffer, *punOutBufferSize);
|
String buffer((char*) pOutBuffer, *punOutBufferSize);
|
||||||
LOG_DEBUG("{} -> Handle: {}, Buffer: '{}'", function_name, resultHandle, buffer)
|
LOG_DEBUG("{} -> Handle: {}, Buffer: '{}'", function_name, resultHandle, buffer);
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("{} -> Handle: {}, Size: '{}'", function_name, resultHandle, *punOutBufferSize)
|
LOG_DEBUG("{} -> Handle: {}, Size: '{}'", function_name, resultHandle, *punOutBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
@@ -199,18 +199,18 @@ namespace steam_inventory {
|
|||||||
const auto success = original_function();
|
const auto success = original_function();
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
LOG_WARN("{} -> Result is false", function_name)
|
LOG_WARN("{} -> Result is false", function_name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (punItemDefIDsArraySize) {
|
if (punItemDefIDsArraySize) {
|
||||||
LOG_DEBUG("{} -> Size: {}", function_name, *punItemDefIDsArraySize)
|
LOG_DEBUG("{} -> Size: {}", function_name, *punItemDefIDsArraySize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pItemDefIDs) { // Definitions were copied
|
if (pItemDefIDs) { // Definitions were copied
|
||||||
for (int i = 0; i < *punItemDefIDsArraySize; i++) {
|
for (int i = 0; i < *punItemDefIDsArraySize; i++) {
|
||||||
const auto& def = pItemDefIDs[i];
|
const auto& def = pItemDefIDs[i];
|
||||||
LOG_DEBUG(" Index: {}, ID: {}", i, def)
|
LOG_DEBUG(" Index: {}, ID: {}", i, def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ namespace steam_inventory {
|
|||||||
LOG_DEBUG(
|
LOG_DEBUG(
|
||||||
"{} -> handle: {}, steamID: {}, original result: {}",
|
"{} -> handle: {}, steamID: {}, original result: {}",
|
||||||
function_name, resultHandle, steamIDExpected, result
|
function_name, resultHandle, steamIDExpected, result
|
||||||
)
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace steam_user {
|
|||||||
const auto result = original_function();
|
const auto result = original_function();
|
||||||
|
|
||||||
if (result == k_EUserHasLicenseResultNoAuth) {
|
if (result == k_EUserHasLicenseResultNoAuth) {
|
||||||
LOG_WARN("{} -> App ID: {:>8}, Result: NoAuth", function_name, dlcId)
|
LOG_WARN("{} -> App ID: {:>8}, Result: NoAuth", function_name, dlcId);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ namespace steam_user {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
LOG_INFO("{} -> App ID: {:>8}, HasLicense: {}", function_name, dlcId, has_license)
|
LOG_INFO("{} -> App ID: {:>8}, HasLicense: {}", function_name, dlcId, has_license);
|
||||||
|
|
||||||
return has_license
|
return has_license
|
||||||
? k_EUserHasLicenseResultHasLicense
|
? k_EUserHasLicenseResultHasLicense
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ project(smoke-api-tools LANGUAGES CXX)
|
|||||||
|
|
||||||
### Install CPM package manager
|
### Install CPM package manager
|
||||||
|
|
||||||
include(../KoalaBox/cmake/get_cpm.cmake)
|
#include(../KoalaBox/cmake/get_cpm.cmake)
|
||||||
|
|
||||||
### Install parser library
|
### Install parser library
|
||||||
|
|
||||||
@@ -54,6 +54,7 @@ CPMAddPackage(
|
|||||||
|
|
||||||
add_executable(steamworks_downloader steamworks_downloader.cpp)
|
add_executable(steamworks_downloader steamworks_downloader.cpp)
|
||||||
target_link_libraries(steamworks_downloader PRIVATE
|
target_link_libraries(steamworks_downloader PRIVATE
|
||||||
|
KoalaBox
|
||||||
cpr # HTTP client
|
cpr # HTTP client
|
||||||
miniz # ZIP library
|
miniz # ZIP library
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,111 +1,21 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <iostream>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <cpr/cpr.h>
|
#include <cpr/cpr.h>
|
||||||
#include <miniz.h>
|
|
||||||
|
#include <koalabox/zip.hpp>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
namespace zip = koalabox::zip;
|
||||||
|
|
||||||
// Function to extract files from a ZIP archive that match multiple regex patterns
|
// ReSharper disable once CppDFAConstantParameter
|
||||||
void extract_files(
|
|
||||||
const fs::path& zip_path,
|
|
||||||
const std::function<fs::path(const std::string& name, bool is_dir)>& predicate
|
|
||||||
) {
|
|
||||||
mz_zip_archive zip = {};
|
|
||||||
|
|
||||||
if (!mz_zip_reader_init_file(&zip, zip_path.string().c_str(), 0)) {
|
|
||||||
throw std::runtime_error("mz_zip_reader_init_file() failed for: " + zip_path.string());
|
|
||||||
}
|
|
||||||
|
|
||||||
[[maybe_unused]] auto guard = [&zip] { mz_zip_reader_end(&zip); };
|
|
||||||
try {
|
|
||||||
std::error_code ec;
|
|
||||||
const mz_uint num_files = mz_zip_reader_get_num_files(&zip);
|
|
||||||
|
|
||||||
for (mz_uint i = 0; i < num_files; ++i) {
|
|
||||||
mz_zip_archive_file_stat st;
|
|
||||||
if (!mz_zip_reader_file_stat(&zip, i, &st)) {
|
|
||||||
mz_zip_reader_end(&zip);
|
|
||||||
throw std::runtime_error(
|
|
||||||
"mz_zip_reader_file_stat() failed at index " + std::to_string(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string name = st.m_filename;
|
|
||||||
|
|
||||||
// Skip dangerous names early
|
|
||||||
if (name.empty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool is_dir = mz_zip_reader_is_file_a_directory(&zip, i) != 0;
|
|
||||||
|
|
||||||
const auto out_path = predicate(name, is_dir);
|
|
||||||
if (out_path.empty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_dir) {
|
|
||||||
fs::create_directories(out_path, ec);
|
|
||||||
if (ec) {
|
|
||||||
mz_zip_reader_end(&zip);
|
|
||||||
throw std::runtime_error(
|
|
||||||
"Failed to create directory: " + out_path.string() + " (" + ec.message()
|
|
||||||
+ ")");
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure parent directories exist
|
|
||||||
fs::create_directories(out_path.parent_path(), ec);
|
|
||||||
if (ec) {
|
|
||||||
mz_zip_reader_end(&zip);
|
|
||||||
throw std::runtime_error(
|
|
||||||
"Failed to create parent directories for: " + out_path.string() + " (" + ec.
|
|
||||||
message() + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract to heap then write to file
|
|
||||||
size_t uncomp_size = 0;
|
|
||||||
void* p = mz_zip_reader_extract_to_heap(&zip, i, &uncomp_size, 0);
|
|
||||||
if (!p) {
|
|
||||||
mz_zip_reader_end(&zip);
|
|
||||||
throw std::runtime_error("Extraction failed for entry: " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ofstream ofs(out_path, std::ios::binary);
|
|
||||||
if (!ofs) {
|
|
||||||
mz_free(p);
|
|
||||||
mz_zip_reader_end(&zip);
|
|
||||||
throw std::runtime_error(
|
|
||||||
"Failed to open output file for writing: " + out_path.string());
|
|
||||||
}
|
|
||||||
ofs.write(static_cast<const char*>(p),
|
|
||||||
static_cast<std::streamsize>(uncomp_size));
|
|
||||||
ofs.close();
|
|
||||||
mz_free(p);
|
|
||||||
|
|
||||||
if (!ofs) {
|
|
||||||
mz_zip_reader_end(&zip);
|
|
||||||
throw std::runtime_error("Failed to write output file: " + out_path.string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_zip_reader_end(&zip);
|
|
||||||
} catch (...) {
|
|
||||||
// Ensure cleanup on exceptions
|
|
||||||
guard();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string generate_random_string(const size_t length) {
|
std::string generate_random_string(const size_t length) {
|
||||||
static constexpr char charset[] =
|
static constexpr char charset[] = "0123456789"
|
||||||
"0123456789"
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
"abcdefghijklmnopqrstuvwxyz";
|
||||||
"abcdefghijklmnopqrstuvwxyz";
|
|
||||||
|
|
||||||
thread_local std::mt19937_64 rng{std::random_device{}()};
|
thread_local std::mt19937_64 rng{std::random_device{}()};
|
||||||
thread_local std::uniform_int_distribution<std::size_t> dist(0, sizeof(charset) - 2);
|
thread_local std::uniform_int_distribution<std::size_t> dist(0, sizeof(charset) - 2);
|
||||||
@@ -121,50 +31,41 @@ namespace {
|
|||||||
|
|
||||||
void print_help() {
|
void print_help() {
|
||||||
std::cout << "Steamworks SDK downloader for SmokeAPI v1.0" << std::endl
|
std::cout << "Steamworks SDK downloader for SmokeAPI v1.0" << std::endl
|
||||||
<< "Usage: steamworks_downloader version1 version2 ... versionN" << std::endl
|
<< "Usage: steamworks_downloader version1 version2 ... versionN" << std::endl
|
||||||
<< "Example: steamworks_downloader 100 158a 162" << std::endl
|
<< "Example: steamworks_downloader 100 158a 162" << std::endl
|
||||||
<< "SDK version list available at: "
|
<< "SDK version list available at: "
|
||||||
<< "https://partner.steamgames.com/downloads/list" << std::endl;
|
<< "https://partner.steamgames.com/downloads/list" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unzip_sdk(const fs::path& zip_file_path, const fs::path& unzip_dir) {
|
void unzip_sdk(const fs::path& zip_file_path, const fs::path& unzip_dir) {
|
||||||
extract_files(zip_file_path, [&](const std::string& name, const bool) {
|
zip::extract_files(zip_file_path, [&](const std::string& name, const bool) {
|
||||||
if (name.starts_with("sdk/public/steam/") && name.ends_with(".h")) {
|
if (name.starts_with("sdk/public/steam/") && name.ends_with(".h")) {
|
||||||
return unzip_dir / "headers" / fs::path(name).filename();
|
return unzip_dir / "headers" / fs::path(name).filename();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (name.starts_with("sdk/redistributable_bin/") && name.ends_with(".dll") &&
|
||||||
name.starts_with("sdk/redistributable_bin/") &&
|
name.find("steam_api") != std::string::npos) {
|
||||||
name.ends_with(".dll") &&
|
|
||||||
name.find("steam_api") != std::string::npos
|
|
||||||
) {
|
|
||||||
return unzip_dir / "binaries" / fs::path(name).filename();
|
return unzip_dir / "binaries" / fs::path(name).filename();
|
||||||
}
|
}
|
||||||
|
|
||||||
return fs::path();
|
return fs::path();
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void download_sdk(
|
void download_sdk(const fs::path& steamworks_dir, const std::string_view& version) {
|
||||||
const fs::path& steamworks_dir,
|
|
||||||
const std::string_view& version
|
|
||||||
) {
|
|
||||||
const auto download_url = std::format(
|
const auto download_url = std::format(
|
||||||
"https://github.com/acidicoala/cdn/raw/refs/heads/main/valve/steamworks_sdk_{}.zip",
|
"https://github.com/acidicoala/cdn/raw/refs/heads/main/valve/steamworks_sdk_{}.zip",
|
||||||
version
|
version
|
||||||
);
|
);
|
||||||
|
|
||||||
const auto zip_file_path = fs::temp_directory_path()
|
const auto zip_file_path =
|
||||||
/ (generate_random_string(16) + ".zip");
|
fs::temp_directory_path() / (generate_random_string(16) + ".zip");
|
||||||
|
|
||||||
std::cout << "Downloading " << download_url << " to " << zip_file_path << std::endl;
|
std::cout << "Downloading " << download_url << " to " << zip_file_path << std::endl;
|
||||||
|
|
||||||
std::ofstream of(zip_file_path, std::ios::binary);
|
std::ofstream of(zip_file_path, std::ios::binary);
|
||||||
if (
|
if (const auto res = cpr::Download(of, cpr::Url{download_url});
|
||||||
const auto res = cpr::Download(of, cpr::Url{download_url});
|
res.error.code != cpr::ErrorCode::OK) {
|
||||||
res.error.code != cpr::ErrorCode::OK
|
|
||||||
) {
|
|
||||||
std::cerr << "Download error: " << res.error.message << std::endl;
|
std::cerr << "Download error: " << res.error.message << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -180,7 +81,7 @@ namespace {
|
|||||||
fs::remove(zip_file_path);
|
fs::remove(zip_file_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A tool for downloading Steamworks SDK and unpacking its headers and binaries
|
* A tool for downloading Steamworks SDK and unpacking its headers and binaries
|
||||||
@@ -198,9 +99,8 @@ int main(const int argc, const char** argv) {
|
|||||||
try {
|
try {
|
||||||
download_sdk(streamworks_dir, argv[i]);
|
download_sdk(streamworks_dir, argv[i]);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::cerr
|
std::cerr << std::format("Error downloading SDK '{}'. Reason: {}", argv[i], e.what())
|
||||||
<< std::format("Error downloading SDK '{}'. Reason: {}", argv[i], e.what())
|
<< std::endl;
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user