add option to unmask Ep3 whispers on proxy server, and prevent this from working on newserv
This commit is contained in:
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+25
-2
@@ -560,14 +560,28 @@ static HandlerResult S_V123_04(shared_ptr<ProxyServer::LinkedSession> ses, uint1
|
||||
}
|
||||
|
||||
static HandlerResult S_V123_06(shared_ptr<ProxyServer::LinkedSession> ses, uint16_t, uint32_t, string& data) {
|
||||
bool modified = false;
|
||||
if (ses->license) {
|
||||
auto& cmd = check_size_t<SC_TextHeader_01_06_11_B0_EE>(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 <typename CmdT>
|
||||
@@ -1031,6 +1045,15 @@ static HandlerResult S_6x(shared_ptr<ProxyServer::LinkedSession> ses, uint16_t,
|
||||
return HandlerResult::Type::SUPPRESS;
|
||||
}
|
||||
}
|
||||
|
||||
} else if ((static_cast<uint8_t>(data[0]) == 0xBD) &&
|
||||
ses->config.check_flag(Client::Flag::PROXY_EP3_UNMASK_WHISPERS) &&
|
||||
is_ep3(ses->version())) {
|
||||
auto& cmd = check_size_t<G_WordSelectDuringBattle_GC_Ep3_6xBD>(data);
|
||||
if (cmd.private_flags & (1 << ses->lobby_client_id)) {
|
||||
cmd.private_flags &= ~(1 << ses->lobby_client_id);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-1
@@ -69,6 +69,8 @@ static shared_ptr<const Menu> proxy_options_menu_for_client(shared_ptr<const Cli
|
||||
"Infinite Meseta", "Fix Meseta value\nat 1,000,000");
|
||||
add_option(ProxyOptionsMenuItemID::EP3_INFINITE_TIME, Client::Flag::PROXY_EP3_INFINITE_TIME_ENABLED,
|
||||
"Infinite time", "Disable overall and\nper-phase time limits\nin battle");
|
||||
add_option(ProxyOptionsMenuItemID::EP3_UNMASK_WHISPERS, Client::Flag::PROXY_EP3_UNMASK_WHISPERS,
|
||||
"Unmask whispers", "Show contents of\nwhisper messages even\nif they are not for\nyou");
|
||||
}
|
||||
}
|
||||
add_bool_option(ProxyOptionsMenuItemID::BLOCK_EVENTS, (c->config.override_lobby_event != 0xFF),
|
||||
@@ -2229,6 +2231,9 @@ static void on_10(shared_ptr<Client> 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<Client> 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) {
|
||||
|
||||
@@ -1637,7 +1637,57 @@ static void on_ep3_private_word_select_bb_bank_action(shared_ptr<Client> c, uint
|
||||
}
|
||||
|
||||
} else if (is_ep3(c->version())) {
|
||||
forward_subcommand(c, command, flag, data, size);
|
||||
|
||||
const auto& cmd = check_size_t<G_WordSelectDuringBattle_GC_Ep3_6xBD>(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<Client> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <initializer_list>
|
||||
#include <phosg/Encoding.hh>
|
||||
#include <phosg/Strings.hh>
|
||||
#include <stdexcept>
|
||||
@@ -58,6 +59,12 @@ struct parray {
|
||||
parray(ItemT v) {
|
||||
this->clear(v);
|
||||
}
|
||||
parray(std::initializer_list<ItemT> 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 <typename ArgT = ItemT>
|
||||
requires(std::is_arithmetic_v<ArgT> || is_converted_endian_sc_v<ArgT>)
|
||||
parray() {
|
||||
|
||||
Reference in New Issue
Block a user