h1-mod/src/client/steam/interface.hpp
2022-02-03 11:05:24 -08:00

86 lines
1.7 KiB
C++

#pragma once
#ifdef interface
#undef interface
#endif
namespace steam
{
struct raw_steam_id final
{
unsigned int account_id : 32;
unsigned int account_instance : 20;
unsigned int account_type : 4;
int universe : 8;
};
typedef union
{
raw_steam_id raw;
unsigned long long bits;
} steam_id;
#pragma pack( push, 1 )
struct raw_game_id final
{
unsigned int app_id : 24;
unsigned int type : 8;
unsigned int mod_id : 32;
};
typedef union
{
raw_game_id raw;
unsigned long long bits;
} game_id;
#pragma pack( pop )
class interface final
{
public:
interface();
interface(void* interface_ptr);
operator bool() const;
template <typename T, typename... Args>
T invoke(const std::string& method_name, Args ... args)
{
if (!this->interface_ptr_)
{
throw std::runtime_error("Invalid interface pointer");
}
const auto method = this->find_method(method_name);
if (!method)
{
throw std::runtime_error("Unable to find method: " + method_name);
}
return static_cast<T(__thiscall*)(void*, Args ...)>(method)(this->interface_ptr_, args...);
}
template <typename T, typename... Args>
T invoke(const size_t table_entry, Args ... args)
{
if (!this->interface_ptr_)
{
throw std::runtime_error("Invalid interface pointer");
}
return static_cast<T(__thiscall*)(void*, Args ...)>((*this->interface_ptr_)[table_entry])(
this->interface_ptr_, args...);
}
private:
void*** interface_ptr_;
std::unordered_map<std::string, void*> methods_;
void* find_method(const std::string& name);
void* search_method(const std::string& name);
std::string analyze_method(const void* method_ptr);
};
}