86 lines
1.7 KiB
C++
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);
|
|
};
|
|
}
|