#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 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(method)(this->interface_ptr_, args...); } template T invoke(const size_t table_entry, Args ... args) { if (!this->interface_ptr_) { throw std::runtime_error("Invalid interface pointer"); } return static_cast((*this->interface_ptr_)[table_entry])( this->interface_ptr_, args...); } private: void*** interface_ptr_; std::unordered_map methods_; void* find_method(const std::string& name); void* search_method(const std::string& name); std::string analyze_method(const void* method_ptr); }; }