Updated logging

This commit is contained in:
acidicoala
2023-01-08 11:52:23 +03:00
parent a2cbf55819
commit 55ada47bef
16 changed files with 132 additions and 87 deletions

View File

@@ -1,13 +1,22 @@
#include <core/config.hpp>
#include <core/paths.hpp>
#include <koalabox/config_parser.hpp>
#include <koalabox/json.hpp>
#include <koalabox/util.hpp>
namespace config {
Config instance; // NOLINT(cert-err58-cpp)
// TODO: Reloading via export
void init() {
instance = koalabox::config_parser::parse<Config>(paths::get_config_path());
const auto path = paths::get_config_path();
if (exists(path)) {
try {
instance = Json(path).get<Config>();
} catch (const Exception& e) {
koalabox::util::panic("Error parsing config: {}", e.what());
}
}
}
AppStatus get_app_status(uint32_t app_id) {

View File

@@ -1,6 +1,7 @@
#pragma once
#include <koalabox/core.hpp>
#include <koalabox/json.hpp>
namespace config {
enum class AppStatus {
@@ -44,7 +45,8 @@ namespace config {
Json koalageddon_config;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
Config, $version, // NOLINT(misc-const-correctness)
Config, // NOLINT(misc-const-correctness)
$version,
logging,
unlock_family_sharing,
default_app_status,

View File

@@ -31,8 +31,8 @@
#define ARGS(...) RCX, ##__VA_ARGS__
#define THIS RCX
#else
#define PARAMS(...) void* ECX, void* EDX, ##__VA_ARGS__
#define ARGS(...) ECX, EDX, ##__VA_ARGS__
#define PARAMS(...) void* ECX, void* EDX __VA_OPT__(,) __VA_ARGS__
#define ARGS(...) ECX, EDX __VA_OPT__(,) __VA_ARGS__
#define THIS ECX
#endif

View File

@@ -2,7 +2,11 @@
#include <koalabox/core.hpp>
#define COMPILE_KOALAGEDDON _WIN64
#ifdef _WIN64
#define COMPILE_KOALAGEDDON 0
#else
#define COMPILE_KOALAGEDDON 1
#endif
using AppId_t = uint32_t;
using SteamInventoryResult_t = uint32_t;

View File

@@ -8,11 +8,11 @@ namespace koalageddon::cache {
std::optional<KoalageddonConfig> get_koalageddon_config() {
try {
const auto cache = koalabox::cache::read_from_cache(KEY_KG_CONFIG).value();
const auto cache = koalabox::cache::read_from_cache(KEY_KG_CONFIG);
return cache.at(KEY_KG_CONFIG).get<KoalageddonConfig>();
return cache[KEY_KG_CONFIG].get<KoalageddonConfig>();
} catch (const Exception& e) {
LOG_ERROR("{} -> Failed to get cached koalageddon config: {}", __func__, e.what())
LOG_ERROR("Failed to get cached koalageddon config: {}", e.what())
return std::nullopt;
}
@@ -20,11 +20,11 @@ namespace koalageddon::cache {
bool save_koalageddon_config(const KoalageddonConfig& config) {
try {
LOG_DEBUG("{} -> Caching koalageddon config", __func__)
LOG_DEBUG("Caching koalageddon config")
return koalabox::cache::save_to_cache(KEY_KG_CONFIG, config);
return koalabox::cache::save_to_cache(KEY_KG_CONFIG, Json(config));
} catch (const Exception& e) {
LOG_ERROR("{} -> Failed to cache koalageddon config: {}", __func__, e.what())
LOG_ERROR("Failed to cache koalageddon config: {}", e.what())
return false;
}

View File

@@ -6,7 +6,6 @@
#include <steam_functions/steam_functions.hpp>
#include <koalabox/dll_monitor.hpp>
#include <koalabox/http_client.hpp>
#include <koalabox/util.hpp>
#include <koalabox/logger.hpp>
namespace koalageddon {
@@ -56,16 +55,16 @@ namespace koalageddon {
void init() {
std::thread(
[]() {
const auto kg_config_source = init_koalageddon_config();
LOG_INFO("Loaded Koalageddon config from the {}", kg_config_source)
}
[]() {
const auto kg_config_source = init_koalageddon_config();
LOG_INFO("Loaded Koalageddon config from the {}", kg_config_source)
}
).detach();
koalabox::dll_monitor::init_listener(
{VSTDLIB_DLL, STEAMCLIENT_DLL}, [](const HMODULE& module_handle, const String& name) {
try {
if (koalabox::util::strings_are_equal(name, VSTDLIB_DLL)) {
if (name < equals > VSTDLIB_DLL) {
// VStdLib DLL handles Family Sharing functions
globals::vstdlib_module = module_handle;
@@ -73,7 +72,7 @@ namespace koalageddon {
if (config::instance.unlock_family_sharing) {
DETOUR_VSTDLIB(Coroutine_Create)
}
} else if (koalabox::util::strings_are_equal(name, STEAMCLIENT_DLL)) {
} else if (name < equals > STEAMCLIENT_DLL) {
// SteamClient DLL handles unlocking functions
globals::steamclient_module = module_handle;

View File

@@ -157,8 +157,8 @@ namespace koalageddon::steamclient {
&instruction
))) {
LOG_TRACE(
"{} -> Visiting {} | {}",
__func__, (void*) current_address, *get_instruction_string(instruction, current_address)
"{} visiting {} | {}", __func__,
(void*) current_address, *get_instruction_string(instruction, current_address)
)
const auto& last_instruction = instruction_list.front();
@@ -255,10 +255,7 @@ namespace koalageddon::steamclient {
if (offset && is_derived_from_base_reg) {
const auto ordinal = *offset / sizeof(uintptr_t);
LOG_DEBUG(
"{} -> Found function ordinal {}::{}@{}",
__func__, target_interface, *context.function_name, ordinal
)
LOG_DEBUG("Found function ordinal {}::{}@{}", target_interface, *context.function_name, ordinal)
map[*context.function_name] = ordinal;
break;
@@ -325,10 +322,10 @@ namespace koalageddon::steamclient {
const uintptr_t start_address,
Set<uintptr_t>& visited_addresses
) {
LOG_TRACE("{} -> start_address: {}", __func__, (void*) start_address)
LOG_TRACE("start_address: {}", (void*) start_address)
if (visited_addresses.contains(start_address)) {
LOG_TRACE("{} -> Breaking recursion due to visited address", __func__)
LOG_TRACE("Breaking recursion due to visited address")
return;
}
@@ -343,8 +340,8 @@ namespace koalageddon::steamclient {
))) {
visited_addresses.insert(current_address);
LOG_TRACE(
"{} -> Visiting {} | {}",
__func__, (void*) current_address, *get_instruction_string(instruction, current_address)
"{} visiting {} | {}", __func__,
(void*) current_address, *get_instruction_string(instruction, current_address)
)
const auto operand = instruction.operands[0];
@@ -352,7 +349,7 @@ namespace koalageddon::steamclient {
if (instruction.mnemonic == ZYDIS_MNEMONIC_CALL &&
operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE
) {
LOG_TRACE("{} -> Found call instruction at {}", __func__, (void*) current_address)
LOG_TRACE("Found call instruction at {}", (void*) current_address)
const auto function_selector_address = get_absolute_address(instruction, current_address);
@@ -375,7 +372,7 @@ namespace koalageddon::steamclient {
process_interface_selector(jump_taken_destination, visited_addresses);
process_interface_selector(jump_not_taken_destination, visited_addresses);
LOG_TRACE("breaking recursion due to conditional branch")
LOG_TRACE("Breaking recursion due to conditional branch")
return;
} else if (instruction.mnemonic == ZYDIS_MNEMONIC_JMP &&
operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE
@@ -384,7 +381,7 @@ namespace koalageddon::steamclient {
process_interface_selector(jump_destination, visited_addresses);
LOG_TRACE("breaking recursion due to unconditional branch")
LOG_TRACE("Breaking recursion due to unconditional branch")
return;
} else if (instruction.mnemonic == ZYDIS_MNEMONIC_JMP &&
operand.type == ZYDIS_OPERAND_TYPE_MEMORY &&
@@ -403,7 +400,7 @@ namespace koalageddon::steamclient {
return;
} else if (instruction.mnemonic == ZYDIS_MNEMONIC_RET) {
LOG_TRACE("{} -> Breaking recursion due to return instruction", __func__)
LOG_TRACE("Breaking recursion due to return instruction")
return;
}
@@ -419,7 +416,7 @@ namespace koalageddon::steamclient {
koalageddon::config.steam_client_internal_interface_selector_ordinal
];
LOG_DEBUG("Found interface selector at: {}", (void*) interface_selector_address);
LOG_DEBUG("Found interface selector at: {}", (void*) interface_selector_address)
if (ZYAN_FAILED(ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_ADDRESS_WIDTH_32))) {
LOG_ERROR("Failed to initialize zydis decoder")

View File

@@ -1,6 +1,7 @@
#pragma once
#include <koalabox/core.hpp>
#include <koalabox/json.hpp>
// Offset values are interpreted according to pointer arithmetic rules, i.e.
// 1 unit offset represents 4 and 8 bytes in 32-bit and 64-bit architectures respectively.

View File

@@ -8,32 +8,43 @@ using namespace koalageddon;
namespace koalageddon::vstdlib {
using namespace koalabox;
VIRTUAL(bool) SharedLicensesLockStatus(PARAMS(void* arg)) {
LOG_DEBUG("{} -> ecx: {}, edx: {}, arg: {}", __func__, ARGS(arg))
return true;
}
VIRTUAL(bool) SharedLicensesLockStatus(PARAMS(void* arg)
) {
LOG_DEBUG("{}(this={}, arg={})", __func__, THIS, arg)
ARGS();
return true;
}
VIRTUAL(bool) SharedLibraryStopPlaying(PARAMS(void* arg)) {
LOG_DEBUG("{} -> ecx: {}, edx: {}, arg: {}", __func__, ARGS(arg))
return true;
}
VIRTUAL(bool) SharedLibraryStopPlaying(PARAMS(void* arg)
) {
LOG_DEBUG("{}(this={}, arg={})", __func__, THIS, arg)
ARGS();
return true;
}
VIRTUAL(void) VStdLib_Callback_Interceptor(PARAMS(const char** name_ptr)) {
GET_ORIGINAL_HOOKED_FUNCTION(VStdLib_Callback_Interceptor)
VStdLib_Callback_Interceptor_o(ARGS(name_ptr));
VIRTUAL(void) VStdLib_Callback_Interceptor(PARAMS(const char** name_ptr)
) {
GET_ORIGINAL_HOOKED_FUNCTION(VStdLib_Callback_Interceptor)
VStdLib_Callback_Interceptor_o(ARGS(name_ptr));
static auto lock_status_hooked = false;
static auto stop_playing_hooked = false;
static auto lock_status_hooked = false;
static auto stop_playing_hooked = false;
if (lock_status_hooked && stop_playing_hooked) {
return;
}
if (
lock_status_hooked&& stop_playing_hooked
) {
return;
}
auto* const data = (CoroutineData*) THIS;
auto* const data = (CoroutineData*) THIS;
if (data && data->get_callback_name()) {
const auto name = String(data->get_callback_name());
LOG_TRACE("{} -> instance: {}, name: '{}'", __func__, fmt::ptr(THIS), name)
if (
data&& data
->
get_callback_name()
) {
const auto name = String(data->get_callback_name());
LOG_TRACE("{}(ecx={}, edx={}, name={})", __func__, ARGS(), name)
if (name == "SharedLicensesLockStatus" && !lock_status_hooked) {
DETOUR_ADDRESS(SharedLicensesLockStatus, data->get_callback_data()->get_callback_address())

View File

@@ -15,11 +15,11 @@ constexpr auto KEY_APPS = "apps";
Apps get_cached_apps() {
try {
const auto cache = koalabox::cache::read_from_cache(KEY_APPS).value();
const auto cache = koalabox::cache::read_from_cache(KEY_APPS);
return cache.get<Apps>();
} catch (const Exception& e) {
LOG_WARN("{} -> Failed to get cached apps: {}", __func__, e.what())
LOG_WARN("Failed to get cached apps: {}", e.what())
return {};
}
@@ -29,7 +29,7 @@ namespace smoke_api::app_cache {
Vector<AppId_t> get_dlc_ids(AppId_t app_id) {
try {
LOG_DEBUG("{} -> Reading cached DLC IDs for the app: {}", __func__, app_id)
LOG_DEBUG("Reading cached DLC IDs for the app: {}", app_id)
const auto app = get_cached_apps().at(std::to_string(app_id));
@@ -41,7 +41,7 @@ namespace smoke_api::app_cache {
bool save_dlc_ids(AppId_t app_id, const Vector<AppId_t>& dlc_ids) {
try {
LOG_DEBUG("{} -> Caching DLC IDs for the app: {}", __func__, app_id)
LOG_DEBUG("Caching DLC IDs for the app: {}", app_id)
auto apps = get_cached_apps();
@@ -49,9 +49,9 @@ namespace smoke_api::app_cache {
.dlc_ids = dlc_ids
};
return koalabox::cache::save_to_cache(KEY_APPS, apps);
return koalabox::cache::save_to_cache(KEY_APPS, Json(apps));
} catch (const Exception& e) {
LOG_ERROR("{} -> Failed to cache DLC IDs fro the app: {}", __func__, app_id)
LOG_ERROR("Failed to cache DLC IDs fro the app: {}", app_id)
return false;
}

View File

@@ -4,16 +4,15 @@
#include <core/globals.hpp>
#include <core/paths.hpp>
#include <steam_functions/steam_functions.hpp>
#include <koalabox/config_parser.hpp>
#include <koalabox/dll_monitor.hpp>
#include <koalabox/logger.hpp>
#include <koalabox/hook.hpp>
#include <koalabox/cache.hpp>
#include <koalabox/loader.hpp>
#include <koalabox/win_util.hpp>
#include <koalabox/util.hpp>
// TODO: Define COMPILE_KOALAGEDDON in CMake
#ifndef _WIN64
#if COMPILE_KOALAGEDDON
#include <koalageddon/koalageddon.hpp>
#endif
@@ -56,7 +55,7 @@ void init_hook_mode() {
}
bool is_valve_steam(const String& exe_name) {
if (not koalabox::util::strings_are_equal(exe_name, "steam.exe")) {
if (exe_name < not_equals > "steam.exe") {
return false;
}
@@ -71,7 +70,7 @@ bool is_valve_steam(const String& exe_name) {
}
// Steam.exe manifest is expected to contain this string
return manifest->find("valvesoftware.steam.steam") != String::npos;
return *manifest < contains > "valvesoftware.steam.steam";
}
namespace smoke_api {
@@ -90,18 +89,18 @@ namespace smoke_api {
koalabox::logger::init_file_logger(paths::get_log_path());
}
LOG_INFO("🐨 {} v{}", PROJECT_NAME, PROJECT_VERSION)
LOG_INFO("🐨 {} v{} | Compiled at '{}'", PROJECT_NAME, PROJECT_VERSION, __TIMESTAMP__)
const auto exe_path = Path(koalabox::win_util::get_module_file_name_or_throw(nullptr));
const auto exe_name = exe_path.filename().string();
LOG_DEBUG(R"(Process name: "{}" [{}-bit])", exe_name, BITNESS)
LOG_DEBUG("Process name: '{}' [{}-bit]", exe_name, BITNESS)
if (koalabox::hook::is_hook_mode(globals::smokeapi_handle, STEAMAPI_DLL)) {
koalabox::hook::init(true);
if (is_valve_steam(exe_name)) {
#ifndef _WIN64
#if COMPILE_KOALAGEDDON
LOG_INFO("🐨💥 Detected Koalageddon mode")
koalageddon::init();
#endif

View File

@@ -1,5 +1,4 @@
#include <steam_functions/steam_functions.hpp>
#include <koalageddon/steamclient.hpp>
#include <build_config.h>
#include <koalabox/hook.hpp>
#include <koalabox/win_util.hpp>
@@ -7,6 +6,10 @@
#include <koalabox/util.hpp>
#include <polyhook2/Misc.hpp>
#if COMPILE_KOALAGEDDON
#include <koalageddon/steamclient.hpp>
#endif
namespace steam_functions {
typedef Map<String, Map<int, int>> FunctionOrdinalMap;
@@ -195,8 +198,7 @@ namespace steam_functions {
HOOK_STEAM_INVENTORY(ISteamInventory_GetResultItemProperty)
}
} else if (version_string.starts_with(CLIENT_ENGINE)) {
// Koalageddon mode
#ifndef _WIN64
#if COMPILE_KOALAGEDDON
koalageddon::steamclient::process_client_engine(reinterpret_cast<uintptr_t>(interface));
#endif
} else {

View File

@@ -3,7 +3,6 @@
#include <core/macros.hpp>
#include <core/types.hpp>
// TODO: Refactor into multiple headers
// ISteamClient

View File

@@ -8,6 +8,27 @@
#include <core/types.hpp>
namespace steam_apps {
// TODO: Needs to go to API
class DLC {
private:
String appid;
public:
String name;
uint32_t app_id = std::stoi(appid);
NLOHMANN_DEFINE_TYPE_INTRUSIVE(DLC, appid, name)
};
struct SteamResponse {
uint32_t success = 0;
Vector<DLC> dlcs;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(SteamResponse, success, dlcs)
};
using GitHubResponse = Map<String, Vector<uint32_t>>;
/// Steamworks may max GetDLCCount value at 64, depending on how much unowned DLCs the user has.
/// Despite this limit, some games with more than 64 DLCs still keep using this method.
/// This means we have to get extra DLC IDs from local config, remote config, or cache.
@@ -43,14 +64,14 @@ namespace steam_apps {
// TODO: Refactor into api namespace
const auto url = fmt::format("https://store.steampowered.com/dlc/{}/ajaxgetdlclist", app_id_str);
const auto json = koalabox::http_client::fetch_json(url);
const auto response = json.get<SteamResponse>();
if (json["success"] != 1) {
throw koalabox::util::exception("Web API responded with 'success' != 1");
if (response.success != 1) {
throw std::runtime_error("Web API responded with 'success' != 1");
}
for (const auto& dlc: json["dlcs"]) {
const auto app_id = dlc["appid"].get<String>();
dlcs.emplace_back(std::stoi(app_id));
for (const auto& dlc: response.dlcs) {
dlcs.emplace_back(dlc.app_id);
}
} catch (const Exception& e) {
LOG_ERROR("Failed to fetch dlc list from steam api: {}", e.what())
@@ -66,9 +87,10 @@ namespace steam_apps {
try {
const String url = "https://raw.githubusercontent.com/acidicoala/public-entitlements/main/steam/v1/dlc.json";
const auto json = koalabox::http_client::fetch_json(url);
const auto response = json.get<GitHubResponse>();
if (json.contains(app_id_str)) {
dlcs = json[app_id_str].get<decltype(dlcs)>();
if (response.contains(app_id_str)) {
dlcs = response.at(app_id_str);
}
} catch (const Exception& e) {
LOG_ERROR("Failed to fetch extra dlc list from github api: {}", e.what())
@@ -102,7 +124,7 @@ namespace steam_apps {
}
String get_app_id_log(const AppId_t app_id) {
return app_id ? fmt::format("App ID: {}, ", app_id) : "";
return app_id ? fmt::format("App ID: {:>8}, ", app_id) : "";
}
bool IsDlcUnlocked(
@@ -114,11 +136,11 @@ namespace steam_apps {
try {
const auto unlocked = config::is_dlc_unlocked(app_id, dlc_id, original_function);
LOG_INFO("{} -> {}DLC ID: {}, 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;
} catch (const Exception& e) {
LOG_ERROR("{} -> Uncaught exception: {}", function_name, e.what())
LOG_ERROR("Uncaught exception: {}", e.what())
return false;
}
}
@@ -165,7 +187,7 @@ namespace steam_apps {
return total_count(injected_count + cached_count);
} catch (const Exception& e) {
LOG_ERROR("{} -> Uncaught exception: {}", function_name, e.what())
LOG_ERROR(" Uncaught exception: {}", function_name, e.what())
return 0;
}
}
@@ -183,7 +205,7 @@ namespace steam_apps {
try {
const auto print_dlc_info = [&](const String& tag) {
LOG_INFO(
"{} -> [{}] {}index: {}, DLC ID: {}, available: {}, name: '{}'",
"{} -> [{:12}] {}index: {:>3}, DLC ID: {:>8}, available: {:5}, name: '{}'",
function_name, tag, get_app_id_log(app_id), iDLC, *pDlcId, *pbAvailable, pchName
)
};

View File

@@ -12,7 +12,7 @@ namespace steam_user {
const auto result = original_function();
if (result == k_EUserHasLicenseResultNoAuth) {
LOG_WARN("{} -> App ID: {}, Result: NoAuth", function_name, appID)
LOG_WARN("{} -> App ID: {:>8}, Result: NoAuth", function_name, appID)
return result;
}
@@ -22,7 +22,7 @@ namespace steam_user {
}
);
LOG_INFO("{} -> App ID: {}, HasLicense: {}", function_name, appID, has_license)
LOG_INFO("{} -> App ID: {:>8}, HasLicense: {}", function_name, appID, has_license)
return has_license
? k_EUserHasLicenseResultHasLicense