* change return type of all client functions from bool to steam_bool to avoid inconsistency problem in the client library

* implement missing client functions
  - `Breakpad_SteamSendMiniDump()`
  - `Steam_IsKnownInterface()`
  - `Steam_NotifyMissingInterface()`
This commit is contained in:
a 2024-08-21 21:37:54 +03:00
parent f8c18b52e2
commit 4b9f88d8ec
6 changed files with 301 additions and 19 deletions

View File

@ -0,0 +1,228 @@
#include "dll/client_known_interfaces.h"
/*
the client function Steam_IsKnownInterface() accesses a structure which has this layout:
typedef struct struct_known_interfaces {
void *unknown_function_ptr;
const char *name; // ex: "STEAMAPPLIST_INTERFACE_VERSION001"
const char *family; // ex: "AppList"
struct_known_interfaces *previous_node;
};
this is a dump of the `name` field when running this function from a debugger
*/
extern const std::unordered_set<std::string> client_known_interfaces = {
"SteamAppDisableUpdate001",
"STEAMAPPLIST_INTERFACE_VERSION001",
"SteamApps001",
"STEAMAPPS_INTERFACE_VERSION001",
"STEAMAPPS_INTERFACE_VERSION002",
"STEAMAPPS_INTERFACE_VERSION003",
"STEAMAPPS_INTERFACE_VERSION004",
"STEAMAPPS_INTERFACE_VERSION005",
"STEAMAPPS_INTERFACE_VERSION006",
"STEAMAPPS_INTERFACE_VERSION007",
"STEAMAPPS_INTERFACE_VERSION008",
"STEAMAPPTICKET_INTERFACE_VERSION001",
"SteamBilling002",
"STEAMCHAT_INTERFACE_VERSION003",
"SteamController003",
"SteamController004",
"SteamController005",
"SteamController006",
"SteamController007",
"SteamController008",
"STEAMCONTROLLER_INTERFACE_VERSION",
"SteamFriends001",
"SteamFriends002",
"SteamFriends003",
"SteamFriends004",
"SteamFriends005",
"SteamFriends006",
"SteamFriends007",
"SteamFriends008",
"SteamFriends009",
"SteamFriends010",
"SteamFriends011",
"SteamFriends012",
"SteamFriends013",
"SteamFriends014",
"SteamFriends015",
"SteamFriends016",
"SteamFriends017",
"SteamGameCoordinator001",
"SteamGameServer002",
"SteamGameServer003",
"SteamGameServer004",
"SteamGameServer005",
"SteamGameServer006",
"SteamGameServer007",
"SteamGameServer008",
"SteamGameServer009",
"SteamGameServer010",
"SteamGameServer011",
"SteamGameServer012",
"SteamGameServer013",
"SteamGameServer014",
"SteamGameServer015",
"SteamGameServerStats001",
"SteamGameStats001",
"STEAMHTMLSURFACE_INTERFACE_VERSION_001",
"STEAMHTMLSURFACE_INTERFACE_VERSION_002",
"STEAMHTMLSURFACE_INTERFACE_VERSION_003",
"STEAMHTMLSURFACE_INTERFACE_VERSION_004",
"STEAMHTMLSURFACE_INTERFACE_VERSION_005",
"STEAMHTTP_INTERFACE_VERSION001",
"STEAMHTTP_INTERFACE_VERSION002",
"STEAMHTTP_INTERFACE_VERSION003",
"SteamInput001",
"SteamInput002",
"SteamInput003",
"SteamInput004",
"SteamInput005",
"SteamInput006",
"STEAMINVENTORY_INTERFACE_V001",
"STEAMINVENTORY_INTERFACE_V002",
"STEAMINVENTORY_INTERFACE_V003",
"SteamMasterServerUpdater001",
"SteamMatchGameSearch001",
"SteamMatchMaking001",
"SteamMatchMaking002",
"SteamMatchMaking003",
"SteamMatchMaking004",
"SteamMatchMaking005",
"SteamMatchMaking006",
"SteamMatchMaking007",
"SteamMatchMaking008",
"SteamMatchMaking009",
"SteamMatchMakingServers001",
"SteamMatchMakingServers002",
"STEAMMUSIC_INTERFACE_VERSION001",
"STEAMMUSICREMOTE_INTERFACE_VERSION001",
"SteamNetworking001",
"SteamNetworking002",
"SteamNetworking003",
"SteamNetworking004",
"SteamNetworking005",
"SteamNetworking006",
"SteamNetworkingMessages002",
"SteamNetworkingSockets002",
"SteamNetworkingSockets003",
"SteamNetworkingSockets004",
"SteamNetworkingSockets005",
"SteamNetworkingSockets006",
"SteamNetworkingSockets008",
"SteamNetworkingSockets009",
"SteamNetworkingSockets010",
"SteamNetworkingSockets011",
"SteamNetworkingSockets012",
"SteamNetworkingSocketsSerialized001",
"SteamNetworkingSocketsSerialized002",
"SteamNetworkingSocketsSerialized003",
"SteamNetworkingSocketsSerialized004",
"SteamNetworkingSocketsSerialized005",
"SteamNetworkingUtils001",
"SteamNetworkingUtils002",
"SteamNetworkingUtils003",
"SteamNetworkingUtils004",
"STEAMPARENTALSETTINGS_INTERFACE_VERSION001",
"SteamParties001",
"SteamParties002",
"STEAMREMOTEPLAY_INTERFACE_VERSION001",
"STEAMREMOTEPLAY_INTERFACE_VERSION002",
"STEAMREMOTESTORAGE_INTERFACE_VERSION001",
"STEAMREMOTESTORAGE_INTERFACE_VERSION002",
"STEAMREMOTESTORAGE_INTERFACE_VERSION003",
"STEAMREMOTESTORAGE_INTERFACE_VERSION004",
"STEAMREMOTESTORAGE_INTERFACE_VERSION005",
"STEAMREMOTESTORAGE_INTERFACE_VERSION006",
"STEAMREMOTESTORAGE_INTERFACE_VERSION007",
"STEAMREMOTESTORAGE_INTERFACE_VERSION008",
"STEAMREMOTESTORAGE_INTERFACE_VERSION009",
"STEAMREMOTESTORAGE_INTERFACE_VERSION010",
"STEAMREMOTESTORAGE_INTERFACE_VERSION011",
"STEAMREMOTESTORAGE_INTERFACE_VERSION012",
"STEAMREMOTESTORAGE_INTERFACE_VERSION013",
"STEAMREMOTESTORAGE_INTERFACE_VERSION014",
"STEAMREMOTESTORAGE_INTERFACE_VERSION015",
"STEAMREMOTESTORAGE_INTERFACE_VERSION016",
"STEAMSCREENSHOTS_INTERFACE_VERSION001",
"STEAMSCREENSHOTS_INTERFACE_VERSION002",
"STEAMSCREENSHOTS_INTERFACE_VERSION003",
"SteamStreamLauncher001",
"STEAMTIMELINE_INTERFACE_V001",
"STEAMTV_INTERFACE_V001",
"STEAMTV_INTERFACE_V002",
"STEAMUGC_INTERFACE_VERSION001",
"STEAMUGC_INTERFACE_VERSION002",
"STEAMUGC_INTERFACE_VERSION003",
"STEAMUGC_INTERFACE_VERSION004",
"STEAMUGC_INTERFACE_VERSION005",
"STEAMUGC_INTERFACE_VERSION006",
"STEAMUGC_INTERFACE_VERSION007",
"STEAMUGC_INTERFACE_VERSION008",
"STEAMUGC_INTERFACE_VERSION009",
"STEAMUGC_INTERFACE_VERSION010",
"STEAMUGC_INTERFACE_VERSION011",
"STEAMUGC_INTERFACE_VERSION012",
"STEAMUGC_INTERFACE_VERSION013",
"STEAMUGC_INTERFACE_VERSION014",
"STEAMUGC_INTERFACE_VERSION015",
"STEAMUGC_INTERFACE_VERSION016",
"STEAMUGC_INTERFACE_VERSION017",
"STEAMUGC_INTERFACE_VERSION018",
"STEAMUGC_INTERFACE_VERSION019",
"STEAMUGC_INTERFACE_VERSION020",
"STEAMUNIFIEDMESSAGES_INTERFACE_VERSION001",
"SteamUser004",
"SteamUser005",
"SteamUser006",
"SteamUser007",
"SteamUser008",
"SteamUser009",
"SteamUser010",
"SteamUser011",
"SteamUser012",
"SteamUser013",
"SteamUser014",
"SteamUser015",
"SteamUser016",
"SteamUser017",
"SteamUser018",
"SteamUser019",
"SteamUser020",
"SteamUser021",
"SteamUser022",
"SteamUser023",
"STEAMUSERSTATS_INTERFACE_VERSION001",
"STEAMUSERSTATS_INTERFACE_VERSION002",
"STEAMUSERSTATS_INTERFACE_VERSION003",
"STEAMUSERSTATS_INTERFACE_VERSION004",
"STEAMUSERSTATS_INTERFACE_VERSION005",
"STEAMUSERSTATS_INTERFACE_VERSION006",
"STEAMUSERSTATS_INTERFACE_VERSION007",
"STEAMUSERSTATS_INTERFACE_VERSION008",
"STEAMUSERSTATS_INTERFACE_VERSION009",
"STEAMUSERSTATS_INTERFACE_VERSION010",
"STEAMUSERSTATS_INTERFACE_VERSION011",
"STEAMUSERSTATS_INTERFACE_VERSION012",
"SteamUtils001",
"SteamUtils002",
"SteamUtils003",
"SteamUtils004",
"SteamUtils005",
"SteamUtils006",
"SteamUtils007",
"SteamUtils008",
"SteamUtils009",
"SteamUtils010",
"STEAMVIDEO_INTERFACE_V001",
"STEAMVIDEO_INTERFACE_V002",
"STEAMVIDEO_INTERFACE_V003",
"STEAMVIDEO_INTERFACE_V004",
"STEAMVIDEO_INTERFACE_V005",
"STEAMVIDEO_INTERFACE_V006",
"STEAMVIDEO_INTERFACE_V007",
};

