From 255878bf601b8069044cd3f31b5d73e9392b098a Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Sun, 18 Feb 2024 09:33:21 -0800 Subject: [PATCH] add $itemnotifs every mode --- README.md | 6 +++++- src/ChatCommands.cc | 16 +++++++-------- src/Client.cc | 22 +++++++++++++++++++- src/Client.hh | 13 ++++++++++-- src/ReceiveCommands.cc | 43 ++++++++++++++++++++++++--------------- src/ReceiveSubcommands.cc | 26 ++++++++++++++++------- 6 files changed, 91 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index c520abb1..9c1d75ce 100644 --- a/README.md +++ b/README.md @@ -364,7 +364,11 @@ 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. - * `$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. + * `$itemnotifs `: Enables item drop notification messages. 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' drops. The modes are: + * `off`: No notifications are shown. + * `rare`: You are notified when a rare item drops. + * `on`: You are notified when any item drops, except Meseta. + * `every`: You are notified when any item drops, including Meseta. * `$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 4d82b1d9..50c5b4bd 100644 --- a/src/ChatCommands.cc +++ b/src/ChatCommands.cc @@ -1553,20 +1553,20 @@ static void proxy_command_song(shared_ptr ses, const } 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); + if (args == "every" || args == "everything") { + config.set_drop_notification_mode(Client::ItemDropNotificationMode::ALL_ITEMS_INCLUDING_MESETA); + send_text_message_printf(ch, "$C6Notifications enabled\nfor all items and\nMeseta"); + } else if (args == "all" || args == "on") { + config.set_drop_notification_mode(Client::ItemDropNotificationMode::ALL_ITEMS); 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); + config.set_drop_notification_mode(Client::ItemDropNotificationMode::RARES_ONLY); 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); + config.set_drop_notification_mode(Client::ItemDropNotificationMode::NOTHING); 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"); + send_text_message_printf(ch, "$C6You must specify\n$C6off$C7, $C6rare$C7, $C6on$C7, or\n$C6everything$C7"); } } diff --git a/src/Client.cc b/src/Client.cc index 9a8a5348..3d198b4a 100644 --- a/src/Client.cc +++ b/src/Client.cc @@ -135,6 +135,26 @@ void Client::Config::set_flags_for_version(Version version, int64_t sub_version) } } +Client::ItemDropNotificationMode Client::Config::get_drop_notification_mode() const { + uint8_t mode_s = (this->check_flag(Flag::ITEM_DROP_NOTIFICATIONS_1) ? 1 : 0) | + (this->check_flag(Flag::ITEM_DROP_NOTIFICATIONS_2) ? 2 : 0); + return static_cast(mode_s); +} + +void Client::Config::set_drop_notification_mode(ItemDropNotificationMode new_mode) { + uint8_t mode_s = static_cast(new_mode); + if (mode_s & 1) { + this->set_flag(Client::Flag::ITEM_DROP_NOTIFICATIONS_1); + } else { + this->clear_flag(Client::Flag::ITEM_DROP_NOTIFICATIONS_1); + } + if (mode_s & 2) { + this->set_flag(Client::Flag::ITEM_DROP_NOTIFICATIONS_2); + } else { + this->clear_flag(Client::Flag::ITEM_DROP_NOTIFICATIONS_2); + } +} + bool Client::Config::should_update_vs(const Config& other) const { constexpr uint64_t mask = static_cast(Flag::CLIENT_SIDE_MASK); return ((this->enabled_flags ^ other.enabled_flags) & mask) || @@ -197,7 +217,7 @@ Client::Client( this->config.set_flags_for_version(version, -1); 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.set_drop_notification_mode(ItemDropNotificationMode::RARES_ONLY); } this->config.specific_version = default_specific_version_for_version(version, -1); diff --git a/src/Client.hh b/src/Client.hh index 3216cbe0..960f206f 100644 --- a/src/Client.hh +++ b/src/Client.hh @@ -72,8 +72,8 @@ public: INFINITE_HP_ENABLED = 0x0000000200000000, INFINITE_TP_ENABLED = 0x0000000400000000, DEBUG_ENABLED = 0x0000000800000000, - RARE_DROP_NOTIFICATIONS_ENABLED = 0x0010000000000000, - ALL_DROP_NOTIFICATIONS_ENABLED = 0x0020000000000000, + ITEM_DROP_NOTIFICATIONS_1 = 0x0010000000000000, + ITEM_DROP_NOTIFICATIONS_2 = 0x0020000000000000, // Proxy option flags PROXY_SAVE_FILES = 0x0000001000000000, @@ -90,6 +90,12 @@ public: PROXY_EP3_UNMASK_WHISPERS = 0x0008000000000000, // clang-format on }; + enum class ItemDropNotificationMode { + NOTHING = 0, + RARES_ONLY = 1, + ALL_ITEMS = 2, + ALL_ITEMS_INCLUDING_MESETA = 3, + }; static constexpr uint64_t DEFAULT_FLAGS = static_cast(Flag::PROXY_CHAT_COMMANDS_ENABLED); @@ -129,6 +135,9 @@ public: void set_flags_for_version(Version version, int64_t sub_version); + ItemDropNotificationMode get_drop_notification_mode() const; + void set_drop_notification_mode(ItemDropNotificationMode new_mode); + template void parse_from(const parray& data) { StringReader r(data.data(), data.size()); diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index 3bd6af50..4fdd25d7 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -49,14 +49,21 @@ static shared_ptr proxy_options_menu_for_client(shared_ptrversion())) { - 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); + switch (c->config.get_drop_notification_mode()) { + case Client::ItemDropNotificationMode::NOTHING: + ret->items.emplace_back(ProxyOptionsMenuItemID::DROP_NOTIFICATIONS, "No drop notifs", item_drop_notifs_description, 0); + break; + case Client::ItemDropNotificationMode::RARES_ONLY: + ret->items.emplace_back(ProxyOptionsMenuItemID::DROP_NOTIFICATIONS, "Rare drop notifs", item_drop_notifs_description, 0); + break; + case Client::ItemDropNotificationMode::ALL_ITEMS: + ret->items.emplace_back(ProxyOptionsMenuItemID::DROP_NOTIFICATIONS, "Item drop notifs", item_drop_notifs_description, 0); + break; + case Client::ItemDropNotificationMode::ALL_ITEMS_INCLUDING_MESETA: + ret->items.emplace_back(ProxyOptionsMenuItemID::DROP_NOTIFICATIONS, "Every drop notif", item_drop_notifs_description, 0); + break; } } add_flag_option(ProxyOptionsMenuItemID::BLOCK_PINGS, Client::Flag::PROXY_SUPPRESS_CLIENT_PINGS, @@ -2304,15 +2311,19 @@ static void on_10(shared_ptr c, uint16_t, uint32_t, string& data) { 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); + switch (c->config.get_drop_notification_mode()) { + case Client::ItemDropNotificationMode::NOTHING: + c->config.set_drop_notification_mode(Client::ItemDropNotificationMode::RARES_ONLY); + break; + case Client::ItemDropNotificationMode::RARES_ONLY: + c->config.set_drop_notification_mode(Client::ItemDropNotificationMode::ALL_ITEMS); + break; + case Client::ItemDropNotificationMode::ALL_ITEMS: + c->config.set_drop_notification_mode(Client::ItemDropNotificationMode::ALL_ITEMS_INCLUDING_MESETA); + break; + case Client::ItemDropNotificationMode::ALL_ITEMS_INCLUDING_MESETA: + c->config.set_drop_notification_mode(Client::ItemDropNotificationMode::NOTHING); + break; } goto resend_proxy_options_menu; case ProxyOptionsMenuItemID::BLOCK_PINGS: diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index 1eba48bb..a3776543 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -1593,15 +1593,27 @@ void send_item_notification_if_needed( 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); + bool should_notify = false; + bool should_include_rare_header = false; + switch (config.get_drop_notification_mode()) { + case Client::ItemDropNotificationMode::NOTHING: + break; + case Client::ItemDropNotificationMode::RARES_ONLY: + should_notify = (is_from_rare_table || (item.data1[0] == 0x03)) && s->item_parameter_table(ch.version)->is_item_rare(item); + should_include_rare_header = true; + break; + case Client::ItemDropNotificationMode::ALL_ITEMS: + should_notify = (item.data1[0] != 0x04); + break; + case Client::ItemDropNotificationMode::ALL_ITEMS_INCLUDING_MESETA: + should_notify = true; + break; + } - } 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)) { + if (should_notify) { string name = s->describe_item(ch.version, item, true); - send_text_message_printf(ch, "$C6Rare item dropped:\n%s", name.c_str()); + const char* rare_header = (should_include_rare_header ? "$C6Rare item dropped:\n" : ""); + send_text_message_printf(ch, "%s%s", rare_header, name.c_str()); } }