From a703ed4ed78d0fa0110a259fe10aa795283e8969 Mon Sep 17 00:00:00 2001 From: Goober Date: Thu, 17 Oct 2024 11:16:41 -0230 Subject: [PATCH 1/2] Initial commit --- docs/CHANGELOG.md | 1 + game_patch/os/commands.cpp | 30 ++++++++++++++++++++++++++++++ game_patch/rf/multi.h | 1 + 3 files changed, 32 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index e88023cd..22fc80f1 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -44,6 +44,7 @@ Version 1.9.0 (not released yet) - Add level filename to "Level Initializing" console message - Properly handle WM_PAINT in dedicated server, may improve performance (DF bug) - Fix crash when `verify_level` command is run without a level being loaded +- Add `server_rcon_password` command Version 1.8.0 (released 2022-09-17) ----------------------------------- diff --git a/game_patch/os/commands.cpp b/game_patch/os/commands.cpp index a1586ad8..7fdec9e5 100644 --- a/game_patch/os/commands.cpp +++ b/game_patch/os/commands.cpp @@ -92,6 +92,35 @@ DcCommandAlias map_info_cmd{ level_info_cmd, }; +ConsoleCommand2 server_rcon_password_cmd{ + "server_rcon_password", + [](std::optional pattern) { + if (!rf::is_multi || !rf::is_server) { + rf::console::print("This command can only be run as a server!"); + return; + } + rf::console::print("Current rcon password is: {}", rf::rcon_password); + + if (pattern) { + if (pattern->size() > 16) { + // game limits client requests to 16 characters + rf::console::print("Server rcon password cannot exceed 16 characters."); + return; + } + + std::strncpy(rf::rcon_password, pattern->c_str(), sizeof(rf::rcon_password) - 1); + rf::rcon_password[sizeof(rf::rcon_password) - 1] = '\0'; // null terminator + rf::console::print("Server rcon password set to: {}", *pattern); + } + else { + std::memset(rf::rcon_password, 0, sizeof(rf::rcon_password)); + rf::console::print("Server rcon password removed."); + } + }, + "Set or remove the server rcon password.", + "server_rcon_password ", +}; + // only allow verify_level if a level is loaded (avoid a crash if command is run in menu) FunHook verify_level_cmd_hook{ 0x0045E1F0, @@ -205,5 +234,6 @@ void console_commands_init() map_cmd.register_cmd(); level_info_cmd.register_cmd(); map_info_cmd.register_cmd(); + server_rcon_password_cmd.register_cmd(); verify_level_cmd_hook.install(); } diff --git a/game_patch/rf/multi.h b/game_patch/rf/multi.h index 92bb5b99..5c3f1d44 100644 --- a/game_patch/rf/multi.h +++ b/game_patch/rf/multi.h @@ -174,6 +174,7 @@ namespace rf static auto& is_dedicated_server = addr_as_ref(0x0064ECBB); static auto& simultaneous_ping = addr_as_ref(0x00599CD8); static auto& tracker_addr = addr_as_ref(0x006FC550); + static auto& rcon_password = *reinterpret_cast(0x0064ECD0); // max 20 characters enum ChatSayType { CHAT_SAY_GLOBAL = 0, From f687814f7136684701e9d0614dbb17c2e4b8c21d Mon Sep 17 00:00:00 2001 From: Goober Date: Thu, 17 Oct 2024 12:37:04 -0230 Subject: [PATCH 2/2] disallow changing rcon pw on listen servers, some cleanup --- game_patch/os/commands.cpp | 17 ++++++++--------- game_patch/rf/multi.h | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/game_patch/os/commands.cpp b/game_patch/os/commands.cpp index 7fdec9e5..8601ef80 100644 --- a/game_patch/os/commands.cpp +++ b/game_patch/os/commands.cpp @@ -94,26 +94,25 @@ DcCommandAlias map_info_cmd{ ConsoleCommand2 server_rcon_password_cmd{ "server_rcon_password", - [](std::optional pattern) { - if (!rf::is_multi || !rf::is_server) { - rf::console::print("This command can only be run as a server!"); + [](std::optional new_rcon_password) { + if (!rf::is_multi || !rf::is_dedicated_server) { + rf::console::print("This command can only be run on a dedicated server!"); return; } - rf::console::print("Current rcon password is: {}", rf::rcon_password); - if (pattern) { - if (pattern->size() > 16) { + if (new_rcon_password) { + if (new_rcon_password->size() > 16) { // game limits client requests to 16 characters rf::console::print("Server rcon password cannot exceed 16 characters."); return; } - std::strncpy(rf::rcon_password, pattern->c_str(), sizeof(rf::rcon_password) - 1); + std::strncpy(rf::rcon_password, new_rcon_password->c_str(), sizeof(rf::rcon_password) - 1); rf::rcon_password[sizeof(rf::rcon_password) - 1] = '\0'; // null terminator - rf::console::print("Server rcon password set to: {}", *pattern); + rf::console::print("Server rcon password set to: {}", rf::rcon_password); } else { - std::memset(rf::rcon_password, 0, sizeof(rf::rcon_password)); + *rf::rcon_password = '\0'; rf::console::print("Server rcon password removed."); } }, diff --git a/game_patch/rf/multi.h b/game_patch/rf/multi.h index 5c3f1d44..4b18e615 100644 --- a/game_patch/rf/multi.h +++ b/game_patch/rf/multi.h @@ -174,7 +174,7 @@ namespace rf static auto& is_dedicated_server = addr_as_ref(0x0064ECBB); static auto& simultaneous_ping = addr_as_ref(0x00599CD8); static auto& tracker_addr = addr_as_ref(0x006FC550); - static auto& rcon_password = *reinterpret_cast(0x0064ECD0); // max 20 characters + static auto& rcon_password = addr_as_ref(0x0064ECD0); enum ChatSayType { CHAT_SAY_GLOBAL = 0,