From 367234ae645746723b800b86f988699ae99e148e Mon Sep 17 00:00:00 2001 From: M4RCK5 Date: Fri, 13 Sep 2024 15:12:27 -0300 Subject: [PATCH 1/7] Lobby Connect Improvements -Removed active user list to prioritize multiplayer lobbies -Fixed infinite loop when the user inputs letters instead of numbers -Clear output when refreshing lobby list --- tools/lobby_connect/lobby_connect.cpp | 214 ++++++++++++++------------ 1 file changed, 112 insertions(+), 102 deletions(-) diff --git a/tools/lobby_connect/lobby_connect.cpp b/tools/lobby_connect/lobby_connect.cpp index 3478f3b3..942aa991 100644 --- a/tools/lobby_connect/lobby_connect.cpp +++ b/tools/lobby_connect/lobby_connect.cpp @@ -31,9 +31,18 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include -#else - #endif + +void title() { + #ifdef _WIN32 + system("cls"); + #else + system("clear"); + #endif + + std::cout << "\n----Lobby Connect----\n\n"; +} + int main() { std::string appid_str(std::to_string(LOBBY_CONNECT_APPID)); set_env_variable("SteamAppId", appid_str); @@ -45,28 +54,20 @@ int main() { //Set appid to: LOBBY_CONNECT_APPID SteamAPI_RestartAppIfNecessary(LOBBY_CONNECT_APPID); - std::cout << "This is a program to find lobbies and run the game with lobby connect parameters" << std::endl; - std::cout << "Api initialized, "; -top: - std::cout << "waiting a few seconds for connections:" << std::endl; + + refresh: + title(); + std::cout << "Please wait...\n"; + for (int i = 0; i < 10; ++i) { SteamAPI_RunCallbacks(); std::this_thread::sleep_for(std::chrono::milliseconds(200)); } - + int friend_count = SteamFriends()->GetFriendCount(k_EFriendFlagAll); - std::cout << "People on the network: " << friend_count << std::endl; - for (int i = 0; i < friend_count; ++i) { - CSteamID id = SteamFriends()->GetFriendByIndex(i, k_EFriendFlagAll); - const char *name = SteamFriends()->GetFriendPersonaName(id); - - FriendGameInfo_t friend_info = {}; - SteamFriends()->GetFriendGamePlayed(id, &friend_info); - std::cout << name << " is playing: " << friend_info.m_gameID.AppID() << std::endl; - } - - std::cout << std::endl << "--------------Menu-------------" << std::endl << "\tappid\tname\tcommand line" << std::endl; - + + title(); + std::vector> arguments; for (int i = 0; i < friend_count; ++i) { CSteamID id = SteamFriends()->GetFriendByIndex(i, k_EFriendFlagAll); @@ -75,100 +76,109 @@ top: FriendGameInfo_t friend_info = {}; SteamFriends()->GetFriendGamePlayed(id, &friend_info); auto appid = friend_info.m_gameID.AppID(); - + if (strlen(connect) > 0) { - std::cout << arguments.size() << "\t" << appid << "\t" << name << "\t" << connect << std::endl; + std::cout << arguments.size() << " - " << name << " is playing " << appid << " (" << connect << ").\n"; arguments.emplace_back(connect, appid); } else { if (friend_info.m_steamIDLobby != k_steamIDNil) { std::string connect = "+connect_lobby " + std::to_string(friend_info.m_steamIDLobby.ConvertToUint64()); - std::cout << arguments.size() << "\t" << appid << "\t" << name << "\t" << connect << std::endl; + std::cout << arguments.size() << " - " << name << " is playing " << appid << " (" << connect << ").\n"; arguments.emplace_back(connect, appid); } } } - - std::cout << arguments.size() << ": Retry." << std::endl; - std::cout << std::endl << "Enter the number corresponding to your choice then press Enter." << std::endl; + + std::cout << arguments.size() << " - Refresh.\n\n"; + std::cout << "Choose an option: "; unsigned int choice; std::cin >> choice; - - if (choice >= arguments.size()) goto top; - + + if (std::cin.fail() || choice >= arguments.size()) { + std::cin.clear(); + std::cin.ignore(std::numeric_limits::max(), '\n'); + goto refresh; + } + + title(); + auto connect = arguments[choice].first; -#ifdef _WIN32 - auto appid = arguments[choice].second; - std::cout << "starting the game with: " << connect << std::endl; - - char szBaseDirectory[MAX_PATH] = ""; - GetModuleFileNameA(0, szBaseDirectory, MAX_PATH); - if (auto bs = strrchr(szBaseDirectory, '\\')) { - *bs = '\0'; - } - auto lobbyFile = std::string(szBaseDirectory) + "\\lobby_connect_" + std::to_string(appid) + ".txt"; - - auto readLobbyFile = [&lobbyFile]() { - std::string data; - std::ifstream ifs(std::filesystem::u8path(lobbyFile)); - if (ifs.is_open()) - std::getline(ifs, data); - return data; - }; - - auto writeLobbyFile = [&lobbyFile](const std::string& data) { - std::ofstream ofs(std::filesystem::u8path(lobbyFile)); - ofs << data << std::endl; - }; - - auto fileExists = [](const std::string& filename) { - std::ifstream ifs(std::filesystem::u8path(filename)); - return ifs.is_open(); - }; - - auto joinLobby = [&connect](std::string filename) { - filename = "\"" + filename + "\" " + connect; - std::cout << filename << std::endl; - - STARTUPINFOA lpStartupInfo; - PROCESS_INFORMATION lpProcessInfo; - - ZeroMemory( &lpStartupInfo, sizeof( lpStartupInfo ) ); - lpStartupInfo.cb = sizeof( lpStartupInfo ); - ZeroMemory( &lpProcessInfo, sizeof( lpProcessInfo ) ); - - auto success = !!CreateProcessA( NULL, - const_cast(filename.c_str()), NULL, NULL, - NULL, NULL, NULL, NULL, - &lpStartupInfo, - &lpProcessInfo - ); - - CloseHandle(lpProcessInfo.hThread); - CloseHandle(lpProcessInfo.hProcess); - return success; - }; - - std::string filename = readLobbyFile(); - if (filename.empty() || !fileExists(filename) || !joinLobby(filename)) { - std::cout << "Please select the game exe" << std::endl; - - OPENFILENAMEA ofn; - char szFileName[MAX_PATH] = ""; - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = 0; - ofn.lpstrFilter = "Exe Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0"; - ofn.lpstrFile = szFileName; - ofn.nMaxFile = MAX_PATH; - ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; - ofn.lpstrDefExt = "exe"; - if(GetOpenFileNameA(&ofn) && joinLobby(szFileName)) { - writeLobbyFile(szFileName); - } - } -#else - std::cout << "Please launch the game with these arguments: " << connect << std::endl; -#endif - + + #ifdef _WIN32 + auto appid = arguments[choice].second; + std::cout << "Starting the game with: " << connect << "\n"; + + char szBaseDirectory[MAX_PATH] = ""; + GetModuleFileNameA(0, szBaseDirectory, MAX_PATH); + if (auto bs = strrchr(szBaseDirectory, '\\')) { + *bs = '\0'; + } + auto lobbyFile = std::string(szBaseDirectory) + "\\lobby_connect_" + std::to_string(appid) + ".txt"; + + auto readLobbyFile = [&lobbyFile]() { + std::string data; + std::ifstream ifs(std::filesystem::u8path(lobbyFile)); + if (ifs.is_open()) + std::getline(ifs, data); + return data; + }; + + auto writeLobbyFile = [&lobbyFile](const std::string& data) { + std::ofstream ofs(std::filesystem::u8path(lobbyFile)); + ofs << data << "\n"; + }; + + auto fileExists = [](const std::string& filename) { + std::ifstream ifs(std::filesystem::u8path(filename)); + return ifs.is_open(); + }; + + auto joinLobby = [&connect](std::string filename) { + filename = "\"" + filename + "\" " + connect; + std::cout << filename << std::endl; + + STARTUPINFOA lpStartupInfo; + PROCESS_INFORMATION lpProcessInfo; + + ZeroMemory( &lpStartupInfo, sizeof( lpStartupInfo ) ); + lpStartupInfo.cb = sizeof( lpStartupInfo ); + ZeroMemory( &lpProcessInfo, sizeof( lpProcessInfo ) ); + + auto success = !!CreateProcessA( NULL, + const_cast(filename.c_str()), NULL, NULL, + NULL, NULL, NULL, NULL, + &lpStartupInfo, + &lpProcessInfo + ); + + CloseHandle(lpProcessInfo.hThread); + CloseHandle(lpProcessInfo.hProcess); + return success; + }; + + std::string filename = readLobbyFile(); + if (filename.empty() || !fileExists(filename) || !joinLobby(filename)) { + std::cout << "Please select the game executable.\n"; + + OPENFILENAMEA ofn; + char szFileName[MAX_PATH] = ""; + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = 0; + ofn.lpstrFilter = "Exe Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0"; + ofn.lpstrFile = szFileName; + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + ofn.lpstrDefExt = "exe"; + if(GetOpenFileNameA(&ofn) && joinLobby(szFileName)) { + writeLobbyFile(szFileName); + } + } + #else + std::cout << "Please launch the game with these arguments: " << connect << "\n\n"; + #endif + return 0; } + + From a68259d7cdb372c64efbf1f101b199176ec886b3 Mon Sep 17 00:00:00 2001 From: M4RCK5 Date: Sat, 14 Sep 2024 01:59:57 -0300 Subject: [PATCH 2/7] MELTY BLOOD TYPE LUMINA Fix [Requested by wizark](https://cs.rin.ru/forum/viewtopic.php?p=3124996#p3124996) --- dll/steam_user_stats_leaderboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dll/steam_user_stats_leaderboard.cpp b/dll/steam_user_stats_leaderboard.cpp index af2845f0..3665e82e 100644 --- a/dll/steam_user_stats_leaderboard.cpp +++ b/dll/steam_user_stats_leaderboard.cpp @@ -186,7 +186,7 @@ unsigned int Steam_User_Stats::cache_leaderboard_ifneeded(const std::string &nam // create a new entry in-memory and try reading the entries from disk struct Steam_Leaderboard new_board{}; - new_board.name = common_helpers::ascii_to_lowercase(name); + new_board.name = name; new_board.sort_method = eLeaderboardSortMethod; new_board.display_type = eLeaderboardDisplayType; new_board.entries = load_leaderboard_entries(name); From fcd523796fe31d3c8b765ff03257ee7a99cb5c67 Mon Sep 17 00:00:00 2001 From: M4RCK5 Date: Sat, 14 Sep 2024 05:32:53 -0300 Subject: [PATCH 3/7] Added back active user list but disabled --- tools/lobby_connect/lobby_connect.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tools/lobby_connect/lobby_connect.cpp b/tools/lobby_connect/lobby_connect.cpp index 942aa991..2bc6780e 100644 --- a/tools/lobby_connect/lobby_connect.cpp +++ b/tools/lobby_connect/lobby_connect.cpp @@ -66,6 +66,18 @@ int main() { int friend_count = SteamFriends()->GetFriendCount(k_EFriendFlagAll); + /* + std::cout << "People on the network: " << friend_count << "\n"; + for (int i = 0; i < friend_count; ++i) { + CSteamID id = SteamFriends()->GetFriendByIndex(i, k_EFriendFlagAll); + const char *name = SteamFriends()->GetFriendPersonaName(id); + + FriendGameInfo_t friend_info = {}; + SteamFriends()->GetFriendGamePlayed(id, &friend_info); + std::cout << name << " is playing: " << friend_info.m_gameID.AppID() << std::endl; + } + */ + title(); std::vector> arguments; From febbf32fb9a6bca34e4e3d423b1b674eacc2c326 Mon Sep 17 00:00:00 2001 From: Detanup01 <91248446+Detanup01@users.noreply.github.com> Date: Sun, 15 Sep 2024 16:46:21 +0200 Subject: [PATCH 4/7] Update stubdrm.cpp Adding new detection for Metal Slug 3 --- tools/steamclient_loader/win/extra_protection/stubdrm.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/steamclient_loader/win/extra_protection/stubdrm.cpp b/tools/steamclient_loader/win/extra_protection/stubdrm.cpp index d94cb4a4..846f1d26 100644 --- a/tools/steamclient_loader/win/extra_protection/stubdrm.cpp +++ b/tools/steamclient_loader/win/extra_protection/stubdrm.cpp @@ -104,6 +104,10 @@ typedef struct SnrDetails { "F6 C? 02 89 ?? ?? ?? ?? ?? A3 ?? ?? ?? ?? 0F 85", "?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 90 E9 00 03 00 00", }, +     { +         "F6 05 ?? ?? ?? ?? 02 89 ?? ?? 0F 85 ?? ?? ?? ?? 5? FF ?? 6?", +         "?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 90 E9 03 03", +     }, }, }, From addfd887823256be9afc34ccc2160fdcd1e40f3e Mon Sep 17 00:00:00 2001 From: Detanup01 <91248446+Detanup01@users.noreply.github.com> Date: Sun, 15 Sep 2024 17:14:00 +0200 Subject: [PATCH 5/7] fixing wrong indent (tabs) --- tools/steamclient_loader/win/extra_protection/stubdrm.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/steamclient_loader/win/extra_protection/stubdrm.cpp b/tools/steamclient_loader/win/extra_protection/stubdrm.cpp index 846f1d26..5b0481ef 100644 --- a/tools/steamclient_loader/win/extra_protection/stubdrm.cpp +++ b/tools/steamclient_loader/win/extra_protection/stubdrm.cpp @@ -104,10 +104,10 @@ typedef struct SnrDetails { "F6 C? 02 89 ?? ?? ?? ?? ?? A3 ?? ?? ?? ?? 0F 85", "?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 90 E9 00 03 00 00", }, -     { -         "F6 05 ?? ?? ?? ?? 02 89 ?? ?? 0F 85 ?? ?? ?? ?? 5? FF ?? 6?", -         "?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 90 E9 03 03", -     }, + { + "F6 05 ?? ?? ?? ?? 02 89 ?? ?? 0F 85 ?? ?? ?? ?? 5? FF ?? 6?", + "?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 90 E9 03 03", + }, }, }, From f7fe813310f1adc90fba7063ba798cca71db6a36 Mon Sep 17 00:00:00 2001 From: Detanup01 <91248446+Detanup01@users.noreply.github.com> Date: Sun, 15 Sep 2024 21:46:09 +0200 Subject: [PATCH 6/7] fix for "inputs" not exists in vdf --- .../controller_config_generator/parse_controller_vdf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/generate_emu_config/controller_config_generator/parse_controller_vdf.py b/tools/generate_emu_config/controller_config_generator/parse_controller_vdf.py index 3a19555c..b80ad57b 100644 --- a/tools/generate_emu_config/controller_config_generator/parse_controller_vdf.py +++ b/tools/generate_emu_config/controller_config_generator/parse_controller_vdf.py @@ -29,6 +29,8 @@ keymap_digital = { } def add_input_bindings(group, bindings, force_binding=None, keymap=keymap_digital): + if "inputs" not in group: + return bindings for i in group["inputs"]: for act in group["inputs"][i]: for fp in group["inputs"][i][act]: From cbef1d49e96da337b2da3872e077fac01b7b0530 Mon Sep 17 00:00:00 2001 From: universal963 <36097923+universal963@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:06:42 +0800 Subject: [PATCH 7/7] Correct undocumented api in `ISteamNetworkingSockets010` and `ISteamNetworkingSockets011` --- dll/dll/steam_networking_sockets.h | 3 --- dll/steam_networking_sockets.cpp | 35 ++++++++++---------------- sdk/steam/isteamnetworkingsockets010.h | 5 ++-- sdk/steam/isteamnetworkingsockets011.h | 5 ++-- 4 files changed, 19 insertions(+), 29 deletions(-) diff --git a/dll/dll/steam_networking_sockets.h b/dll/dll/steam_networking_sockets.h index abe289d7..036376d3 100644 --- a/dll/dll/steam_networking_sockets.h +++ b/dll/dll/steam_networking_sockets.h @@ -490,9 +490,6 @@ public: /// - k_EResultInvalidParam - nLanes is bad EResult GetConnectionRealTimeStatus( HSteamNetConnection hConn, SteamNetConnectionRealTimeStatus_t *pStatus, int nLanes, SteamNetConnectionRealTimeLaneStatus_t *pLanes ); - // based on reversing the vftable returned from original steamclient64.dll - bool GetConnectionRealTimeStatus_old( HSteamNetConnection hConn, SteamNetConnectionRealTimeStatus_t *pStatus ); - /// Fetch the next available message(s) from the socket, if any. /// Returns the number of messages returned into your array, up to nMaxMessages. /// If the connection handle is invalid, -1 is returned. diff --git a/dll/steam_networking_sockets.cpp b/dll/steam_networking_sockets.cpp index 696d7bf3..c789968b 100644 --- a/dll/steam_networking_sockets.cpp +++ b/dll/steam_networking_sockets.cpp @@ -950,24 +950,6 @@ EResult Steam_Networking_Sockets::GetConnectionRealTimeStatus( HSteamNetConnecti return k_EResultOK; } -// based on reversing the vftable returned from original steamclient64.dll -bool Steam_Networking_Sockets::GetConnectionRealTimeStatus_old( HSteamNetConnection hConn, SteamNetConnectionRealTimeStatus_t *pStatus ) -{ - PRINT_DEBUG("undocumented API, interface v10-11"); - /* - ... - xor r9d, r9d // int nLanes = 0 - mov qword ptr ss:[rsp+0x20], 0x0 // SteamNetConnectionRealTimeLaneStatus_t *pLanes = nullptr - ... - call qword ptr ds:[rax+0x80] // call GetConnectionRealTimeStatus(hConn, pStatus, nLanes, pLanes) - test eax, eax - setne al if (eax !=0) { al=1 } else { al=0 } - ... - ret - */ - return GetConnectionRealTimeStatus(hConn, pStatus, 0, nullptr) != EResult::k_EResultNone; -} - /// Fetch the next available message(s) from the socket, if any. /// Returns the number of messages returned into your array, up to nMaxMessages. /// If the connection handle is invalid, -1 is returned. @@ -1022,10 +1004,19 @@ bool Steam_Networking_Sockets::GetConnectionInfo( HSteamNetConnection hConn, Ste bool Steam_Networking_Sockets::GetQuickConnectionStatus( HSteamNetConnection hConn, SteamNetworkingQuickConnectionStatus *pStats ) { PRINT_DEBUG_ENTRY(); - if (!pStats) - return false; - - return GetConnectionRealTimeStatus(hConn, pStats, 0, NULL) == k_EResultOK; + // based on reversing the vftable returned from original steamclient64.dll + /* + ... + xor r9d, r9d // int nLanes = 0 + mov qword ptr ss:[rsp+0x20], 0x0 // SteamNetConnectionRealTimeLaneStatus_t *pLanes = nullptr + ... + call qword ptr ds:[rax+0x80] // call GetConnectionRealTimeStatus(hConn, pStatus, nLanes, pLanes) + test eax, eax + setne al if (eax !=0) { al=1 } else { al=0 } + ... + ret + */ + return GetConnectionRealTimeStatus(hConn, pStats, 0, NULL) != k_EResultNone; } diff --git a/sdk/steam/isteamnetworkingsockets010.h b/sdk/steam/isteamnetworkingsockets010.h index 1e260c88..589b3e6f 100644 --- a/sdk/steam/isteamnetworkingsockets010.h +++ b/sdk/steam/isteamnetworkingsockets010.h @@ -301,8 +301,9 @@ public: /// Returns basic information about the high-level state of the connection. virtual bool GetConnectionInfo( HSteamNetConnection hConn, SteamNetConnectionInfo_t *pInfo ) = 0; - // based on reversing the vftable returned from original steamclient64.dll - virtual bool GetConnectionRealTimeStatus_old( HSteamNetConnection hConn, SteamNetConnectionRealTimeStatus_t *pStatus ) = 0; + /// Returns a small set of information about the real-time state of the connection + /// Returns false if the connection handle is invalid, or the connection has ended. + virtual bool GetQuickConnectionStatus( HSteamNetConnection hConn, SteamNetworkingQuickConnectionStatus *pStats ) = 0; /// Returns detailed connection stats in text format. Useful /// for dumping to a log, etc. diff --git a/sdk/steam/isteamnetworkingsockets011.h b/sdk/steam/isteamnetworkingsockets011.h index 73fe8aa7..1550a884 100644 --- a/sdk/steam/isteamnetworkingsockets011.h +++ b/sdk/steam/isteamnetworkingsockets011.h @@ -301,8 +301,9 @@ public: /// Returns basic information about the high-level state of the connection. virtual bool GetConnectionInfo( HSteamNetConnection hConn, SteamNetConnectionInfo_t *pInfo ) = 0; - // based on reversing the vftable returned from original steamclient64.dll - virtual bool GetConnectionRealTimeStatus_old( HSteamNetConnection hConn, SteamNetConnectionRealTimeStatus_t *pStatus ) = 0; + /// Returns a small set of information about the real-time state of the connection + /// Returns false if the connection handle is invalid, or the connection has ended. + virtual bool GetQuickConnectionStatus( HSteamNetConnection hConn, SteamNetworkingQuickConnectionStatus *pStats ) = 0; /// Returns detailed connection stats in text format. Useful /// for dumping to a log, etc.