You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
SmokeAPI/src/core/types.hpp

141 lines
4.7 KiB
C++

#pragma once
#include <nlohmann/json.hpp>
#include <core/globals.hpp>
#include <koalabox/core.hpp>
#include <koalabox/hook.hpp>
#include <koalabox/logger.hpp>
/**
* By default, virtual functions are declared with __thiscall
* convention, which is normal since they are class members.
* But it presents an issue for us, since we cannot pass *this
* pointer as a function argument. This is because *this
* pointer is passed via register ECX in __thiscall
* convention. Hence, to resolve this issue we declare our
* hooked functions with __fastcall convention, to trick
* the compiler into reading ECX & EDX registers as 1st
* and 2nd function arguments respectively. Similarly, __fastcall
* makes the compiler push the first argument into the ECX register,
* which mimics the __thiscall calling convention. Register EDX
* is not used anywhere in this case, but we still pass it along
* to conform to the __fastcall convention. This all applies
* to the x86 architecture.
*
* In x86-64 however, there is only one calling convention,
* so __fastcall is simply ignored. However, RDX in this case
* will store_mode the 1st actual argument to the function, so we
* have to omit it from the function signature.
*
* The macros below implement the above-mentioned considerations.
*/
#ifdef _WIN64
#define PARAMS(...) void* RCX, __VA_ARGS__
#define ARGS(...) RCX, __VA_ARGS__
#define THIS RCX
#else
#define PARAMS(...) const void* ECX, const void* EDX, __VA_ARGS__
#define ARGS(...) ECX, EDX, __VA_ARGS__
#define THIS ECX
#endif
// Names beginning with $ designate macros that are not meant to be used directly by the sources consuming this file
#define DLL_EXPORT(TYPE) extern "C" [[maybe_unused]] __declspec( dllexport ) TYPE __cdecl
#define VIRTUAL(TYPE) __declspec(noinline) TYPE __fastcall
#define GET_ORIGINAL_HOOKED_FUNCTION(FUNC) \
static const auto FUNC##_o = koalabox::hook::get_original_hooked_function(globals::address_map, #FUNC, FUNC);
#define GET_ORIGINAL_FUNCTION_STEAMAPI(FUNC) \
static const auto FUNC##_o = koalabox::hook::get_original_function(globals::steamapi_module, #FUNC, FUNC);
#define DETOUR_ADDRESS(FUNC, ADDRESS) \
koalabox::hook::detour_or_warn(globals::address_map, ADDRESS, #FUNC, reinterpret_cast<uintptr_t>(FUNC));
#define $DETOUR(FUNC, NAME, MODULE_HANDLE) \
koalabox::hook::detour_or_warn(globals::address_map, MODULE_HANDLE, NAME, reinterpret_cast<uintptr_t>(FUNC));
#define DETOUR_STEAMCLIENT(FUNC) $DETOUR(FUNC, #FUNC, globals::steamclient_module)
#define DETOUR_VSTDLIB(FUNC) $DETOUR(vstdlib::FUNC, #FUNC, globals::vstdlib_module)
#ifdef _WIN64
#define COMPILE_STORE_MODE 0
#else
#define COMPILE_STORE_MODE 1
#endif
constexpr auto STEAM_APPS = "STEAMAPPS_INTERFACE_VERSION";
constexpr auto STEAM_CLIENT = "SteamClient";
constexpr auto STEAM_USER = "SteamUser";
constexpr auto STEAM_INVENTORY = "STEAMINVENTORY_INTERFACE_V";
constexpr auto CLIENT_ENGINE = "CLIENTENGINE_INTERFACE_VERSION";
using AppId_t = uint32_t;
using SteamInventoryResult_t = uint32_t;
using SteamItemInstanceID_t = uint64_t;
using SteamItemDef_t = uint32_t;
using HSteamPipe = uint32_t;
using HSteamUser = uint32_t;
using CSteamID = uint64_t;
using EResult = uint32_t;
struct SteamItemDetails_t {
SteamItemInstanceID_t m_itemId;
uint32_t m_iDefinition;
uint16_t m_unQuantity;
uint16_t m_unFlags; // see ESteamItemFlags
};
// results from UserHasLicenseForApp
enum EUserHasLicenseForAppResult {
k_EUserHasLicenseResultHasLicense = 0, // User has a license for specified app
k_EUserHasLicenseResultDoesNotHaveLicense = 1, // User does not have a license for the specified app
k_EUserHasLicenseResultNoAuth = 2, // User has not been authenticated
};
// These aliases exist solely to increase code readability
using AppIdKey = String;
using DlcIdKey = String;
using DlcNameValue = String;
using DlcNameMap = Map<DlcIdKey, DlcNameValue>;
struct App {
DlcNameMap dlcs;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(App, dlcs) // NOLINT(misc-const-correctness)
};
using AppDlcNameMap = Map<AppIdKey, App>;
class DLC {
private:
// These 2 names must match the property names from Steam API
String appid;
String name;
public:
explicit DLC() = default;
explicit DLC(String appid, String name) : appid{std::move(appid)}, name{std::move(name)} {}
[[nodiscard]] String get_id_str() const {
return appid;
};
[[nodiscard]] uint32_t get_id() const {
return std::stoi(appid);
};
[[nodiscard]] String get_name() const {
return name;
};
NLOHMANN_DEFINE_TYPE_INTRUSIVE(DLC, appid, name)
static Vector<DLC> get_dlcs_from_apps(const AppDlcNameMap& apps, AppId_t app_id);
static DlcNameMap get_dlc_map_from_vector(const Vector<DLC>& vector);
};