From 4de23561b0f4afa5961b98b218e5025cbf84e5e4 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Fri, 22 Dec 2023 21:52:51 -0800 Subject: [PATCH] add option to unmask Ep3 whispers on proxy server, and prevent this from working on newserv --- src/Client.hh | 1 + src/Menu.hh | 1 + src/ProxyCommands.cc | 27 ++++++++++++++++++-- src/ReceiveCommands.cc | 11 ++++++++- src/ReceiveSubcommands.cc | 52 ++++++++++++++++++++++++++++++++++++++- src/Text.hh | 7 ++++++ 6 files changed, 95 insertions(+), 4 deletions(-) diff --git a/src/Client.hh b/src/Client.hh index 11ccaafd..16442fe2 100644 --- a/src/Client.hh +++ b/src/Client.hh @@ -79,6 +79,7 @@ public: PROXY_RED_NAME_ENABLED = 0x0000200000000000, PROXY_BLANK_NAME_ENABLED = 0x0000400000000000, PROXY_BLOCK_FUNCTION_CALLS = 0x0000800000000000, + PROXY_EP3_UNMASK_WHISPERS = 0x0008000000000000, // clang-format on }; diff --git a/src/Menu.hh b/src/Menu.hh index 7bfb68c0..33468a60 100644 --- a/src/Menu.hh +++ b/src/Menu.hh @@ -75,6 +75,7 @@ constexpr uint32_t SUPPRESS_LOGIN = 0xAA0D0DAA; constexpr uint32_t SKIP_CARD = 0xAA0E0EAA; constexpr uint32_t EP3_INFINITE_MESETA = 0xAA0F0FAA; constexpr uint32_t EP3_INFINITE_TIME = 0xAA1010AA; +constexpr uint32_t EP3_UNMASK_WHISPERS = 0xAA1111AA; } // namespace ProxyOptionsMenuItemID namespace TeamRewardMenuItemID { diff --git a/src/ProxyCommands.cc b/src/ProxyCommands.cc index 69bd0d4c..2fc6cb55 100644 --- a/src/ProxyCommands.cc +++ b/src/ProxyCommands.cc @@ -560,14 +560,28 @@ static HandlerResult S_V123_04(shared_ptr ses, uint1 } static HandlerResult S_V123_06(shared_ptr ses, uint16_t, uint32_t, string& data) { + bool modified = false; if (ses->license) { auto& cmd = check_size_t(data, 0xFFFF); if (cmd.guild_card_number == ses->remote_guild_card_number) { cmd.guild_card_number = ses->license->serial_number; - return HandlerResult::Type::MODIFIED; + modified = true; } } - return HandlerResult::Type::FORWARD; + + // If the session is Ep3, and Unmask Whispers is on, and there's enough data, + // and the message has private_flags, and the private_flags say that you + // shouldn't see the message, then change the private_flags + if (is_ep3(ses->version()) && + ses->config.check_flag(Client::Flag::PROXY_EP3_UNMASK_WHISPERS) && + (data.size() >= 12) && + (data[sizeof(SC_TextHeader_01_06_11_B0_EE)] != '\t') && + (data[sizeof(SC_TextHeader_01_06_11_B0_EE)] & (1 << ses->lobby_client_id))) { + data[sizeof(SC_TextHeader_01_06_11_B0_EE)] &= ~(1 << ses->lobby_client_id); + modified = true; + } + + return modified ? HandlerResult::Type::MODIFIED : HandlerResult::Type::FORWARD; } template @@ -1031,6 +1045,15 @@ static HandlerResult S_6x(shared_ptr ses, uint16_t, return HandlerResult::Type::SUPPRESS; } } + + } else if ((static_cast(data[0]) == 0xBD) && + ses->config.check_flag(Client::Flag::PROXY_EP3_UNMASK_WHISPERS) && + is_ep3(ses->version())) { + auto& cmd = check_size_t(data); + if (cmd.private_flags & (1 << ses->lobby_client_id)) { + cmd.private_flags &= ~(1 << ses->lobby_client_id); + modified = true; + } } } diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index a18e27ca..44aa022e 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -69,6 +69,8 @@ static shared_ptr proxy_options_menu_for_client(shared_ptrconfig.override_lobby_event != 0xFF), @@ -2229,6 +2231,9 @@ static void on_10(shared_ptr c, uint16_t, uint32_t, string& data) { case ProxyOptionsMenuItemID::EP3_INFINITE_TIME: c->config.toggle_flag(Client::Flag::PROXY_EP3_INFINITE_TIME_ENABLED); goto resend_proxy_options_menu; + case ProxyOptionsMenuItemID::EP3_UNMASK_WHISPERS: + c->config.toggle_flag(Client::Flag::PROXY_EP3_UNMASK_WHISPERS); + goto resend_proxy_options_menu; case ProxyOptionsMenuItemID::BLOCK_EVENTS: c->config.override_lobby_event = (c->config.override_lobby_event == 0xFF) ? 0x00 : 0xFF; goto resend_proxy_options_menu; @@ -3172,7 +3177,11 @@ static void on_06(shared_ptr c, uint16_t, uint32_t, string& data) { } for (size_t x = 0; x < l->max_clients; x++) { if (l->clients[x]) { - send_chat_message(l->clients[x], c->license->serial_number, from_name, text, private_flags); + if (private_flags & (1 << x)) { + send_chat_message(l->clients[x], c->license->serial_number, from_name, "(whisper)", private_flags); + } else { + send_chat_message(l->clients[x], c->license->serial_number, from_name, text, private_flags); + } } } for (const auto& watcher_l : l->watcher_lobbies) { diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index 74a84cf3..bbaafdaa 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -1637,7 +1637,57 @@ static void on_ep3_private_word_select_bb_bank_action(shared_ptr c, uint } } else if (is_ep3(c->version())) { - forward_subcommand(c, command, flag, data, size); + + const auto& cmd = check_size_t(data, size); + G_WordSelectDuringBattle_GC_Ep3_6xBD masked_cmd = { + {0xBD, sizeof(G_WordSelectDuringBattle_GC_Ep3_6xBD) >> 2, cmd.header.client_id}, + 0x0001, + 0x0001, + // "Please use the Whispers function." + {0x00C1, 0x02C7, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, + 0x0000, + 0x0000, + cmd.private_flags, + {0, 0, 0}}; + + auto send_to_client = [&](shared_ptr lc) -> void { + if (cmd.private_flags & (1 << lc->lobby_client_id)) { + send_command_t(lc, command, flag, masked_cmd); + } else { + send_command_t(lc, command, flag, cmd); + } + }; + + if (command_is_private(command)) { + if (flag >= l->max_clients) { + return; + } + auto target = l->clients[flag]; + if (target) { + send_to_client(target); + } + } else { + for (auto& lc : l->clients) { + if (lc && (lc != c) && is_ep3(lc->version())) { + send_to_client(lc); + } + } + } + + for (const auto& watcher_lobby : l->watcher_lobbies) { + for (auto& target : watcher_lobby->clients) { + if (target && is_ep3(target->version())) { + send_command(target, command, flag, data, size); + } + } + } + + if (l->battle_record && l->battle_record->battle_in_progress()) { + auto type = ((command & 0xF0) == 0xC0) + ? Episode3::BattleRecord::Event::Type::EP3_GAME_COMMAND + : Episode3::BattleRecord::Event::Type::GAME_COMMAND; + l->battle_record->add_command(type, data, size); + } } } diff --git a/src/Text.hh b/src/Text.hh index 1ce75692..0b1d2834 100644 --- a/src/Text.hh +++ b/src/Text.hh @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -58,6 +59,12 @@ struct parray { parray(ItemT v) { this->clear(v); } + parray(std::initializer_list init_items) { + for (size_t z = 0; z < init_items.size(); z++) { + this->items[z] = std::data(init_items)[z]; + } + this->clear_after(init_items.size()); + } template requires(std::is_arithmetic_v || is_converted_endian_sc_v) parray() {