View File

@ -18,6 +18,7 @@
#define STEAM_API_FUNCTIONS_IMPL
#include "dll/dll.h"
#include "dll/settings_parser.h"
#include "dll/client_known_interfaces.h"
static char old_client[128] = STEAMCLIENT_INTERFACE_VERSION; //"SteamClient017";
@ -1320,7 +1321,7 @@ STEAMCLIENT_API steam_bool Steam_BGetCallback( HSteamPipe hSteamPipe, CallbackMs
STEAMCLIENT_API void Steam_FreeLastCallback( HSteamPipe hSteamPipe )
{
PRINT_DEBUG("Steam_FreeLastCallback %i", hSteamPipe);
PRINT_DEBUG("%i", hSteamPipe);
SteamAPI_ManualDispatch_FreeLastCallback( hSteamPipe );
}
@ -1347,6 +1348,11 @@ STEAMCLIENT_API void Breakpad_SteamMiniDumpInit( uint32 a, const char *b, const
PRINT_DEBUG_TODO();
}
STEAMCLIENT_API void Breakpad_SteamSendMiniDump( void *a, uint32 b )
{
PRINT_DEBUG_TODO();
}
STEAMCLIENT_API void Breakpad_SteamSetAppID( uint32 unAppID )
{
PRINT_DEBUG_TODO();
@ -1369,19 +1375,19 @@ STEAMCLIENT_API void Breakpad_SteamWriteMiniDumpUsingExceptionInfoWithBuildId( i
PRINT_DEBUG(" app is writing a crash dump! [XXXXXXXXXXXXXXXXXXXXXXXXXXX]");
}
STEAMCLIENT_API bool Steam_BConnected( HSteamUser hUser, HSteamPipe hSteamPipe )
STEAMCLIENT_API steam_bool Steam_BConnected( HSteamUser hUser, HSteamPipe hSteamPipe )
{
PRINT_DEBUG_ENTRY();
return true;
}
STEAMCLIENT_API bool Steam_BLoggedOn( HSteamUser hUser, HSteamPipe hSteamPipe )
STEAMCLIENT_API steam_bool Steam_BLoggedOn( HSteamUser hUser, HSteamPipe hSteamPipe )
{
PRINT_DEBUG_ENTRY();
return true;
}
STEAMCLIENT_API bool Steam_BReleaseSteamPipe( HSteamPipe hSteamPipe )
STEAMCLIENT_API steam_bool Steam_BReleaseSteamPipe( HSteamPipe hSteamPipe )
{
PRINT_DEBUG_TODO();
return false;
@ -1411,19 +1417,19 @@ STEAMCLIENT_API HSteamPipe Steam_CreateSteamPipe()
return 0;
}
STEAMCLIENT_API bool Steam_GSBLoggedOn( void *phSteamHandle )
STEAMCLIENT_API steam_bool Steam_GSBLoggedOn( void *phSteamHandle )
{
PRINT_DEBUG_TODO();
return false;
}
STEAMCLIENT_API bool Steam_GSBSecure( void *phSteamHandle)
STEAMCLIENT_API steam_bool Steam_GSBSecure( void *phSteamHandle)
{
PRINT_DEBUG_TODO();
return false;
}
STEAMCLIENT_API bool Steam_GSGetSteam2GetEncryptionKeyToSendToNewClient( void *phSteamHandle, void *pvEncryptionKey, uint32 *pcbEncryptionKey, uint32 cbMaxEncryptionKey )
STEAMCLIENT_API steam_bool Steam_GSGetSteam2GetEncryptionKeyToSendToNewClient( void *phSteamHandle, void *pvEncryptionKey, uint32 *pcbEncryptionKey, uint32 cbMaxEncryptionKey )
{
PRINT_DEBUG_TODO();
return false;
@ -1445,37 +1451,37 @@ STEAMCLIENT_API void Steam_GSLogOn( void *phSteamHandle )
PRINT_DEBUG_TODO();
}
STEAMCLIENT_API bool Steam_GSRemoveUserConnect( void *phSteamHandle, uint32 unUserID )
STEAMCLIENT_API steam_bool Steam_GSRemoveUserConnect( void *phSteamHandle, uint32 unUserID )
{
PRINT_DEBUG_TODO();
return false;
}
STEAMCLIENT_API bool Steam_GSSendSteam2UserConnect( void *phSteamHandle, uint32 unUserID, const void *pvRawKey, uint32 unKeyLen, uint32 unIPPublic, uint16 usPort, const void *pvCookie, uint32 cubCookie )
STEAMCLIENT_API steam_bool Steam_GSSendSteam2UserConnect( void *phSteamHandle, uint32 unUserID, const void *pvRawKey, uint32 unKeyLen, uint32 unIPPublic, uint16 usPort, const void *pvCookie, uint32 cubCookie )
{
PRINT_DEBUG_TODO();
return false;
}
STEAMCLIENT_API bool Steam_GSSendSteam3UserConnect( void *phSteamHandle, uint64 steamID, uint32 unIPPublic, const void *pvCookie, uint32 cubCookie )
STEAMCLIENT_API steam_bool Steam_GSSendSteam3UserConnect( void *phSteamHandle, uint64 steamID, uint32 unIPPublic, const void *pvCookie, uint32 cubCookie )
{
PRINT_DEBUG_TODO();
return false;
}
STEAMCLIENT_API bool Steam_GSSendUserDisconnect( void *phSteamHandle, uint64 ulSteamID, uint32 unUserID )
STEAMCLIENT_API steam_bool Steam_GSSendUserDisconnect( void *phSteamHandle, uint64 ulSteamID, uint32 unUserID )
{
PRINT_DEBUG_TODO();
return false;
}
STEAMCLIENT_API bool Steam_GSSendUserStatusResponse( void *phSteamHandle, uint64 ulSteamID, int nSecondsConnected, int nSecondsSinceLast )
STEAMCLIENT_API steam_bool Steam_GSSendUserStatusResponse( void *phSteamHandle, uint64 ulSteamID, int nSecondsConnected, int nSecondsSinceLast )
{
PRINT_DEBUG_TODO();
return false;
}
STEAMCLIENT_API bool Steam_GSSetServerType( void *phSteamHandle, int32 nAppIdServed, uint32 unServerFlags, uint32 unGameIP, uint32 unGamePort, const char *pchGameDir, const char *pchVersion )
STEAMCLIENT_API steam_bool Steam_GSSetServerType( void *phSteamHandle, int32 nAppIdServed, uint32 unServerFlags, uint32 unGameIP, uint32 unGamePort, const char *pchGameDir, const char *pchVersion )
{
PRINT_DEBUG_TODO();
return false;
@ -1486,7 +1492,7 @@ STEAMCLIENT_API void Steam_GSSetSpawnCount( void *phSteamHandle, uint32 ucSpawn
PRINT_DEBUG_TODO();
}
STEAMCLIENT_API bool Steam_GSUpdateStatus( void *phSteamHandle, int cPlayers, int cPlayersMax, int cBotPlayers, const char *pchServerName, const char *pchMapName )
STEAMCLIENT_API steam_bool Steam_GSUpdateStatus( void *phSteamHandle, int cPlayers, int cPlayersMax, int cBotPlayers, const char *pchServerName, const char *pchMapName )
{
PRINT_DEBUG_TODO();
return false;
@ -1495,7 +1501,7 @@ STEAMCLIENT_API bool Steam_GSUpdateStatus( void *phSteamHandle, int cPlayers, in
STEAMCLIENT_API void* Steam_GetGSHandle( HSteamUser hUser, HSteamPipe hSteamPipe )
{
PRINT_DEBUG_TODO();
return NULL;
return nullptr;
}
STEAMCLIENT_API int Steam_InitiateGameConnection( HSteamUser hUser, HSteamPipe hSteamPipe, void *pBlob, int cbMaxBlob, uint64 steamID, int nGameAppID, uint32 unIPServer, uint16 usPortServer, bool bSecure )
@ -1504,6 +1510,24 @@ STEAMCLIENT_API int Steam_InitiateGameConnection( HSteamUser hUser, HSteamPipe h
return 0;
}
// https://github.com/ValveSoftware/Proton/blob/962bbc4e74dde0643a6edab7c845bc628601f23f/lsteamclient/steamclient_main.c#L579-L586
STEAMCLIENT_API steam_bool Steam_IsKnownInterface( const char *pchVersion )
{
PRINT_DEBUG("'%s'", pchVersion);
// real client doesn't validate if the arg was null
if (!pchVersion) return false;
bool found = client_known_interfaces.count(pchVersion);
PRINT_DEBUG(" result=%i", (int)found);
if (!found) {
get_steam_client()->report_missing_impl(pchVersion, EMU_FUNC_NAME);
}
return found;
}
STEAMCLIENT_API void Steam_LogOff( HSteamUser hUser, HSteamPipe hSteamPipe )
{
PRINT_DEBUG_TODO();
@ -1514,6 +1538,13 @@ STEAMCLIENT_API void Steam_LogOn( HSteamUser hUser, HSteamPipe hSteamPipe, uint6
PRINT_DEBUG_TODO();
}
// https://github.com/ValveSoftware/Proton/blob/962bbc4e74dde0643a6edab7c845bc628601f23f/lsteamclient/steamclient_main.c#L588-L594
STEAMCLIENT_API void Steam_NotifyMissingInterface(HSteamPipe hSteamPipe, const char *pchVersion )
{
PRINT_DEBUG("XXXXXXXXXXXXX '%s' %i", pchVersion, hSteamPipe);
get_steam_client()->report_missing_impl(pchVersion, EMU_FUNC_NAME);
}
STEAMCLIENT_API void Steam_ReleaseThreadLocalMemory(bool thread_exit)
{
PRINT_DEBUG_TODO();

View File

@ -0,0 +1,9 @@
#ifndef _CLIENT_KNOWN_INTERFACES_H_
#define _CLIENT_KNOWN_INTERFACES_H_
#include <unordered_set>
#include <string>
extern const std::unordered_set<std::string> client_known_interfaces;
#endif // _CLIENT_KNOWN_INTERFACES_H_

View File

@ -338,6 +338,7 @@ public:
void DestroyAllInterfaces();
void report_missing_impl(std::string_view itf, std::string_view caller);
[[noreturn]] void report_missing_impl_and_exit(std::string_view itf, std::string_view caller);
};

View File

@ -3,7 +3,7 @@
// https://developer.valvesoftware.com/wiki/Steam_Application_IDs
// https://developer.valvesoftware.com/wiki/Dedicated_Servers_List
// they're not really accurate
const std::map<uint32, std::string> steam_preowned_app_ids = {
extern const std::map<uint32, std::string> steam_preowned_app_ids = {
// { 0, "Base Goldsource Shared Binaries" },
// { 1, "Base Goldsource Shared Content" },

View File

@ -938,7 +938,7 @@ ISteamAppTicket *Steam_Client::GetAppTicket( HSteamUser hSteamUser, HSteamPipe h
report_missing_impl_and_exit(pchVersion, EMU_FUNC_NAME);
}
void Steam_Client::report_missing_impl_and_exit(std::string_view itf, std::string_view caller)
void Steam_Client::report_missing_impl(std::string_view itf, std::string_view caller)
{
PRINT_DEBUG("'%s' '%s'", itf.data(), caller.data());
std::lock_guard lck(global_mutex);
@ -947,18 +947,27 @@ void Steam_Client::report_missing_impl_and_exit(std::string_view itf, std::strin
try {
ss << "INTERFACE=" << itf << "\n";
ss << "CALLER FN=" << caller << "\n";
}
catch(...) { }
try {
if (settings_client) {
ss << "APPID=" << settings_client->get_local_game_id().AppID() << "\n";
}
}
catch(...) { }
try {
std::string time(common_helpers::get_utc_time());
if (time.size()) {
ss << "TIME=" << time << "\n";
}
ss << "--------------------\n" << std::endl;
}
catch(...) { }
try {
std::ofstream report(std::filesystem::u8path(get_full_program_path() + "EMU_MISSING_INTERFACE.txt"), std::ios::out | std::ios::app);
if (report.is_open()) {
report << ss.str();
@ -969,6 +978,10 @@ void Steam_Client::report_missing_impl_and_exit(std::string_view itf, std::strin
#if defined(__WINDOWS__)
MessageBoxA(nullptr, ss.str().c_str(), "Missing interface", MB_OK);
#endif
}
void Steam_Client::report_missing_impl_and_exit(std::string_view itf, std::string_view caller)
{
report_missing_impl(itf, caller);
std::exit(0x4155149); // MISSING :)
}