From 8177707413e326e1fc520cbd90d4f7b06af7a348 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Tue, 21 Mar 2023 00:14:54 +0100 Subject: [PATCH] SDK Launcher light refactor * Fixed bug causing command line interface not to work properly. * Optimized warning text and instructions. * Terminal will not be freed when compiled in Debug/Profile. * The console will now forward the command to all game window instances. --- r5dev/sdklauncher/basepanel.cpp | 42 ++++++++---- r5dev/sdklauncher/sdklauncher.cpp | 98 +++++++++++++++------------ r5dev/sdklauncher/sdklauncher.h | 2 + r5dev/sdklauncher/sdklauncher_const.h | 6 +- 4 files changed, 90 insertions(+), 58 deletions(-) diff --git a/r5dev/sdklauncher/basepanel.cpp b/r5dev/sdklauncher/basepanel.cpp index 744eabcf..b821189a 100644 --- a/r5dev/sdklauncher/basepanel.cpp +++ b/r5dev/sdklauncher/basepanel.cpp @@ -705,29 +705,45 @@ void CSurface::GetVirtualItem(const std::unique_ptr(pSender->FindForm()); + vector vecHandles; - const HWND hWindow = FindWindowA("Respawn001", NULL); - if (hWindow) + if (!EnumWindows(EnumWindowsProc, reinterpret_cast(&vecHandles))) + return; + + if (vecHandles.empty()) + return; + + const String kzCommand = pSurface->m_ConsoleCommandTextBox->Text(); + const char* szCommand = kzCommand.ToCString(); + + bool bSuccess = false; + + for (const HWND hWindow : vecHandles) { - const String kzCommand = pSurface->m_ConsoleCommandTextBox->Text(); - const char* szCommand = kzCommand.ToCString(); - COPYDATASTRUCT cData = { 0, (DWORD)strnlen_s(szCommand, 259) + 1, (void*)szCommand }; + char szWindowName[256]; + GetWindowTextA(hWindow, szWindowName, 256); + COPYDATASTRUCT cData = { 0, (DWORD)strnlen_s(szCommand, 259) + 1, (void*)szCommand }; bool bProcessingMessage = SendMessageA(hWindow, WM_COPYDATA, NULL, (LPARAM)&cData); // WM_COPYDATA will only return 0 or 1, that's why we use a boolean. - if (bProcessingMessage) + if (bProcessingMessage && !bSuccess) { - pSurface->m_ConsoleCommandTextBox->SetText(""); - pSurface->m_LogList.push_back(LogList_t((spdlog::level::level_enum)2, kzCommand)); - pSurface->m_ConsoleListView->SetVirtualListSize(static_cast(pSurface->m_LogList.size())); - pSurface->m_ConsoleListView->Refresh(); + bSuccess = true; } } + + if (bSuccess) // At least one game instance received the command. + { + pSurface->m_LogList.push_back(LogList_t((spdlog::level::level_enum)2, kzCommand)); + pSurface->m_ConsoleListView->SetVirtualListSize(static_cast(pSurface->m_LogList.size())); + pSurface->m_ConsoleListView->Refresh(); + pSurface->m_ConsoleCommandTextBox->SetText(""); + } } //----------------------------------------------------------------------------- @@ -878,10 +894,10 @@ eLaunchMode CSurface::BuildParameter(string& svParameters) { AppendParameterInternal(svParameters, "-dev"); AppendParameterInternal(svParameters, "-devsdk"); - results = eLaunchMode::LM_HOST_DEV; + results = eLaunchMode::LM_GAME_DEV; } else - results = eLaunchMode::LM_HOST; + results = eLaunchMode::LM_GAME; if (this->m_CheatsToggle->Checked()) { diff --git a/r5dev/sdklauncher/sdklauncher.cpp b/r5dev/sdklauncher/sdklauncher.cpp index 4fdc9a75..79ce7fb6 100644 --- a/r5dev/sdklauncher/sdklauncher.cpp +++ b/r5dev/sdklauncher/sdklauncher.cpp @@ -53,22 +53,22 @@ int CLauncher::HandleCommandLine(int argc, char* argv[]) { for (int i = 1; i < __argc; ++i) { - std::string arg = __argv[i]; - eLaunchMode mode = eLaunchMode::LM_HOST; + string arg = __argv[i]; + eLaunchMode mode = eLaunchMode::LM_NONE; if ((arg == "-developer") || (arg == "-dev")) { - mode = eLaunchMode::LM_HOST_DEV; + mode = eLaunchMode::LM_GAME_DEV; } else if ((arg == "-retail") || (arg == "-prod")) { - mode = eLaunchMode::LM_HOST; + mode = eLaunchMode::LM_GAME; } - else if ((arg == "-dedicated_dev") || (arg == "-dedid")) + else if ((arg == "-server_dev") || (arg == "-svd")) { mode = eLaunchMode::LM_SERVER_DEV; } - else if ((arg == "-dedicated") || (arg == "-dedi")) + else if ((arg == "-server") || (arg == "-sv")) { mode = eLaunchMode::LM_SERVER; } @@ -81,15 +81,15 @@ int CLauncher::HandleCommandLine(int argc, char* argv[]) mode = eLaunchMode::LM_CLIENT; } - if (CreateLaunchContext(mode) && LaunchProcess()) + if (mode != eLaunchMode::LM_NONE) { - Sleep(2000); - return EXIT_SUCCESS; + if (CreateLaunchContext(mode) && LaunchProcess()) + { + return EXIT_SUCCESS; + } } - - Sleep(2000); - return EXIT_FAILURE; } + return -1; } @@ -100,23 +100,11 @@ int CLauncher::HandleCommandLine(int argc, char* argv[]) int CLauncher::HandleInput() { std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; - AddLog(spdlog::level::level_enum::warn, "If a DEV option has been chosen as launch parameter, do not broadcast servers to the Server Browser!\n"); - AddLog(spdlog::level::level_enum::warn, "All FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY ConVar's/ConCommand's will be enabled.\n"); - AddLog(spdlog::level::level_enum::warn, "Connected clients will be able to set and execute anything marked FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY.\n"); + AddLog(spdlog::level::level_enum::warn, "The '{:s}' options are for development purposes; use the '{:s}' options for default usage.\n", "DEV", "PROD"); std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; - AddLog(spdlog::level::level_enum::warn, "Use DEV HOST [0] for research and development purposes.\n"); - AddLog(spdlog::level::level_enum::warn, "Use RETAIL HOST [1] for playing the game and creating servers.\n"); - AddLog(spdlog::level::level_enum::warn, "Use DEV SERVER [2] for research and development purposes.\n"); - AddLog(spdlog::level::level_enum::warn, "Use RETAIL SERVER [3] for running and hosting dedicated servers.\n"); - AddLog(spdlog::level::level_enum::warn, "Use DEV CLIENT [4] for research and development purposes.\n"); - AddLog(spdlog::level::level_enum::warn, "Use RETAIL CLIENT [5] for running the client only game.\n"); - std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; - AddLog(spdlog::level::level_enum::info, "Enter '0' for 'DEV HOST'.\n"); - AddLog(spdlog::level::level_enum::info, "Enter '1' for 'RETAIL HOST'.\n"); - AddLog(spdlog::level::level_enum::info, "Enter '2' for 'DEV SERVER'.\n"); - AddLog(spdlog::level::level_enum::info, "Enter '3' for 'RETAIL SERVER'.\n"); - AddLog(spdlog::level::level_enum::info, "Enter '4' for 'DEV CLIENT'.\n"); - AddLog(spdlog::level::level_enum::info, "Enter '5' for 'RETAIL CLIENT'.\n"); + AddLog(spdlog::level::level_enum::info, "{:6s} ('0' = {:s} | '1' = {:s}).\n", "GAME", "DEV", "PROD"); + AddLog(spdlog::level::level_enum::info, "{:6s} ('2' = {:s} | '3' = {:s}).\n", "SERVER", "DEV", "PROD"); + AddLog(spdlog::level::level_enum::info, "{:6s} ('4' = {:s} | '5' = {:s}).\n", "CLIENT", "DEV", "PROD"); std::cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; std::cout << "User input: "; @@ -129,26 +117,21 @@ int CLauncher::HandleInput() if (CreateLaunchContext(mode) && LaunchProcess()) { - Sleep(2000); return EXIT_SUCCESS; } else { AddLog(spdlog::level::level_enum::err, "Invalid mode (range 0-5).\n"); - Sleep(2000); return EXIT_FAILURE; } } catch (const std::exception& e) { - AddLog(spdlog::level::level_enum::err, "SDK Launcher only takes numerical input; error: {:s}.\n", e.what()); - Sleep(2000); + AddLog(spdlog::level::level_enum::err, "SDK Launcher only takes numerical input (error = {:s}).\n", e.what()); return EXIT_FAILURE; } } AddLog(spdlog::level::level_enum::err, "SDK Launcher requires numerical input.\n"); - - Sleep(2000); return EXIT_FAILURE; } @@ -164,20 +147,20 @@ bool CLauncher::CreateLaunchContext(eLaunchMode lMode, const char* szCommandLine /////////////////////////////////////////////////////////////////////////// switch (lMode) { - case eLaunchMode::LM_HOST_DEV: + case eLaunchMode::LM_GAME_DEV: { if (!szConfig) { szConfig = "startup_dev.cfg"; } SetupLaunchContext(szConfig, MAIN_WORKER_DLL, MAIN_GAME_DLL, szCommandLine); - AddLog(spdlog::level::level_enum::info, "*** LAUNCHING GAME [DEV] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHING GAME [{:s}] ***\n", "DEV"); break; } - case eLaunchMode::LM_HOST: + case eLaunchMode::LM_GAME: { if (!szConfig) { szConfig = "startup_retail.cfg"; } SetupLaunchContext(szConfig, MAIN_WORKER_DLL, MAIN_GAME_DLL, szCommandLine); - AddLog(spdlog::level::level_enum::info, "*** LAUNCHING GAME [RETAIL] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHING GAME [{:s}] ***\n", "PROD"); break; } case eLaunchMode::LM_SERVER_DEV: @@ -185,7 +168,7 @@ bool CLauncher::CreateLaunchContext(eLaunchMode lMode, const char* szCommandLine if (!szConfig) { szConfig = "startup_dedi_dev.cfg"; } SetupLaunchContext(szConfig, SERVER_WORKER_DLL, SERVER_GAME_DLL, szCommandLine); - AddLog(spdlog::level::level_enum::info, "*** LAUNCHING DEDICATED [DEV] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHING SERVER [{:s}] ***\n", "DEV"); break; } case eLaunchMode::LM_SERVER: @@ -193,7 +176,7 @@ bool CLauncher::CreateLaunchContext(eLaunchMode lMode, const char* szCommandLine if (!szConfig) { szConfig = "startup_dedi_retail.cfg"; } SetupLaunchContext(szConfig, SERVER_WORKER_DLL, SERVER_GAME_DLL, szCommandLine); - AddLog(spdlog::level::level_enum::info, "*** LAUNCHING DEDICATED [RETAIL] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHING SERVER [{:s}] ***\n", "PROD"); break; } case eLaunchMode::LM_CLIENT_DEV: @@ -201,7 +184,7 @@ bool CLauncher::CreateLaunchContext(eLaunchMode lMode, const char* szCommandLine if (!szConfig) { szConfig = "startup_client_dev.cfg"; } SetupLaunchContext(szConfig, CLIENT_WORKER_DLL, MAIN_GAME_DLL, szCommandLine); - AddLog(spdlog::level::level_enum::info, "*** LAUNCHING CLIENT [DEV] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHING CLIENT [{:s}] ***\n", "DEV"); break; } case eLaunchMode::LM_CLIENT: @@ -209,12 +192,12 @@ bool CLauncher::CreateLaunchContext(eLaunchMode lMode, const char* szCommandLine if (!szConfig) { szConfig = "startup_client_retail.cfg"; } SetupLaunchContext(szConfig, CLIENT_WORKER_DLL, MAIN_GAME_DLL, szCommandLine); - AddLog(spdlog::level::level_enum::info, "*** LAUNCHING CLIENT [RETAIL] ***\n"); + AddLog(spdlog::level::level_enum::info, "*** LAUNCHING CLIENT [{:s}] ***\n", "PROD"); break; } default: { - AddLog(spdlog::level::level_enum::err, "*** NO LAUNCH MODE SPECIFIED ***\n"); + AddLog(spdlog::level::level_enum::err, "No launch mode specified.\n"); return false; } } @@ -326,6 +309,33 @@ bool CLauncher::LaunchProcess() const return true; } +/////////////////////////////////////////////////////////////////////////////// +// Purpose: Window enumerator callback. +// Input : hwnd - +// lParam - +// Output : TRUE on success, FALSE otherwise. +/////////////////////////////////////////////////////////////////////////////// +BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) +{ + vector* pHandles = reinterpret_cast*>(lParam); + if (!pHandles) + { + return FALSE; + } + + char szClassName[256]; + if (!GetClassNameA(hwnd, szClassName, 256)) + { + return FALSE; + } + + if (strcmp(szClassName, DEFAULT_WINDOW_CLASS_NAME) == 0) + { + pHandles->push_back(hwnd); + } + return TRUE; +} + /////////////////////////////////////////////////////////////////////////////// // EntryPoint. /////////////////////////////////////////////////////////////////////////////// @@ -334,7 +344,9 @@ int main(int argc, char* argv[], char* envp[]) g_pLauncher->InitLogger(); if (__argc < 2) { +#ifdef NDEBUG FreeConsole(); +#endif // NDEBUG g_pLauncher->RunSurface(); } else diff --git a/r5dev/sdklauncher/sdklauncher.h b/r5dev/sdklauncher/sdklauncher.h index 31ce2598..ad7a58f2 100644 --- a/r5dev/sdklauncher/sdklauncher.h +++ b/r5dev/sdklauncher/sdklauncher.h @@ -56,4 +56,6 @@ private: string m_svCurrentDir; }; +BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam); + extern CLauncher* g_pLauncher; diff --git a/r5dev/sdklauncher/sdklauncher_const.h b/r5dev/sdklauncher/sdklauncher_const.h index b2dc4bb5..aaca6286 100644 --- a/r5dev/sdklauncher/sdklauncher_const.h +++ b/r5dev/sdklauncher/sdklauncher_const.h @@ -9,14 +9,16 @@ #define GAME_CFG_PATH "platform\\cfg\\" +#define DEFAULT_WINDOW_CLASS_NAME "Respawn001" + //----------------------------------------------------------------------------- // Launch and inject specified dll based on launch mode //----------------------------------------------------------------------------- enum class eLaunchMode : int { LM_NONE = -1, - LM_HOST_DEV, - LM_HOST, + LM_GAME_DEV, + LM_GAME, LM_SERVER_DEV, LM_SERVER, LM_CLIENT_DEV,