diff --git a/README.md b/README.md index 914c7614..5590bd8d 100644 --- a/README.md +++ b/README.md @@ -363,7 +363,7 @@ Some commands only work on the game server and not on the proxy server. The chat * `$si` (game server only): Shows basic information about the server. * `$ping`: Shows round-trip ping time from the server to you. On the proxy server, shows the ping time from you to the proxy and from the proxy to the server. * `$matcount` (game server only): Shows how many of each type of material you've used. - * `$rarenotifs` (game server only): Enables or disables rare drop notifications. Only applies to server drop modes (see `$dropmode`); notifications are not supported in client drop mode. When enabled, you'll see a message whenever a rare item drops. In private drop mode, you will only see a notification if the item is visible to you; you won't be notified of other players' rare drops. + * `$itemnotifs `: Enables item drop notification messages. The modes are `off`, `rare`, and `on`, which should be self-explanatory. If the game has private drops enabled, you will only see a notification if the dropped item is visible to you; you won't be notified of other players' rare drops. * `$what` (game server only): Shows the type, name, and stats of the nearest item on the ground. * `$where` (game server only): Shows your current floor number and coordinates. Mainly useful for debugging. diff --git a/src/ChatCommands.cc b/src/ChatCommands.cc index 66e749b9..296c6809 100644 --- a/src/ChatCommands.cc +++ b/src/ChatCommands.cc @@ -1555,10 +1555,30 @@ static void proxy_command_song(shared_ptr ses, const send_ep3_change_music(ses->client_channel, song); } -static void server_command_rare_notifs(shared_ptr c, const std::string&) { - c->config.toggle_flag(Client::Flag::RARE_DROP_NOTIFICATIONS_ENABLED); - bool enabled = c->config.check_flag(Client::Flag::RARE_DROP_NOTIFICATIONS_ENABLED); - send_text_message_printf(c, "$C6Rare notifications\n%s", enabled ? "enabled" : "disabled"); +static void command_item_notifs(Channel& ch, Client::Config& config, const std::string& args) { + if (args == "all" || args == "on") { + config.clear_flag(Client::Flag::RARE_DROP_NOTIFICATIONS_ENABLED); + config.set_flag(Client::Flag::ALL_DROP_NOTIFICATIONS_ENABLED); + send_text_message_printf(ch, "$C6Notifications enabled\nfor all items"); + } else if (args == "rare" || args == "rares") { + config.set_flag(Client::Flag::RARE_DROP_NOTIFICATIONS_ENABLED); + config.clear_flag(Client::Flag::ALL_DROP_NOTIFICATIONS_ENABLED); + send_text_message_printf(ch, "$C6Notifications enabled\nfor rare items only"); + } else if (args == "none" || args == "off") { + config.clear_flag(Client::Flag::RARE_DROP_NOTIFICATIONS_ENABLED); + config.clear_flag(Client::Flag::ALL_DROP_NOTIFICATIONS_ENABLED); + send_text_message_printf(ch, "$C6Notifications disabled\nfor all items"); + } else { + send_text_message_printf(ch, "$C6You must specify\n$C6off$C7, $C6rare$C7, or $C6on$C7"); + } +} + +static void server_command_item_notifs(shared_ptr c, const std::string& args) { + command_item_notifs(c->channel, c->config, args); +} + +static void proxy_command_item_notifs(shared_ptr ses, const std::string& args) { + command_item_notifs(ses->client_channel, ses->config, args); } static void server_command_infinite_hp(shared_ptr c, const std::string&) { @@ -2058,6 +2078,7 @@ static const unordered_map chat_commands({ {"$inftime", {server_command_ep3_infinite_time, nullptr}}, {"$inftp", {server_command_infinite_tp, proxy_command_infinite_tp}}, {"$item", {server_command_item, proxy_command_item}}, + {"$itemnotifs", {server_command_item_notifs, proxy_command_item_notifs}}, {"$i", {server_command_item, proxy_command_item}}, {"$kick", {server_command_kick, nullptr}}, {"$li", {server_command_lobby_info, proxy_command_lobby_info}}, @@ -2083,7 +2104,6 @@ static const unordered_map chat_commands({ {"$qsyncall", {server_command_qsyncall, proxy_command_qsyncall}}, {"$quest", {server_command_quest, nullptr}}, {"$rand", {server_command_rand, proxy_command_rand}}, - {"$rarenotifs", {server_command_rare_notifs, nullptr}}, {"$save", {server_command_save, nullptr}}, {"$savechar", {server_command_savechar, nullptr}}, {"$saverec", {server_command_saverec, nullptr}}, diff --git a/src/Client.cc b/src/Client.cc index 0c070331..7659c10d 100644 --- a/src/Client.cc +++ b/src/Client.cc @@ -195,7 +195,8 @@ Client::Client( external_bank_character_index(-1), last_play_time_update(0) { this->config.set_flags_for_version(version, -1); - if (server->get_state()->default_rare_notifs_enabled) { + auto s = server->get_state(); + if (is_v1_or_v2(this->version()) ? s->default_rare_notifs_enabled_v1_v2 : s->default_rare_notifs_enabled_v3_v4) { this->config.set_flag(Flag::RARE_DROP_NOTIFICATIONS_ENABLED); } this->config.specific_version = default_specific_version_for_version(version, -1); @@ -209,7 +210,7 @@ Client::Client( // Don't print data sent to patch clients to the logs. The patch server // protocol is fully understood and data logs for patch clients are generally // more annoying than helpful at this point. - if ((server->get_state()->hide_download_commands) && + if ((s->hide_download_commands) && ((this->channel.version == Version::PC_PATCH) || (this->channel.version == Version::BB_PATCH))) { this->channel.terminal_recv_color = TerminalFormat::END; this->channel.terminal_send_color = TerminalFormat::END; diff --git a/src/Client.hh b/src/Client.hh index 84322ec3..f2f0b61c 100644 --- a/src/Client.hh +++ b/src/Client.hh @@ -73,6 +73,7 @@ public: INFINITE_TP_ENABLED = 0x0000000400000000, DEBUG_ENABLED = 0x0000000800000000, RARE_DROP_NOTIFICATIONS_ENABLED = 0x0010000000000000, + ALL_DROP_NOTIFICATIONS_ENABLED = 0x0020000000000000, // Proxy option flags PROXY_SAVE_FILES = 0x0000001000000000, diff --git a/src/Menu.hh b/src/Menu.hh index 467e893a..58ab46c3 100644 --- a/src/Menu.hh +++ b/src/Menu.hh @@ -61,20 +61,21 @@ namespace ProxyOptionsMenuItemID { constexpr uint32_t GO_BACK = 0xAAFFFFAA; constexpr uint32_t CHAT_COMMANDS = 0xAA0101AA; constexpr uint32_t PLAYER_NOTIFICATIONS = 0xAA0202AA; -constexpr uint32_t BLOCK_PINGS = 0xAA0303AA; -constexpr uint32_t INFINITE_HP = 0xAA0404AA; -constexpr uint32_t INFINITE_TP = 0xAA0505AA; -constexpr uint32_t SWITCH_ASSIST = 0xAA0606AA; -constexpr uint32_t BLOCK_EVENTS = 0xAA0707AA; -constexpr uint32_t BLOCK_PATCHES = 0xAA0808AA; -constexpr uint32_t SAVE_FILES = 0xAA0909AA; -constexpr uint32_t RED_NAME = 0xAA0A0AAA; -constexpr uint32_t BLANK_NAME = 0xAA0B0BAA; -constexpr uint32_t SUPPRESS_LOGIN = 0xAA0C0CAA; -constexpr uint32_t SKIP_CARD = 0xAA0D0DAA; -constexpr uint32_t EP3_INFINITE_MESETA = 0xAA0E0EAA; -constexpr uint32_t EP3_INFINITE_TIME = 0xAA0F0FAA; -constexpr uint32_t EP3_UNMASK_WHISPERS = 0xAA1010AA; +constexpr uint32_t DROP_NOTIFICATIONS = 0xAA0303AA; +constexpr uint32_t BLOCK_PINGS = 0xAA0404AA; +constexpr uint32_t INFINITE_HP = 0xAA0505AA; +constexpr uint32_t INFINITE_TP = 0xAA0606AA; +constexpr uint32_t SWITCH_ASSIST = 0xAA0707AA; +constexpr uint32_t BLOCK_EVENTS = 0xAA0808AA; +constexpr uint32_t BLOCK_PATCHES = 0xAA0909AA; +constexpr uint32_t SAVE_FILES = 0xAA0A0AAA; +constexpr uint32_t RED_NAME = 0xAA0B0BAA; +constexpr uint32_t BLANK_NAME = 0xAA0C0CAA; +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 2f7bafe1..903b5073 100644 --- a/src/ProxyCommands.cc +++ b/src/ProxyCommands.cc @@ -1048,6 +1048,10 @@ static HandlerResult S_6x(shared_ptr ses, uint16_t, return HandlerResult::Type::SUPPRESS; } + } else if (data[0] == 0x5F) { + const auto& cmd = check_size_t(data, sizeof(G_DropItem_PC_V3_BB_6x5F)); + send_item_notification_if_needed(ses->require_server_state(), ses->client_channel, ses->config, cmd.item.item, true); + } else if ((data[0] == 0x60) && ses->next_drop_item.data1d[0] && !is_v4(ses->version())) { const auto& cmd = check_size_t( data, sizeof(G_StandardDropItemRequest_PC_V3_BB_6x60)); @@ -1785,6 +1789,9 @@ static HandlerResult C_6x(shared_ptr ses, uint16_t c send_player_stats_change(ses->server_channel, ses->lobby_client_id, PlayerStatsChange::ADD_TP, 255); } + } else if (data[0] == 0x5F) { + const auto& cmd = check_size_t(data, sizeof(G_DropItem_PC_V3_BB_6x5F)); + send_item_notification_if_needed(ses->require_server_state(), ses->client_channel, ses->config, cmd.item.item, true); } } return C_6x(ses, command, flag, data); diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index fb426be8..cb3c3df5 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -41,51 +41,59 @@ static shared_ptr proxy_options_menu_for_client(shared_ptritems.emplace_back(item_id, option, description, 0); }; - auto add_option = [&](uint32_t item_id, Client::Flag flag, const char* text, const char* description) -> void { + auto add_flag_option = [&](uint32_t item_id, Client::Flag flag, const char* text, const char* description) -> void { add_bool_option(item_id, c->config.check_flag(flag), text, description); }; - add_option(ProxyOptionsMenuItemID::CHAT_COMMANDS, Client::Flag::PROXY_CHAT_COMMANDS_ENABLED, + add_flag_option(ProxyOptionsMenuItemID::CHAT_COMMANDS, Client::Flag::PROXY_CHAT_COMMANDS_ENABLED, "Chat commands", "Enable chat\ncommands"); - add_option(ProxyOptionsMenuItemID::PLAYER_NOTIFICATIONS, Client::Flag::PROXY_PLAYER_NOTIFICATIONS_ENABLED, + add_flag_option(ProxyOptionsMenuItemID::PLAYER_NOTIFICATIONS, Client::Flag::PROXY_PLAYER_NOTIFICATIONS_ENABLED, "Player notifs", "Show a message\nwhen other players\njoin or leave"); - add_option(ProxyOptionsMenuItemID::BLOCK_PINGS, Client::Flag::PROXY_SUPPRESS_CLIENT_PINGS, + static const char* item_drop_notifs_description = "Enable item drop\nnotifications\n\nYou can change this\nduring the game with\nthe %sitemnotifs\ncommand"; + if (c->config.check_flag(Client::Flag::ALL_DROP_NOTIFICATIONS_ENABLED)) { + ret->items.emplace_back(ProxyOptionsMenuItemID::DROP_NOTIFICATIONS, "All drop notifs", item_drop_notifs_description, 0); + } else if (c->config.check_flag(Client::Flag::RARE_DROP_NOTIFICATIONS_ENABLED)) { + ret->items.emplace_back(ProxyOptionsMenuItemID::DROP_NOTIFICATIONS, "Rare drop notifs", item_drop_notifs_description, 0); + } else { + ret->items.emplace_back(ProxyOptionsMenuItemID::DROP_NOTIFICATIONS, "No drop notifs", item_drop_notifs_description, 0); + } + add_flag_option(ProxyOptionsMenuItemID::BLOCK_PINGS, Client::Flag::PROXY_SUPPRESS_CLIENT_PINGS, "Block pings", "Block ping commands\nsent by the client"); add_bool_option(ProxyOptionsMenuItemID::BLOCK_EVENTS, (c->config.override_lobby_event != 0xFF), "Block events", "Disable seasonal\nevents in the lobby\nand in games"); - add_option(ProxyOptionsMenuItemID::BLOCK_PATCHES, Client::Flag::PROXY_BLOCK_FUNCTION_CALLS, + add_flag_option(ProxyOptionsMenuItemID::BLOCK_PATCHES, Client::Flag::PROXY_BLOCK_FUNCTION_CALLS, "Block patches", "Disable patches sent\nby the remote server"); - add_option(ProxyOptionsMenuItemID::SWITCH_ASSIST, Client::Flag::SWITCH_ASSIST_ENABLED, + add_flag_option(ProxyOptionsMenuItemID::SWITCH_ASSIST, Client::Flag::SWITCH_ASSIST_ENABLED, "Switch assist", "Automatically try\nto unlock 2-player\ndoors when you step\non both switches\nsequentially"); if ((s->cheat_mode_behavior != ServerState::BehaviorSwitch::OFF) || c->license->check_flag(License::Flag::CHEAT_ANYWHERE)) { if (!is_ep3(c->version())) { - add_option(ProxyOptionsMenuItemID::INFINITE_HP, Client::Flag::INFINITE_HP_ENABLED, + add_flag_option(ProxyOptionsMenuItemID::INFINITE_HP, Client::Flag::INFINITE_HP_ENABLED, "Infinite HP", "Enable automatic HP\nrestoration when\nyou are hit by an\nenemy or trap\n\nCannot revive you\nfrom one-hit kills"); - add_option(ProxyOptionsMenuItemID::INFINITE_TP, Client::Flag::INFINITE_TP_ENABLED, + add_flag_option(ProxyOptionsMenuItemID::INFINITE_TP, Client::Flag::INFINITE_TP_ENABLED, "Infinite TP", "Enable automatic TP\nrestoration when\nyou cast any\ntechnique"); } else { // Note: This option's text is the maximum possible length for any menu item - add_option(ProxyOptionsMenuItemID::EP3_INFINITE_MESETA, Client::Flag::PROXY_EP3_INFINITE_MESETA_ENABLED, + add_flag_option(ProxyOptionsMenuItemID::EP3_INFINITE_MESETA, Client::Flag::PROXY_EP3_INFINITE_MESETA_ENABLED, "Infinite Meseta", "Fix Meseta value\nat 1,000,000"); - add_option(ProxyOptionsMenuItemID::EP3_INFINITE_TIME, Client::Flag::PROXY_EP3_INFINITE_TIME_ENABLED, + add_flag_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, + add_flag_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"); } } if (s->proxy_allow_save_files) { - add_option(ProxyOptionsMenuItemID::SAVE_FILES, Client::Flag::PROXY_SAVE_FILES, + add_flag_option(ProxyOptionsMenuItemID::SAVE_FILES, Client::Flag::PROXY_SAVE_FILES, "Save files", "Save local copies of\nfiles from the\nremote server\n(quests, etc.)"); } if (s->proxy_enable_login_options) { - add_option(ProxyOptionsMenuItemID::RED_NAME, Client::Flag::PROXY_RED_NAME_ENABLED, + add_flag_option(ProxyOptionsMenuItemID::RED_NAME, Client::Flag::PROXY_RED_NAME_ENABLED, "Red name", "Set the colors\nof your name and\nChallenge Mode\nrank to red"); - add_option(ProxyOptionsMenuItemID::BLANK_NAME, Client::Flag::PROXY_BLANK_NAME_ENABLED, + add_flag_option(ProxyOptionsMenuItemID::BLANK_NAME, Client::Flag::PROXY_BLANK_NAME_ENABLED, "Blank name", "Suppress your\ncharacter name\nduring login"); if (c->version() != Version::XB_V3) { - add_option(ProxyOptionsMenuItemID::SUPPRESS_LOGIN, Client::Flag::PROXY_SUPPRESS_REMOTE_LOGIN, + add_flag_option(ProxyOptionsMenuItemID::SUPPRESS_LOGIN, Client::Flag::PROXY_SUPPRESS_REMOTE_LOGIN, "Skip login", "Use an alternate\nlogin sequence"); - add_option(ProxyOptionsMenuItemID::SKIP_CARD, Client::Flag::PROXY_ZERO_REMOTE_GUILD_CARD, + add_flag_option(ProxyOptionsMenuItemID::SKIP_CARD, Client::Flag::PROXY_ZERO_REMOTE_GUILD_CARD, "Skip card", "Use an alternate\nvalue for your initial\nGuild Card"); } } @@ -2292,6 +2300,18 @@ static void on_10(shared_ptr c, uint16_t, uint32_t, string& data) { case ProxyOptionsMenuItemID::PLAYER_NOTIFICATIONS: c->config.toggle_flag(Client::Flag::PROXY_PLAYER_NOTIFICATIONS_ENABLED); goto resend_proxy_options_menu; + case ProxyOptionsMenuItemID::DROP_NOTIFICATIONS: + if (c->config.check_flag(Client::Flag::ALL_DROP_NOTIFICATIONS_ENABLED)) { + c->config.clear_flag(Client::Flag::ALL_DROP_NOTIFICATIONS_ENABLED); + c->config.clear_flag(Client::Flag::RARE_DROP_NOTIFICATIONS_ENABLED); + } else if (c->config.check_flag(Client::Flag::RARE_DROP_NOTIFICATIONS_ENABLED)) { + c->config.set_flag(Client::Flag::ALL_DROP_NOTIFICATIONS_ENABLED); + c->config.clear_flag(Client::Flag::RARE_DROP_NOTIFICATIONS_ENABLED); + } else { + c->config.clear_flag(Client::Flag::ALL_DROP_NOTIFICATIONS_ENABLED); + c->config.set_flag(Client::Flag::RARE_DROP_NOTIFICATIONS_ENABLED); + } + goto resend_proxy_options_menu; case ProxyOptionsMenuItemID::BLOCK_PINGS: c->config.toggle_flag(Client::Flag::PROXY_SUPPRESS_CLIENT_PINGS); goto resend_proxy_options_menu; diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index 2119f637..3e3b25ac 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -1577,15 +1577,22 @@ static void on_buy_shop_item(shared_ptr c, uint8_t command, uint8_t flag forward_subcommand_with_item_transcode_t(c, command, flag, cmd); } -static void send_rare_notification_if_needed(shared_ptr to_c, const ItemData& item, bool is_from_rare_table) { - auto s = to_c->require_server_state(); - if (!to_c->config.check_flag(Client::Flag::RARE_DROP_NOTIFICATIONS_ENABLED) || - (!is_from_rare_table && (item.data1[0] != 0x03)) || - !s->item_parameter_table(to_c->version())->is_item_rare(item)) { - return; +void send_item_notification_if_needed( + shared_ptr s, + Channel& ch, + const Client::Config& config, + const ItemData& item, + bool is_from_rare_table) { + if (config.check_flag(Client::Flag::ALL_DROP_NOTIFICATIONS_ENABLED)) { + string name = s->describe_item(ch.version, item, true); + send_text_message(ch, name); + + } else if (config.check_flag(Client::Flag::RARE_DROP_NOTIFICATIONS_ENABLED) && + (is_from_rare_table || (item.data1[0] == 0x03)) && + s->item_parameter_table(ch.version)->is_item_rare(item)) { + string name = s->describe_item(ch.version, item, true); + send_text_message_printf(ch, "$C6Rare item dropped:\n%s", name.c_str()); } - string name = s->describe_item(to_c->version(), item, true); - send_text_message_printf(to_c, "$C6Rare item dropped:\n%s", name.c_str()); } template @@ -1635,10 +1642,7 @@ static void on_box_or_enemy_item_drop_t(shared_ptr c, uint8_t command, u send_command_t(lc, command, flag, cmd); } } - // TODO: Make rare drop notifications work in client drop mode. The problem - // is that we can't know if items are from the rare table or not when the - // client generates them, and some common items like Celestial Shield have - // 9 stars on v2 so they would be considered rare without that check. + send_item_notification_if_needed(s, lc->channel, lc->config, cmd.item.item, true); } } @@ -2288,7 +2292,7 @@ static void on_entity_drop_item_request(shared_ptr c, uint8_t command, u res.item.id.load(), cmd.floor, cmd.x.load(), cmd.z.load(), lc->channel.name.c_str()); l->add_item(cmd.floor, res.item, cmd.x, cmd.z, (1 << lc->lobby_client_id)); send_drop_item_to_channel(s, lc->channel, res.item, !is_box, cmd.floor, cmd.x, cmd.z, cmd.entity_id); - send_rare_notification_if_needed(lc, res.item, res.is_from_rare_table); + send_item_notification_if_needed(s, lc->channel, lc->config, res.item, res.is_from_rare_table); } } @@ -2300,7 +2304,7 @@ static void on_entity_drop_item_request(shared_ptr c, uint8_t command, u send_drop_item_to_lobby(l, res.item, !is_box, cmd.floor, cmd.x, cmd.z, cmd.entity_id); for (auto lc : l->clients) { if (lc) { - send_rare_notification_if_needed(lc, res.item, res.is_from_rare_table); + send_item_notification_if_needed(s, lc->channel, lc->config, res.item, res.is_from_rare_table); } } } @@ -2321,7 +2325,7 @@ static void on_entity_drop_item_request(shared_ptr c, uint8_t command, u res.item.id.load(), cmd.floor, cmd.x.load(), cmd.z.load(), lc->channel.name.c_str()); l->add_item(cmd.floor, res.item, cmd.x, cmd.z, (1 << lc->lobby_client_id)); send_drop_item_to_channel(s, lc->channel, res.item, !is_box, cmd.floor, cmd.x, cmd.z, cmd.entity_id); - send_rare_notification_if_needed(lc, res.item, res.is_from_rare_table); + send_item_notification_if_needed(s, lc->channel, lc->config, res.item, res.is_from_rare_table); } } } diff --git a/src/ReceiveSubcommands.hh b/src/ReceiveSubcommands.hh index 52cdd105..677f3f3a 100644 --- a/src/ReceiveSubcommands.hh +++ b/src/ReceiveSubcommands.hh @@ -9,3 +9,10 @@ void on_subcommand_multi(std::shared_ptr c, uint8_t command, uint8_t flag, std::string& data); bool subcommand_is_implemented(uint8_t which); + +void send_item_notification_if_needed( + std::shared_ptr s, + Channel& ch, + const Client::Config& config, + const ItemData& item, + bool is_from_rare_table); diff --git a/src/ServerState.cc b/src/ServerState.cc index b3b0b202..975354a2 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -715,7 +715,10 @@ void ServerState::load_config() { this->persistent_game_idle_timeout_usecs = json.get_int("PersistentGameIdleTimeout", 0); this->cheat_mode_behavior = parse_behavior_switch("CheatModeBehavior", BehaviorSwitch::OFF_BY_DEFAULT); - this->default_rare_notifs_enabled = json.get_bool("RareNotificationsEnabledByDefault", false); + this->default_rare_notifs_enabled_v1_v2 = json.get_bool("RareNotificationsEnabledByDefault", false); + this->default_rare_notifs_enabled_v3_v4 = this->default_rare_notifs_enabled_v1_v2; + this->default_rare_notifs_enabled_v1_v2 = json.get_bool("RareNotificationsEnabledByDefaultV1V2", this->default_rare_notifs_enabled_v1_v2); + this->default_rare_notifs_enabled_v3_v4 = json.get_bool("RareNotificationsEnabledByDefaultV3V4", this->default_rare_notifs_enabled_v3_v4); this->ep3_send_function_call_enabled = json.get_bool("EnableEpisode3SendFunctionCall", false); this->catch_handler_exceptions = json.get_bool("CatchHandlerExceptions", true); diff --git a/src/ServerState.hh b/src/ServerState.hh index 3a6b153f..b6389929 100644 --- a/src/ServerState.hh +++ b/src/ServerState.hh @@ -118,7 +118,8 @@ struct ServerState : public std::enable_shared_from_this { bool hide_download_commands = true; RunShellBehavior run_shell_behavior = RunShellBehavior::DEFAULT; BehaviorSwitch cheat_mode_behavior = BehaviorSwitch::OFF_BY_DEFAULT; - bool default_rare_notifs_enabled = false; + bool default_rare_notifs_enabled_v1_v2 = false; + bool default_rare_notifs_enabled_v3_v4 = false; std::vector> bb_private_keys; std::shared_ptr function_code_index; std::shared_ptr pc_patch_file_index; diff --git a/system/config.example.json b/system/config.example.json index 1d1b78d6..196246f9 100644 --- a/system/config.example.json +++ b/system/config.example.json @@ -898,8 +898,9 @@ "CheatModeBehavior": "OnByDefault", // Whether to enable rare drop notifications by default. Players can toggle - // this behavior for themselves with the $rarenotifs command. - "RareNotificationsEnabledByDefault": false, + // this behavior for themselves with the $itemnotifs command. + "RareNotificationsEnabledByDefaultV1V2": false, + "RareNotificationsEnabledByDefaultV3V4": false, // Whether to enable patches on Episode 3 USA. This functionality depends on // exploiting a bug in Episode 3, and while it seems to work reliably on