From 75158f2c295bdc52ab4743b3529ce9092ccfd502 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Mon, 8 May 2023 00:28:59 -0400 Subject: handle channel moves + region change --- src/components/voiceinfobox.cpp | 39 +++++++++++++++++++++++------------- src/components/voiceinfobox.hpp | 2 ++ src/discord/discord.cpp | 44 +++++++++++++++++++++++++++++++++++++++++ src/discord/discord.hpp | 3 +++ src/discord/voiceclient.cpp | 4 ++++ src/discord/websocket.cpp | 7 ++++++- 6 files changed, 84 insertions(+), 15 deletions(-) diff --git a/src/components/voiceinfobox.cpp b/src/components/voiceinfobox.cpp index b870794..4c5a127 100644 --- a/src/components/voiceinfobox.cpp +++ b/src/components/voiceinfobox.cpp @@ -29,20 +29,7 @@ VoiceInfoBox::VoiceInfoBox() Abaddon::Get().GetDiscordClient().signal_voice_requested_connect().connect([this](Snowflake channel_id) { show(); - - if (const auto channel = Abaddon::Get().GetDiscordClient().GetChannel(channel_id); channel.has_value() && channel->Name.has_value()) { - if (channel->GuildID.has_value()) { - if (const auto guild = Abaddon::Get().GetDiscordClient().GetGuild(*channel->GuildID); guild.has_value()) { - m_location.set_label(*channel->Name + " / " + guild->Name); - return; - } - } - - m_location.set_label(*channel->Name); - return; - } - - m_location.set_label("Unknown"); + UpdateLocation(); }); Abaddon::Get().GetDiscordClient().signal_voice_requested_disconnect().connect([this]() { @@ -72,6 +59,10 @@ VoiceInfoBox::VoiceInfoBox() m_status.set_label(label); }); + Abaddon::Get().GetDiscordClient().signal_voice_channel_changed().connect([this](Snowflake channel_id) { + UpdateLocation(); + }); + AddPointerCursor(m_status_ev); m_status_ev.signal_button_press_event().connect([this](GdkEventButton *ev) -> bool { if (ev->type == GDK_BUTTON_PRESS && ev->button == GDK_BUTTON_PRIMARY) { @@ -100,4 +91,24 @@ VoiceInfoBox::VoiceInfoBox() show_all_children(); } +void VoiceInfoBox::UpdateLocation() { + auto &discord = Abaddon::Get().GetDiscordClient(); + + const auto channel_id = discord.GetVoiceChannelID(); + + if (const auto channel = discord.GetChannel(channel_id); channel.has_value() && channel->Name.has_value()) { + if (channel->GuildID.has_value()) { + if (const auto guild = discord.GetGuild(*channel->GuildID); guild.has_value()) { + m_location.set_label(*channel->Name + " / " + guild->Name); + return; + } + } + + m_location.set_label(*channel->Name); + return; + } + + m_location.set_label("Unknown"); +} + #endif diff --git a/src/components/voiceinfobox.hpp b/src/components/voiceinfobox.hpp index 74aad27..9988c63 100644 --- a/src/components/voiceinfobox.hpp +++ b/src/components/voiceinfobox.hpp @@ -12,6 +12,8 @@ public: VoiceInfoBox(); private: + void UpdateLocation(); + Gtk::Box m_left; Gtk::EventBox m_status_ev; Gtk::Label m_status; diff --git a/src/discord/discord.cpp b/src/discord/discord.cpp index 64988d2..675b640 100644 --- a/src/discord/discord.cpp +++ b/src/discord/discord.cpp @@ -2207,7 +2207,42 @@ void DiscordClient::HandleGatewayGuildMembersChunk(const GatewayMessage &msg) { } #ifdef WITH_VOICE + +/* + * When you connect to a voice channel: + * C->S: VOICE_STATE_UPDATE + * S->C: VOICE_STATE_UPDATE + * S->C: VOICE_SERVER_UPDATE + * + * A new websocket is opened to the ws specified by VOICE_SERVER_UPDATE then: + * S->C: HELLO + * C->S: IDENTIFY + * S->C: READY + * C->U: discover + * U->C: discover result + * C->S: SELECT_PROTOCOL + * S->C: SESSION_DESCRIPTION + * Done!!! + * + * When you get disconnected (no particular order): + * S->C: 4014 Disconnected (Server to voice gateway) + * S->C: VOICE_STATE_UPDATE (Server to main gateway) + * + * When you get moved: + * S->C: VOICE_STATE_UPDATE + * S->C: VOICE_SERVER_UPDATE (usually) + * S->C: 4014 Disconnected (Server to voice gateway) + * + * Key thing: 4014 Disconnected can come before or after or in between main gateway messages + * + * Region change: + * Same thing but close code 4000 + * + */ + void DiscordClient::HandleGatewayVoiceStateUpdate(const GatewayMessage &msg) { + spdlog::get("discord")->trace("VOICE_STATE_UPDATE"); + VoiceState data = msg.Data; if (data.UserID == m_user_data.ID) { @@ -2217,6 +2252,9 @@ void DiscordClient::HandleGatewayVoiceStateUpdate(const GatewayMessage &msg) { // channel_id = null means disconnect. stop cuz out of order maybe if (!data.ChannelID.has_value() && (m_voice.IsConnected() || m_voice.IsConnecting())) { m_voice.Stop(); + } else if (data.ChannelID.has_value()) { + m_voice_channel_id = *data.ChannelID; + m_signal_voice_channel_changed.emit(m_voice_channel_id); } } else { if (data.GuildID.has_value() && data.Member.has_value()) { @@ -2245,6 +2283,8 @@ void DiscordClient::HandleGatewayVoiceStateUpdate(const GatewayMessage &msg) { } void DiscordClient::HandleGatewayVoiceServerUpdate(const GatewayMessage &msg) { + spdlog::get("discord")->trace("VOICE_SERVER_UPDATE"); + VoiceServerUpdateData data = msg.Data; spdlog::get("discord")->debug("Voice server endpoint: {}", data.Endpoint); spdlog::get("discord")->debug("Voice token: {}", data.Token); @@ -3055,4 +3095,8 @@ DiscordClient::type_signal_voice_requested_disconnect DiscordClient::signal_voic DiscordClient::type_signal_voice_client_state_update DiscordClient::signal_voice_client_state_update() { return m_signal_voice_client_state_update; } + +DiscordClient::type_signal_voice_channel_changed DiscordClient::signal_voice_channel_changed() { + return m_signal_voice_channel_changed; +} #endif diff --git a/src/discord/discord.hpp b/src/discord/discord.hpp index aadb72d..cb76ef6 100644 --- a/src/discord/discord.hpp +++ b/src/discord/discord.hpp @@ -454,6 +454,7 @@ public: using type_signal_voice_requested_connect = sigc::signal; using type_signal_voice_requested_disconnect = sigc::signal; using type_signal_voice_client_state_update = sigc::signal; + using type_signal_voice_channel_changed = sigc::signal; #endif type_signal_gateway_ready signal_gateway_ready(); @@ -520,6 +521,7 @@ public: type_signal_voice_requested_connect signal_voice_requested_connect(); type_signal_voice_requested_disconnect signal_voice_requested_disconnect(); type_signal_voice_client_state_update signal_voice_client_state_update(); + type_signal_voice_channel_changed signal_voice_channel_changed(); #endif protected: @@ -587,5 +589,6 @@ protected: type_signal_voice_requested_connect m_signal_voice_requested_connect; type_signal_voice_requested_disconnect m_signal_voice_requested_disconnect; type_signal_voice_client_state_update m_signal_voice_client_state_update; + type_signal_voice_channel_changed m_signal_voice_channel_changed; #endif }; diff --git a/src/discord/voiceclient.cpp b/src/discord/voiceclient.cpp index c58d4b8..c37ba7b 100644 --- a/src/discord/voiceclient.cpp +++ b/src/discord/voiceclient.cpp @@ -166,6 +166,10 @@ DiscordVoiceClient::~DiscordVoiceClient() { } void DiscordVoiceClient::Start() { + if (IsConnected() || IsConnecting()) { + Stop(); + } + SetState(State::ConnectingToWebsocket); m_ssrc_map.clear(); m_heartbeat_waiter.revive(); diff --git a/src/discord/websocket.cpp b/src/discord/websocket.cpp index d40d057..f886e69 100644 --- a/src/discord/websocket.cpp +++ b/src/discord/websocket.cpp @@ -49,7 +49,12 @@ void Websocket::Stop() { void Websocket::Stop(uint16_t code) { m_log->debug("Stopping with close code {}", code); - m_websocket-> stop(code); + m_websocket->stop(code); + m_log->trace("Socket::stop complete"); + while (Gtk::Main::events_pending()) { + Gtk::Main::iteration(); + } + m_log->trace("No events pending"); } void Websocket::Send(const std::string &str) { -- cgit v1.2.3