diff --git a/src/ChatCommands.cc b/src/ChatCommands.cc index edc4aec0..d0674c9b 100644 --- a/src/ChatCommands.cc +++ b/src/ChatCommands.cc @@ -135,13 +135,13 @@ static void proxy_command_lobby_info(shared_ptr, (session.leader_client_id == session.lobby_client_id) ? " (L)" : ""); vector cheats_tokens; - if (session.switch_assist) { + if (session.options.switch_assist) { cheats_tokens.emplace_back("SWA"); } - if (session.infinite_hp) { + if (session.options.infinite_hp) { cheats_tokens.emplace_back("HP"); } - if (session.infinite_tp) { + if (session.options.infinite_tp) { cheats_tokens.emplace_back("TP"); } if (!cheats_tokens.empty()) { @@ -150,13 +150,13 @@ static void proxy_command_lobby_info(shared_ptr, } vector behaviors_tokens; - if (session.save_files) { + if (session.options.save_files) { behaviors_tokens.emplace_back("SAVE"); } - if (session.suppress_remote_login) { + if (session.options.suppress_remote_login) { behaviors_tokens.emplace_back("SL"); } - if (session.function_call_return_value >= 0) { + if (session.options.function_call_return_value >= 0) { behaviors_tokens.emplace_back("BFC"); } if (!behaviors_tokens.empty()) { @@ -164,9 +164,9 @@ static void proxy_command_lobby_info(shared_ptr, msg += join(behaviors_tokens, ","); } - if (session.override_section_id >= 0) { - msg += "\n$C7SecID override: $C6"; - msg += name_for_section_id(session.override_section_id); + if (session.options.override_section_id >= 0) { + msg += "\n$C7SecID*: $C6"; + msg += name_for_section_id(session.options.override_section_id); } send_text_message(session.client_channel, decode_sjis(msg)); @@ -201,9 +201,9 @@ static void proxy_command_arrow(shared_ptr, static void server_command_dbgid(shared_ptr, shared_ptr, shared_ptr c, const std::u16string&) { - c->prefer_high_lobby_client_id = !c->prefer_high_lobby_client_id; + c->options.prefer_high_lobby_client_id = !c->options.prefer_high_lobby_client_id; send_text_message_printf(c, "ID preference set\nto $C6%s", - c->prefer_high_lobby_client_id ? "high" : "low"); + c->options.prefer_high_lobby_client_id ? "high" : "low"); } static void server_command_auction(shared_ptr, shared_ptr l, @@ -308,9 +308,9 @@ static void server_command_cheat(shared_ptr, shared_ptr l, if (!c) { continue; } - c->infinite_hp = false; - c->infinite_tp = false; - c->switch_assist = false; + c->options.infinite_hp = false; + c->options.infinite_tp = false; + c->options.switch_assist = false; } l->next_drop_item = PlayerInventoryItem(); } @@ -334,17 +334,17 @@ static void server_command_lobby_event(shared_ptr, shared_ptr, ProxyServer::LinkedSession& session, const std::u16string& args) { if (args.empty()) { - session.override_lobby_event = -1; + session.options.override_lobby_event = -1; } else { uint8_t new_event = event_for_name(args); if (new_event == 0xFF) { send_text_message(session.client_channel, u"$C6No such lobby event."); } else { - session.override_lobby_event = new_event; + session.options.override_lobby_event = new_event; if ((session.version == GameVersion::GC && !(session.newserv_client_config.cfg.flags & Client::Flag::IS_TRIAL_EDITION)) || (session.version == GameVersion::XB) || (session.version == GameVersion::BB)) { - session.client_channel.send(0xDA, session.override_lobby_event); + session.client_channel.send(0xDA, session.options.override_lobby_event); } } } @@ -446,14 +446,14 @@ static void server_command_secid(shared_ptr, shared_ptr l, check_is_game(l, false); if (!args[0]) { - c->override_section_id = -1; + c->options.override_section_id = -1; send_text_message(c, u"$C6Override section ID\nremoved"); } else { uint8_t new_secid = section_id_for_name(args); if (new_secid == 0xFF) { send_text_message(c, u"$C6Invalid section ID"); } else { - c->override_section_id = new_secid; + c->options.override_section_id = new_secid; send_text_message(c, u"$C6Override section ID\nset"); } } @@ -462,14 +462,14 @@ static void server_command_secid(shared_ptr, shared_ptr l, static void proxy_command_secid(shared_ptr, ProxyServer::LinkedSession& session, const std::u16string& args) { if (!args[0]) { - session.override_section_id = -1; + session.options.override_section_id = -1; send_text_message(session.client_channel, u"$C6Override section ID\nremoved"); } else { uint8_t new_secid = section_id_for_name(args); if (new_secid == 0xFF) { send_text_message(session.client_channel, u"$C6Invalid section ID"); } else { - session.override_section_id = new_secid; + session.options.override_section_id = new_secid; send_text_message(session.client_channel, u"$C6Override section ID\nset"); } } @@ -480,10 +480,10 @@ static void server_command_rand(shared_ptr, shared_ptr l, check_is_game(l, false); if (!args[0]) { - c->override_random_seed = -1; + c->options.override_random_seed = -1; send_text_message(c, u"$C6Override seed\nremoved"); } else { - c->override_random_seed = stoul(encode_sjis(args), 0, 16); + c->options.override_random_seed = stoul(encode_sjis(args), 0, 16); send_text_message(c, u"$C6Override seed\nset"); } } @@ -491,10 +491,10 @@ static void server_command_rand(shared_ptr, shared_ptr l, static void proxy_command_rand(shared_ptr, ProxyServer::LinkedSession& session, const std::u16string& args) { if (!args[0]) { - session.override_random_seed = -1; + session.options.override_random_seed = -1; send_text_message(session.client_channel, u"$C6Override seed\nremoved"); } else { - session.override_random_seed = stoul(encode_sjis(args), 0, 16); + session.options.override_random_seed = stoul(encode_sjis(args), 0, 16); send_text_message(session.client_channel, u"$C6Override seed\nset"); } } @@ -933,15 +933,16 @@ static void server_command_infinite_hp(shared_ptr, shared_ptrinfinite_hp = !c->infinite_hp; - send_text_message_printf(c, "$C6Infinite HP %s", c->infinite_hp ? "enabled" : "disabled"); + c->options.infinite_hp = !c->options.infinite_hp; + send_text_message_printf(c, "$C6Infinite HP %s", + c->options.infinite_hp ? "enabled" : "disabled"); } static void proxy_command_infinite_hp(shared_ptr, ProxyServer::LinkedSession& session, const std::u16string&) { - session.infinite_hp = !session.infinite_hp; + session.options.infinite_hp = !session.options.infinite_hp; send_text_message_printf(session.client_channel, "$C6Infinite HP %s", - session.infinite_hp ? "enabled" : "disabled"); + session.options.infinite_hp ? "enabled" : "disabled"); } static void server_command_infinite_tp(shared_ptr, shared_ptr l, @@ -949,15 +950,16 @@ static void server_command_infinite_tp(shared_ptr, shared_ptrinfinite_tp = !c->infinite_tp; - send_text_message_printf(c, "$C6Infinite TP %s", c->infinite_tp ? "enabled" : "disabled"); + c->options.infinite_tp = !c->options.infinite_tp; + send_text_message_printf(c, "$C6Infinite TP %s", + c->options.infinite_tp ? "enabled" : "disabled"); } static void proxy_command_infinite_tp(shared_ptr, ProxyServer::LinkedSession& session, const std::u16string&) { - session.infinite_tp = !session.infinite_tp; + session.options.infinite_tp = !session.options.infinite_tp; send_text_message_printf(session.client_channel, "$C6Infinite TP %s", - session.infinite_tp ? "enabled" : "disabled"); + session.options.infinite_tp ? "enabled" : "disabled"); } static void server_command_switch_assist(shared_ptr, shared_ptr l, @@ -965,14 +967,16 @@ static void server_command_switch_assist(shared_ptr, shared_ptrswitch_assist = !c->switch_assist; - send_text_message_printf(c, "$C6Switch assist %s", c->switch_assist ? "enabled" : "disabled"); + c->options.switch_assist = !c->options.switch_assist; + send_text_message_printf(c, "$C6Switch assist %s", + c->options.switch_assist ? "enabled" : "disabled"); } static void proxy_command_switch_assist(shared_ptr, ProxyServer::LinkedSession& session, const std::u16string&) { - session.switch_assist = !session.switch_assist; - send_text_message_printf(session.client_channel, "$C6Switch assist %s", session.switch_assist ? "enabled" : "disabled"); + session.options.switch_assist = !session.options.switch_assist; + send_text_message_printf(session.client_channel, "$C6Switch assist %s", + session.options.switch_assist ? "enabled" : "disabled"); } static void server_command_item(shared_ptr, shared_ptr l, diff --git a/src/Client.cc b/src/Client.cc index 6a77f195..f2075c68 100644 --- a/src/Client.cc +++ b/src/Client.cc @@ -25,6 +25,24 @@ static atomic next_id(1); +ClientOptions::ClientOptions() + : switch_assist(false), + infinite_hp(false), + infinite_tp(false), + prefer_high_lobby_client_id(false), + override_section_id(-1), + override_lobby_event(-1), + override_lobby_number(-1), + override_random_seed(-1), + save_files(false), + enable_chat_filter(true), + block_events(false), + suppress_remote_login(false), + zero_remote_guild_card(false), + function_call_return_value(-1) { } + + + Client::Client( struct bufferevent* bev, GameVersion version, @@ -46,7 +64,6 @@ Client::Client( lobby_id(0), lobby_client_id(0), lobby_arrow_color(0), - prefer_high_lobby_client_id(false), preferred_lobby_id(-1), save_game_data_event( event_new( @@ -57,18 +74,8 @@ Client::Client( card_battle_table_seat_number(0), card_battle_table_seat_state(0), next_exp_value(0), - override_section_id(-1), - override_random_seed(-1), - infinite_hp(false), - infinite_tp(false), - switch_assist(false), can_chat(true), pending_bb_save_player_index(0), - proxy_block_events(false), - proxy_block_function_calls(false), - proxy_save_files(false), - proxy_suppress_remote_login(false), - proxy_zero_remote_guild_card(false), dol_base_addr(0) { this->last_switch_enabled_command.header.subcommand = 0; memset(&this->next_connection_addr, 0, sizeof(this->next_connection_addr)); diff --git a/src/Client.hh b/src/Client.hh index 9a537441..a4876125 100644 --- a/src/Client.hh +++ b/src/Client.hh @@ -24,6 +24,28 @@ extern FileContentsCache client_options_cache; +struct ClientOptions { + // Options used on both game and proxy server + bool switch_assist; + bool infinite_hp; + bool infinite_tp; + bool prefer_high_lobby_client_id; + int16_t override_section_id; + int16_t override_lobby_event; + int16_t override_lobby_number; + int64_t override_random_seed; + + // Options used only on proxy server + bool save_files; + bool enable_chat_filter; + bool block_events; + bool suppress_remote_login; + bool zero_remote_guild_card; + int64_t function_call_return_value; // -1 = don't block function calls + + ClientOptions(); +}; + struct Client { enum Flag { // This flag has two meanings. If set on a client with GameVersion::DC, then @@ -103,13 +125,13 @@ struct Client { std::vector patch_file_checksum_requests; // Lobby/positioning + ClientOptions options; float x; float z; uint32_t area; // which area is the client in? uint32_t lobby_id; // which lobby is this person in? uint8_t lobby_client_id; // which client number is this person? uint8_t lobby_arrow_color; // lobby arrow color ID - bool prefer_high_lobby_client_id; int64_t preferred_lobby_id; // <0 = no preference ClientGameData game_data; std::unique_ptr save_game_data_event; @@ -120,22 +142,11 @@ struct Client { // Miscellaneous (used by chat commands) uint32_t next_exp_value; // next EXP value to give - int16_t override_section_id; // valid if >= 0 - int64_t override_random_seed; // valid if >= 0 - bool infinite_hp; // cheats enabled - bool infinite_tp; // cheats enabled - bool switch_assist; // cheats enabled G_SwitchStateChanged_6x05 last_switch_enabled_command; bool can_chat; std::string pending_bb_save_username; uint8_t pending_bb_save_player_index; - bool proxy_block_events; - bool proxy_block_function_calls; - bool proxy_save_files; - bool proxy_suppress_remote_login; - bool proxy_zero_remote_guild_card; - // File loading state uint32_t dol_base_addr; std::shared_ptr loading_dol_file; diff --git a/src/Lobby.cc b/src/Lobby.cc index 27ee8d93..b7c73115 100644 --- a/src/Lobby.cc +++ b/src/Lobby.cc @@ -82,7 +82,7 @@ void Lobby::add_client(shared_ptr c, ssize_t required_client_id) { this->clients[required_client_id] = c; index = required_client_id; - } else if (c->prefer_high_lobby_client_id) { + } else if (c->options.prefer_high_lobby_client_id) { for (index = max_clients - 1; index >= min_client_id; index--) { if (!this->clients[index].get()) { this->clients[index] = c; diff --git a/src/Menu.hh b/src/Menu.hh index cfdb63b0..4855a3f2 100644 --- a/src/Menu.hh +++ b/src/Menu.hh @@ -58,6 +58,7 @@ namespace PatchesMenuItemID { namespace ProxyOptionsMenuItemID { constexpr uint32_t GO_BACK = 0xAAFFFFAA; + constexpr uint32_t CHAT_FILTER = 0xAA0000AA; constexpr uint32_t INFINITE_HP = 0xAA1111AA; constexpr uint32_t INFINITE_TP = 0xAA2222AA; constexpr uint32_t SWITCH_ASSIST = 0xAA3333AA; diff --git a/src/ProxyCommands.cc b/src/ProxyCommands.cc index 0ecc4ebc..98c4cf00 100644 --- a/src/ProxyCommands.cc +++ b/src/ProxyCommands.cc @@ -142,7 +142,7 @@ static HandlerResult S_97(shared_ptr, static HandlerResult C_G_9E(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string&) { - if (session.suppress_remote_login) { + if (session.options.suppress_remote_login) { le_uint64_t checksum = random_object() & 0x0000FFFFFFFFFFFF; session.server_channel.send(0x96, 0x00, &checksum, sizeof(checksum)); @@ -160,7 +160,7 @@ static HandlerResult C_G_9E(shared_ptr, static HandlerResult S_G_9A(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string&) { - if (!session.license || session.suppress_remote_login) { + if (!session.license || session.options.suppress_remote_login) { return HandlerResult::Type::FORWARD; } @@ -355,7 +355,7 @@ static HandlerResult S_V123P_02_17( session.server_channel.send(0xDB, 0x00, &cmd, sizeof(cmd)); return HandlerResult::Type::SUPPRESS; - } else if (session.suppress_remote_login) { + } else if (session.options.suppress_remote_login) { uint32_t guild_card_number; if (session.remote_guild_card_number >= 0) { guild_card_number = session.remote_guild_card_number; @@ -597,7 +597,7 @@ static HandlerResult S_B2(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t flag, string& data) { const auto& cmd = check_size_t(data, sizeof(S_ExecuteCode_B2), 0xFFFF); - if (cmd.code_size && session.save_files) { + if (cmd.code_size && session.options.save_files) { uint64_t filename_timestamp = now(); string code = data.substr(sizeof(S_ExecuteCode_B2)); @@ -684,10 +684,10 @@ static HandlerResult S_B2(shared_ptr, #endif } - if (session.function_call_return_value >= 0) { + if (session.options.function_call_return_value >= 0) { session.log.info("Blocking function call from server"); C_ExecuteCodeResult_B3 cmd; - cmd.return_value = session.function_call_return_value; + cmd.return_value = session.options.function_call_return_value; cmd.checksum = 0; session.server_channel.send(0xB3, flag, &cmd, sizeof(cmd)); return HandlerResult::Type::SUPPRESS; @@ -710,7 +710,7 @@ static HandlerResult C_B3(shared_ptr, static HandlerResult S_B_E7(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { - if (session.save_files) { + if (session.options.save_files) { string output_filename = string_printf("player.%" PRId64 ".bin", now()); save_file(output_filename, data); session.log.info("Wrote player data to file %s", output_filename.c_str()); @@ -855,8 +855,9 @@ static HandlerResult S_V3_BB_DA(shared_ptr, if ((session.version == GameVersion::GC) && (session.newserv_client_config.cfg.flags & Client::Flag::IS_TRIAL_EDITION)) { return HandlerResult::Type::SUPPRESS; - } else if (session.override_lobby_event >= 0 && static_cast(flag) != session.override_lobby_event) { - return HandlerResult(HandlerResult::Type::MODIFIED, 0xDA, session.override_lobby_event); + } else if ((session.options.override_lobby_event >= 0) && + (static_cast(flag) != session.options.override_lobby_event)) { + return HandlerResult(HandlerResult::Type::MODIFIED, 0xDA, session.options.override_lobby_event); } else { return HandlerResult::Type::FORWARD; } @@ -866,7 +867,7 @@ static HandlerResult S_6x(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { check_implemented_subcommand(session, data); - if (session.save_files) { + if (session.options.save_files) { if ((session.version == GameVersion::GC) && (data.size() >= 0x14)) { if (static_cast(data[0]) == 0xB6) { const auto& header = check_size_t( @@ -986,7 +987,7 @@ static HandlerResult S_44_A6(shared_ptr, string filename = cmd.filename; string output_filename; - if (session.save_files) { + if (session.options.save_files) { output_filename = string_printf("%s.%s.%" PRIu64, filename.c_str(), (command == 0xA6) ? "download" : "online", now()); @@ -1003,7 +1004,7 @@ static HandlerResult S_44_A6(shared_ptr, ProxyServer::LinkedSession::SavingFile sf( cmd.filename, output_filename, cmd.file_size); session.saving_files.emplace(cmd.filename, move(sf)); - if (session.save_files) { + if (session.options.save_files) { session.log.info("Opened file %s", output_filename.c_str()); } else { session.log.info("Tracking file %s", filename.c_str()); @@ -1067,7 +1068,7 @@ static HandlerResult S_G_B7(shared_ptr, static HandlerResult S_G_B8(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { - if (session.save_files) { + if (session.options.save_files) { if (data.size() < 4) { session.log.warning("Card list data size is too small; not saving file"); return HandlerResult::Type::FORWARD; @@ -1153,12 +1154,12 @@ static HandlerResult S_65_67_68(shared_ptr, session.log.warning("Proxied player appears multiple times in lobby"); } - if (session.override_lobby_event >= 0) { - cmd.event = session.override_lobby_event; + if (session.options.override_lobby_event >= 0) { + cmd.event = session.options.override_lobby_event; modified = true; } - if (session.override_lobby_number >= 0) { - cmd.lobby_number = session.override_lobby_number; + if (session.options.override_lobby_number >= 0) { + cmd.lobby_number = session.options.override_lobby_number; modified = true; } @@ -1209,16 +1210,16 @@ static HandlerResult S_64(shared_ptr, x, p.guild_card_number, p.name.c_str()); } - if (session.override_section_id >= 0) { - cmd->section_id = session.override_section_id; + if (session.options.override_section_id >= 0) { + cmd->section_id = session.options.override_section_id; modified = true; } - if (session.override_lobby_event >= 0) { - cmd->event = session.override_lobby_event; + if (session.options.override_lobby_event >= 0) { + cmd->event = session.options.override_lobby_event; modified = true; } - if (session.override_random_seed >= 0) { - cmd->rare_seed = session.override_random_seed; + if (session.options.override_random_seed >= 0) { + cmd->rare_seed = session.options.override_random_seed; modified = true; } @@ -1287,7 +1288,7 @@ static HandlerResult C_06(shared_ptr s, return HandlerResult::Type::SUPPRESS; } - } else if (session.enable_chat_filter) { + } else if (session.options.enable_chat_filter) { add_color_inplace(data.data() + 8, data.size() - 8); // TODO: We should return MODIFIED here if the message was changed by // the add_color_inplace call @@ -1360,12 +1361,12 @@ static HandlerResult C_6x(shared_ptr s, session.area = cmd.area; } else if (data[0] == 0x2F || data[0] == 0x4B || data[0] == 0x4C) { - if (session.infinite_hp) { + if (session.options.infinite_hp) { send_player_stats_change(session.client_channel, session.lobby_client_id, PlayerStatsChange::ADD_HP, 2550); } } else if (data[0] == 0x48) { - if (session.infinite_tp) { + if (session.options.infinite_tp) { send_player_stats_change(session.client_channel, session.lobby_client_id, PlayerStatsChange::ADD_TP, 255); } @@ -1384,7 +1385,7 @@ HandlerResult C_6x(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { check_implemented_subcommand(session, data); - if (!data.empty() && (data[0] == 0x05) && session.switch_assist) { + if (!data.empty() && (data[0] == 0x05) && session.options.switch_assist) { auto& cmd = check_size_t(data); if (cmd.flags && cmd.header.object_id != 0xFFFF) { if (session.last_switch_enabled_command.header.subcommand == 0x05) { diff --git a/src/ProxyServer.cc b/src/ProxyServer.cc index fd942e9a..075b96a5 100644 --- a/src/ProxyServer.cc +++ b/src/ProxyServer.cc @@ -484,17 +484,7 @@ ProxyServer::LinkedSession::LinkedSession( sub_version(0), // This is set during resume() language(1), // Default = English. This is also set during resume() remote_guild_card_number(-1), - enable_chat_filter(true), - switch_assist(false), - infinite_hp(false), - infinite_tp(false), - save_files(false), - suppress_remote_login(false), - function_call_return_value(-1), next_item_id(0x0F000000), - override_section_id(-1), - override_lobby_event(-1), - override_lobby_number(-1), lobby_players(12), lobby_client_id(0), leader_client_id(0), @@ -657,13 +647,13 @@ void ProxyServer::LinkedSession::on_error(Channel& ch, short events) { if (events & BEV_EVENT_CONNECTED) { session->log.info("%s channel connected", is_server_stream ? "Server" : "Client"); - if (is_server_stream && (session->override_lobby_event >= 0) && + if (is_server_stream && (session->options.override_lobby_event >= 0) && ( ((session->version == GameVersion::GC) && !(session->newserv_client_config.cfg.flags & Client::Flag::IS_TRIAL_EDITION)) || (session->version == GameVersion::XB) || (session->version == GameVersion::BB) )) { - session->client_channel.send(0xDA, session->override_lobby_event); + session->client_channel.send(0xDA, session->options.override_lobby_event); } } if (events & BEV_EVENT_ERROR) { diff --git a/src/ProxyServer.hh b/src/ProxyServer.hh index b02f190a..ea076090 100644 --- a/src/ProxyServer.hh +++ b/src/ProxyServer.hh @@ -59,24 +59,14 @@ public: std::string hardware_id; // Only used for DC sessions std::string login_command_bb; + ClientOptions options; int64_t remote_guild_card_number; parray remote_client_config_data; ClientConfigBB newserv_client_config; - bool enable_chat_filter; - bool switch_assist; - bool infinite_hp; - bool infinite_tp; - bool save_files; - bool suppress_remote_login; std::deque should_forward_function_call_return_queue; - int64_t function_call_return_value; // -1 = don't block function calls G_SwitchStateChanged_6x05 last_switch_enabled_command; PlayerInventoryItem next_drop_item; uint32_t next_item_id; - int16_t override_section_id; - int16_t override_lobby_event; - int16_t override_lobby_number; - int64_t override_random_seed; struct LobbyPlayer { uint32_t guild_card_number; diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index 3890efb7..e1eb992a 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -72,14 +72,15 @@ vector quest_download_menu({ static const unordered_map proxy_options_menu_descriptions({ {ProxyOptionsMenuItemID::GO_BACK, u"Return to the\nproxy menu"}, - {ProxyOptionsMenuItemID::INFINITE_HP, u"If enabled, the proxy\nwill restore your HP\nwhen you are hit by\nan enemy or trap,\nbut cannot revive\nyou from one-hit\nkills"}, - {ProxyOptionsMenuItemID::INFINITE_TP, u"If enabled, the proxy\nwill restore your TP\nwhen you cast any\ntechnique"}, - {ProxyOptionsMenuItemID::SWITCH_ASSIST, u"If enabled, the proxy\nwill attempt to\nunlock 2-player\ndoors when you step\non both switches\nsequentially"}, - {ProxyOptionsMenuItemID::BLOCK_EVENTS, u"If enabled, seasonal\nevents in the lobby\nand in games are\ndisabled."}, - {ProxyOptionsMenuItemID::BLOCK_PATCHES, u"If enabled, patches\nsent by the remote\nserver are blocked."}, - {ProxyOptionsMenuItemID::SAVE_FILES, u"If enabled, the proxy\nwill save local\ncopies of files from\nthe remote server\n(quests, etc.)"}, - {ProxyOptionsMenuItemID::SUPPRESS_LOGIN, u"If enabled, the proxy\nwill use an alternate\nlogin sequence"}, - {ProxyOptionsMenuItemID::SKIP_CARD, u"If enabled, the proxy\nwill use an alternate\nvalue for your initial\nGuild Card"}, + {ProxyOptionsMenuItemID::CHAT_FILTER, u"Enable escape\nsequences in chat\nmessages"}, + {ProxyOptionsMenuItemID::INFINITE_HP, u"Enable automatic HP\nrestoration when\nyou are hit by an\nenemy or trap\n\nCannot revive you\nfrom one-hit kills"}, + {ProxyOptionsMenuItemID::INFINITE_TP, u"Enable automatic TP\nrestoration when\nyou cast any\ntechnique"}, + {ProxyOptionsMenuItemID::SWITCH_ASSIST, u"Automatically try\nto unlock 2-player\ndoors when you step\non both switches\nsequentially"}, + {ProxyOptionsMenuItemID::BLOCK_EVENTS, u"Disable seasonal\nevents in the lobby\nand in games"}, + {ProxyOptionsMenuItemID::BLOCK_PATCHES, u"Disable patches sent\nby the remote server"}, + {ProxyOptionsMenuItemID::SAVE_FILES, u"Save local copies of\nfiles from the remote\nserver (quests, etc.)"}, + {ProxyOptionsMenuItemID::SUPPRESS_LOGIN, u"Use an alternate\nlogin sequence"}, + {ProxyOptionsMenuItemID::SKIP_CARD, u"Use an alternate\nvalue for your initial\nGuild Card"}, }); static vector proxy_options_menu_for_client( @@ -90,26 +91,28 @@ static vector proxy_options_menu_for_client( // way in which the menu abstraction is currently insufficient (there is a // TODO about this in README.md). ret.emplace_back(ProxyOptionsMenuItemID::GO_BACK, u"Go back", u"", 0); + ret.emplace_back(ProxyOptionsMenuItemID::CHAT_FILTER, + c->options.enable_chat_filter ? u"Chat filter ON" : u"Chat filter OFF", u"", 0); if (!(c->flags & Client::Flag::IS_EPISODE_3)) { ret.emplace_back(ProxyOptionsMenuItemID::INFINITE_HP, - c->infinite_hp ? u"Infinite HP ON" : u"Infinite HP OFF", u"", 0); + c->options.infinite_hp ? u"Infinite HP ON" : u"Infinite HP OFF", u"", 0); ret.emplace_back(ProxyOptionsMenuItemID::INFINITE_TP, - c->infinite_tp ? u"Infinite TP ON" : u"Infinite TP OFF", u"", 0); + c->options.infinite_tp ? u"Infinite TP ON" : u"Infinite TP OFF", u"", 0); ret.emplace_back(ProxyOptionsMenuItemID::SWITCH_ASSIST, - c->switch_assist ? u"Switch assist ON" : u"Switch assist OFF", u"", 0); + c->options.switch_assist ? u"Switch assist ON" : u"Switch assist OFF", u"", 0); } ret.emplace_back(ProxyOptionsMenuItemID::BLOCK_EVENTS, - c->proxy_block_events ? u"Block events ON" : u"Block events OFF", u"", 0); + c->options.block_events ? u"Block events ON" : u"Block events OFF", u"", 0); ret.emplace_back(ProxyOptionsMenuItemID::BLOCK_PATCHES, - c->proxy_block_function_calls ? u"Block patches ON" : u"Block patches OFF", u"", 0); + (c->options.function_call_return_value >= 0) ? u"Block patches ON" : u"Block patches OFF", u"", 0); if (s->proxy_allow_save_files) { ret.emplace_back(ProxyOptionsMenuItemID::SAVE_FILES, - c->proxy_save_files ? u"Save files ON" : u"Save files OFF", u"", 0); + c->options.save_files ? u"Save files ON" : u"Save files OFF", u"", 0); } ret.emplace_back(ProxyOptionsMenuItemID::SUPPRESS_LOGIN, - c->proxy_suppress_remote_login ? u"Skip login ON" : u"Skip login OFF", u"", 0); + c->options.suppress_remote_login ? u"Skip login ON" : u"Skip login OFF", u"", 0); ret.emplace_back(ProxyOptionsMenuItemID::SKIP_CARD, - c->proxy_zero_remote_guild_card ? u"Skip card ON" : u"Skip card OFF", u"", 0); + c->options.zero_remote_guild_card ? u"Skip card ON" : u"Skip card OFF", u"", 0); return ret; } @@ -132,25 +135,10 @@ static void send_client_to_proxy_server(shared_ptr s, shared_ptrproxy_server->delete_session(c->license->serial_number); auto session = s->proxy_server->create_licensed_session( c->license, local_port, c->version(), c->export_config_bb()); - session->infinite_hp = c->infinite_hp; - session->infinite_tp = c->infinite_tp; - session->switch_assist = c->switch_assist; - session->save_files = s->proxy_allow_save_files && c->proxy_save_files; - session->suppress_remote_login = c->proxy_suppress_remote_login; - if (c->proxy_block_events) { - session->override_lobby_event = 0; - } - if (c->proxy_block_function_calls) { - session->function_call_return_value = 0xFFFFFFFF; - } - if (c->proxy_zero_remote_guild_card) { + session->options = c->options; + session->options.save_files &= s->proxy_allow_save_files; + if (session->options.zero_remote_guild_card) { session->remote_guild_card_number = 0; - } else { - try { - string key = string_printf("proxy_remote_guild_card_number:%" PRIX32, c->license->serial_number); - const auto& entry = client_options_cache.get_or_throw(key); - session->remote_guild_card_number = stoul(*entry->data, nullptr, 10); - } catch (const out_of_range&) { } } send_reconnect(c, s->connect_address_for_client(c), local_port); @@ -159,13 +147,6 @@ static void send_client_to_proxy_server(shared_ptr s, shared_ptr s, shared_ptr c) { send_menu(c, u"Proxy server", MenuID::PROXY_DESTINATIONS, s->proxy_destinations_menu_for_version(c->version())); - try { - string key = string_printf("proxy_remote_guild_card_number:%" PRIX32, c->license->serial_number); - const auto& entry = client_options_cache.get_or_throw(key); - uint32_t proxy_remote_guild_card_number = stoul(*entry->data, nullptr, 10); - string info_str = string_printf("Your remote Guild\nCard number is\noverridden as\n$C6%" PRIu32, proxy_remote_guild_card_number); - send_ship_info(c, decode_sjis(info_str)); - } catch (const out_of_range&) { } } static bool send_enable_send_function_call_if_applicable( @@ -1769,29 +1750,36 @@ static void on_menu_selection(shared_ptr s, shared_ptr c, case ProxyOptionsMenuItemID::GO_BACK: send_proxy_destinations_menu(s, c); break; + case ProxyOptionsMenuItemID::CHAT_FILTER: + c->options.enable_chat_filter = !c->options.enable_chat_filter; + goto resend_proxy_options_menu; case ProxyOptionsMenuItemID::INFINITE_HP: - c->infinite_hp = !c->infinite_hp; + c->options.infinite_hp = !c->options.infinite_hp; goto resend_proxy_options_menu; case ProxyOptionsMenuItemID::INFINITE_TP: - c->infinite_tp = !c->infinite_tp; + c->options.infinite_tp = !c->options.infinite_tp; goto resend_proxy_options_menu; case ProxyOptionsMenuItemID::SWITCH_ASSIST: - c->switch_assist = !c->switch_assist; + c->options.switch_assist = !c->options.switch_assist; goto resend_proxy_options_menu; case ProxyOptionsMenuItemID::BLOCK_EVENTS: - c->proxy_block_events = !c->proxy_block_events; + c->options.block_events = !c->options.block_events; goto resend_proxy_options_menu; case ProxyOptionsMenuItemID::BLOCK_PATCHES: - c->proxy_block_function_calls = !c->proxy_block_function_calls; + if (c->options.function_call_return_value >= 0) { + c->options.function_call_return_value = -1; + } else { + c->options.function_call_return_value = 0xFFFFFFFF; + } goto resend_proxy_options_menu; case ProxyOptionsMenuItemID::SAVE_FILES: - c->proxy_save_files = !c->proxy_save_files; + c->options.save_files = !c->options.save_files; goto resend_proxy_options_menu; case ProxyOptionsMenuItemID::SUPPRESS_LOGIN: - c->proxy_suppress_remote_login = !c->proxy_suppress_remote_login; + c->options.suppress_remote_login = !c->options.suppress_remote_login; goto resend_proxy_options_menu; case ProxyOptionsMenuItemID::SKIP_CARD: - c->proxy_zero_remote_guild_card = !c->proxy_zero_remote_guild_card; + c->options.zero_remote_guild_card = !c->options.zero_remote_guild_card; resend_proxy_options_menu: send_menu(c, s->name.c_str(), MenuID::PROXY_OPTIONS, proxy_options_menu_for_client(s, c)); @@ -3048,12 +3036,12 @@ shared_ptr create_game_generic( (item_tracking_enabled ? Lobby::Flag::ITEM_TRACKING_ENABLED : 0); game->password = password; game->version = c->version(); - game->section_id = c->override_section_id >= 0 - ? c->override_section_id : c->game_data.player()->disp.section_id; + game->section_id = c->options.override_section_id >= 0 + ? c->options.override_section_id : c->game_data.player()->disp.section_id; game->episode = episode; game->difficulty = difficulty; - if (c->override_random_seed >= 0) { - game->random_seed = c->override_random_seed; + if (c->options.override_random_seed >= 0) { + game->random_seed = c->options.override_random_seed; game->random->seed(game->random_seed); } if (battle_player) { diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index 1f5bfd50..5f8fbe7a 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -370,7 +370,7 @@ static void on_subcommand_hit_by_enemy(shared_ptr, return; } forward_subcommand(l, c, command, flag, data); - if ((l->flags & Lobby::Flag::CHEATS_ENABLED) && c->infinite_hp) { + if ((l->flags & Lobby::Flag::CHEATS_ENABLED) && c->options.infinite_hp) { send_player_stats_change(l, c, PlayerStatsChange::ADD_HP, 2550); } } @@ -384,7 +384,7 @@ static void on_subcommand_cast_technique_finished(shared_ptr, return; } forward_subcommand(l, c, command, flag, data); - if ((l->flags & Lobby::Flag::CHEATS_ENABLED) && c->infinite_tp) { + if ((l->flags & Lobby::Flag::CHEATS_ENABLED) && c->options.infinite_tp) { send_player_stats_change(l, c, PlayerStatsChange::ADD_TP, 255); } } @@ -434,7 +434,7 @@ static void on_subcommand_switch_state_changed(shared_ptr, } forward_subcommand(l, c, command, flag, data); if (cmd.flags && cmd.header.object_id != 0xFFFF) { - if ((l->flags & Lobby::Flag::CHEATS_ENABLED) && c->switch_assist && + if ((l->flags & Lobby::Flag::CHEATS_ENABLED) && c->options.switch_assist && (c->last_switch_enabled_command.header.subcommand == 0x05)) { c->log.info("[Switch assist] Replaying previous enable command"); forward_subcommand(l, c, command, flag, &c->last_switch_enabled_command, diff --git a/src/ServerShell.cc b/src/ServerShell.cc index 9c84a79e..9e303afc 100644 --- a/src/ServerShell.cc +++ b/src/ServerShell.cc @@ -529,54 +529,59 @@ Proxy commands (these will only work when exactly one client is connected):\n\ } else if (command_name == "set-override-section-id") { auto session = this->get_proxy_session(); if (command_args.empty()) { - session->override_section_id = -1; + session->options.override_section_id = -1; } else { - session->override_section_id = section_id_for_name(command_args); + session->options.override_section_id = section_id_for_name(command_args); } } else if (command_name == "set-override-event") { auto session = this->get_proxy_session(); if (command_args.empty()) { - session->override_lobby_event = -1; + session->options.override_lobby_event = -1; } else { - session->override_lobby_event = event_for_name(command_args); - session->client_channel.send(0xDA, session->override_lobby_event); + session->options.override_lobby_event = event_for_name(command_args); + if ((session->version != GameVersion::DC) && + (session->version != GameVersion::PC) && ( + !((session->version == GameVersion::GC) && + (session->newserv_client_config.cfg.flags & Client::Flag::IS_TRIAL_EDITION)))) { + session->client_channel.send(0xDA, session->options.override_lobby_event); + } } } else if (command_name == "set-override-lobby-number") { auto session = this->get_proxy_session(); if (command_args.empty()) { - session->override_lobby_number = -1; + session->options.override_lobby_number = -1; } else { - session->override_lobby_number = lobby_type_for_name(command_args); + session->options.override_lobby_number = lobby_type_for_name(command_args); } } else if (command_name == "set-chat-filter") { auto session = this->get_proxy_session(); - set_boolean(&session->enable_chat_filter, command_args); + set_boolean(&session->options.enable_chat_filter, command_args); } else if (command_name == "set-infinite-hp") { auto session = this->get_proxy_session(); - set_boolean(&session->infinite_hp, command_args); + set_boolean(&session->options.infinite_hp, command_args); } else if (command_name == "set-infinite-tp") { auto session = this->get_proxy_session(); - set_boolean(&session->infinite_tp, command_args); + set_boolean(&session->options.infinite_tp, command_args); } else if (command_name == "set-switch-assist") { auto session = this->get_proxy_session(); - set_boolean(&session->switch_assist, command_args); + set_boolean(&session->options.switch_assist, command_args); } else if (command_name == "set-save-files") { auto session = this->get_proxy_session(); - set_boolean(&session->save_files, command_args); + set_boolean(&session->options.save_files, command_args); } else if (command_name == "set-block-function-calls") { auto session = this->get_proxy_session(); if (command_args.empty()) { - session->function_call_return_value = -1; + session->options.function_call_return_value = -1; } else { - session->function_call_return_value = stoul(command_args); + session->options.function_call_return_value = stoul(command_args); } } else if (command_name == "set-next-item") {