From 4e9f713975b7e4275d718efa153907d72c401410 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Wed, 19 Feb 2025 02:30:38 -0500 Subject: [PATCH 1/4] Initial websocket rewrite with curl ws --- CMakeLists.txt | 31 +--- src/discord/discord.cpp | 6 +- src/discord/discord.hpp | 2 +- src/discord/voiceclient.cpp | 8 +- src/discord/voiceclient.hpp | 2 +- src/discord/websocket.cpp | 212 +++++++++++++++++++++++----- src/discord/websocket.hpp | 59 ++++++-- src/remoteauth/remoteauthclient.cpp | 13 +- src/remoteauth/remoteauthclient.hpp | 2 +- 9 files changed, 248 insertions(+), 87 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 49bc2ece..f6334282 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(abaddon) set(ABADDON_RESOURCE_DIR "${CMAKE_INSTALL_PREFIX}/share/abaddon" CACHE PATH "Fallback directory for resources on Linux") -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") option(USE_LIBHANDY "Enable features that require libhandy (default)" ON) @@ -19,15 +19,7 @@ find_package(CURL) find_package(ZLIB REQUIRED) find_package(SQLite3 REQUIRED) find_package(gtkmm REQUIRED) - -set(USE_TLS TRUE) -set(USE_OPEN_SSL TRUE) -find_package(IXWebSocket QUIET) -if (NOT IXWebSocket_FOUND) - message("ixwebsocket was not found and will be included as a submodule") - add_subdirectory(subprojects/ixwebsocket) - include_directories(IXWEBSOCKET_INCLUDE_DIRS) -endif () +find_package(OpenSSL REQUIRED) if (MINGW OR WIN32) link_libraries(ws2_32) @@ -82,24 +74,6 @@ else () target_sources(abaddon PRIVATE src/notifications/notifier_fallback.cpp) endif () -if (IXWebSocket_LIBRARIES) - target_link_libraries(abaddon ${IXWebSocket_LIBRARIES}) - find_library(MBEDTLS_X509_LIBRARY mbedx509) - find_library(MBEDTLS_TLS_LIBRARY mbedtls) - find_library(MBEDTLS_CRYPTO_LIBRARY mbedcrypto) - if (MBEDTLS_TLS_LIBRARY) - target_link_libraries(abaddon ${MBEDTLS_TLS_LIBRARY}) - endif () - if (MBEDTLS_X509_LIBRARY) - target_link_libraries(abaddon ${MBEDTLS_X509_LIBRARY}) - endif () - if (MBEDTLS_CRYPTO_LIBRARY) - target_link_libraries(abaddon ${MBEDTLS_CRYPTO_LIBRARY}) - endif () -else () - target_link_libraries(abaddon $) -endif () - find_package(Threads) if (Threads_FOUND) target_link_libraries(abaddon Threads::Threads) @@ -120,6 +94,7 @@ target_link_libraries(abaddon ${NLOHMANN_JSON_LIBRARIES}) target_link_libraries(abaddon ${CMAKE_DL_LIBS}) target_link_libraries(abaddon CURL::libcurl) +target_link_libraries(abaddon OpenSSL::SSL OpenSSL::Crypto) include(CheckAtomic) if (NOT HAVE_CXX_ATOMICS_WITHOUT_LIB OR NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB) diff --git a/src/discord/discord.cpp b/src/discord/discord.cpp index 34600ea3..9ea2dad1 100644 --- a/src/discord/discord.cpp +++ b/src/discord/discord.cpp @@ -2768,7 +2768,7 @@ EPremiumType DiscordClient::GetSelfPremiumType() const { void DiscordClient::HeartbeatThread() { while (m_client_connected) { if (!m_heartbeat_acked) { - printf("wow! a heartbeat wasn't acked! how could this happen?"); + spdlog::get("discord")->warn("Heartbeat not acked"); } m_heartbeat_acked = false; @@ -2855,8 +2855,8 @@ void DiscordClient::SetSuperPropertiesFromIdentity(const IdentifyMessage &identi void DiscordClient::HandleSocketOpen() { } -void DiscordClient::HandleSocketClose(const ix::WebSocketCloseInfo &info) { - auto close_code = static_cast(info.code); +void DiscordClient::HandleSocketClose(const Websocket::CloseInfo &info) { + auto close_code = static_cast(info.Code); auto cb = [this, close_code]() { m_heartbeat_waiter.kill(); if (m_heartbeat_thread.joinable()) m_heartbeat_thread.join(); diff --git a/src/discord/discord.hpp b/src/discord/discord.hpp index e1c9c402..2cebaa2b 100644 --- a/src/discord/discord.hpp +++ b/src/discord/discord.hpp @@ -328,7 +328,7 @@ class DiscordClient { void SetSuperPropertiesFromIdentity(const IdentifyMessage &identity); void HandleSocketOpen(); - void HandleSocketClose(const ix::WebSocketCloseInfo &info); + void HandleSocketClose(const Websocket::CloseInfo &info); static bool CheckCode(const http::response_type &r); static bool CheckCode(const http::response_type &r, int expected); diff --git a/src/discord/voiceclient.cpp b/src/discord/voiceclient.cpp index f021e49f..e34127fe 100644 --- a/src/discord/voiceclient.cpp +++ b/src/discord/voiceclient.cpp @@ -414,11 +414,11 @@ void DiscordVoiceClient::OnWebsocketOpen() { SetState(State::EstablishingConnection); } -void DiscordVoiceClient::OnWebsocketClose(const ix::WebSocketCloseInfo &info) { - if (info.remote) { - m_log->debug("Websocket closed (remote): {} ({})", info.code, info.reason); +void DiscordVoiceClient::OnWebsocketClose(const Websocket::CloseInfo &info) { + if (info.Remote) { + m_log->debug("Websocket closed (remote): {} ({})", info.Code, info.Reason); } else { - m_log->debug("Websocket closed (local): {} ({})", info.code, info.reason); + m_log->debug("Websocket closed (local): {} ({})", info.Code, info.Reason); } } diff --git a/src/discord/voiceclient.hpp b/src/discord/voiceclient.hpp index aa1014cf..bb3117e4 100644 --- a/src/discord/voiceclient.hpp +++ b/src/discord/voiceclient.hpp @@ -242,7 +242,7 @@ class DiscordVoiceClient { void SelectProtocol(const char *ip, uint16_t port); void OnWebsocketOpen(); - void OnWebsocketClose(const ix::WebSocketCloseInfo &info); + void OnWebsocketClose(const Websocket::CloseInfo &info); void OnWebsocketMessage(const std::string &str); void HeartbeatThread(); diff --git a/src/discord/websocket.cpp b/src/discord/websocket.cpp index 565c94cf..5c5c05fe 100644 --- a/src/discord/websocket.cpp +++ b/src/discord/websocket.cpp @@ -1,23 +1,22 @@ #include "websocket.hpp" -#include - #include #include - -Websocket::Websocket(const std::string &id) - : m_close_info { 1000, "Normal", false } { +Websocket::Websocket(const std::string &id) { if (m_log = spdlog::get(id); !m_log) { m_log = spdlog::stdout_color_mt(id); } + m_websocket = curl_easy_init(); + curl_easy_setopt(m_websocket, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(m_websocket, CURLOPT_CONNECT_ONLY, 2L); + m_open_dispatcher.connect([this]() { m_signal_open.emit(); }); m_close_dispatcher.connect([this]() { - Stop(); m_signal_close.emit(m_close_info); }); } @@ -25,17 +24,18 @@ Websocket::Websocket(const std::string &id) void Websocket::StartConnection(const std::string &url) { m_log->debug("Starting connection to {}", url); - m_websocket = std::make_unique(); + m_sent_close = false; + m_state = State::Connecting; + + std::scoped_lock lock(m_mutex); + curl_easy_setopt(m_websocket, CURLOPT_URL, url.c_str()); - m_websocket->disableAutomaticReconnection(); - m_websocket->setUrl(url); - m_websocket->setOnMessageCallback([this](auto &&msg) { OnMessage(std::forward(msg)); }); - m_websocket->setExtraHeaders(ix::WebSocketHttpHeaders { { "User-Agent", m_agent }, { "Origin", "https://discord.com" } }); // idk if this actually works - m_websocket->start(); + m_thread = std::thread(&Websocket::Task, this); } void Websocket::SetUserAgent(std::string agent) { - m_agent = std::move(agent); + std::scoped_lock lock(m_mutex); + curl_easy_setopt(m_websocket, CURLOPT_USERAGENT, agent.c_str()); } bool Websocket::GetPrintMessages() const noexcept { @@ -48,12 +48,36 @@ void Websocket::SetPrintMessages(bool show) noexcept { void Websocket::Stop() { m_log->debug("Stopping with default close code"); - Stop(ix::WebSocketCloseConstants::kNormalClosureCode); + Stop(1000); } void Websocket::Stop(uint16_t code) { + if (m_state == State::Closing) { + m_log->debug("Attempting to stop while in Closing state"); + return; + } + + if (m_state == State::Closed) { + m_log->debug("Attempting to stop while in Closed state"); + return; + } + m_log->debug("Stopping with close code {}", code); - m_websocket->stop(code); + + m_state = State::Closing; + + { + std::vector payload = { static_cast(code >> 8), static_cast(code & 0xFF) }; + m_sent_close = true; + { + std::scoped_lock lock(m_mutex); + size_t sent; + curl_ws_send(m_websocket, payload.data(), payload.size(), &sent, 0, CURLWS_CLOSE); + } + std::unique_lock lock(m_close_mutex); + m_close_cv.wait(lock); + } + m_log->trace("Socket::stop complete"); while (Gtk::Main::events_pending()) { Gtk::Main::iteration(); @@ -62,38 +86,160 @@ void Websocket::Stop(uint16_t code) { } void Websocket::Send(const std::string &str) { + if (m_state != State::Open) { + m_log->warn("Attempt to send on non-open state"); + return; + } + if (m_print_messages) m_log->trace("Send: {}", str); - m_websocket->sendText(str); + + std::scoped_lock lock(m_mutex); + + size_t offset = 0; + while (true) { + size_t sent; + auto code = curl_ws_send(m_websocket, str.data() + offset, str.size() - offset, &sent, 0, CURLWS_TEXT); + offset += sent; + if (code == CURLE_OK) { + if (offset >= str.size()) { + break; + } + } else if (code == CURLE_AGAIN) { + continue; + } else { + m_log->error("Websocket::Send: {}", curl_easy_strerror(code)); + break; + } + } } void Websocket::Send(const nlohmann::json &j) { Send(j.dump()); } -void Websocket::OnMessage(const ix::WebSocketMessagePtr &msg) { - switch (msg->type) { - case ix::WebSocketMessageType::Open: { - m_log->debug("Received open frame, dispatching"); - m_open_dispatcher.emit(); - } break; - case ix::WebSocketMessageType::Close: { - const auto remote = msg->closeInfo.remote ? " Remote" : ""; - m_log->debug("Received close frame, dispatching. {} ({}){}", msg->closeInfo.code, msg->closeInfo.reason, remote); - m_close_info = msg->closeInfo; +void Websocket::OnMessage(const WebSocketMessage &message) { + switch (message.Type) { + case WebSocketMessage::MessageType::binary: + case WebSocketMessage::MessageType::text: { + m_log->trace("Received {} bytes", message.Data.size()); + std::string payload = std::string(message.Data.begin(), message.Data.end()); + m_signal_message.emit(payload); + break; + } + case WebSocketMessage::MessageType::close: { + m_close_info = message.CloseInfo; + m_close_info.Remote = !m_sent_close; + + m_log->debug( + "Received close frame{}, dispatching. {} ({})", + m_close_info.Remote ? " (Remote)" : "", + message.CloseInfo.Code, + message.CloseInfo.Reason); + m_close_cv.notify_all(); m_close_dispatcher.emit(); - } break; - case ix::WebSocketMessageType::Message: { - m_signal_message.emit(msg->str); - } break; - case ix::WebSocketMessageType::Error: { - m_log->error("Websocket error: Status: {} Reason: {}", msg->errorInfo.http_status, msg->errorInfo.reason); - } break; + break; + } default: break; } } +std::expected Websocket::ReceiveMessage() { + WebSocketMessage message; + + curl_socket_t socket; + { + std::scoped_lock lock(m_mutex); + curl_easy_getinfo(m_websocket, CURLINFO_ACTIVESOCKET, &socket); + } + + while (m_state == State::Open || m_state == State::Closing) { + if (m_state == State::Closing && !m_sent_close) { + // if were closing and we didnt send the close then server already did + return std::unexpected(Error::closing); + } + + fd_set rfds; + FD_ZERO(&rfds); + FD_SET(socket, &rfds); + + timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + + if (select(socket + 1, &rfds, nullptr, nullptr, &tv) == -1) { + return std::unexpected(Websocket::Error::select_error); + } + + size_t rlen; + const curl_ws_frame *meta; + char buffer[256]; + + std::scoped_lock lock(m_mutex); + + auto code = curl_ws_recv(m_websocket, buffer, sizeof(buffer), &rlen, &meta); + if (code != CURLE_OK) { + if (code == CURLE_AGAIN) { + continue; + } else { + return std::unexpected(Websocket::Error::recv_error); + } + } + + if (meta->flags & CURLWS_PING) { + message.Type = WebSocketMessage::MessageType::ping; + } else if (meta->flags & CURLWS_TEXT) { + message.Type = WebSocketMessage::MessageType::text; + } else if (meta->flags & CURLWS_BINARY) { + message.Type = WebSocketMessage::MessageType::binary; + } else if (meta->flags & CURLWS_CLOSE) { + message.Type = WebSocketMessage::MessageType::close; + message.CloseInfo.Code = (static_cast(buffer[0]) << 8) | static_cast(buffer[1]); + message.CloseInfo.Reason = std::string(buffer + 2, rlen - 2); + if (m_sent_close) { + m_state = State::Closed; + } else { + m_state = State::Closing; + } + } + + message.Data.insert(message.Data.end(), buffer, buffer + rlen); + + if (meta->bytesleft == 0 && (meta->flags & CURLWS_CONT) == 0) { + break; + } + } + + return message; +} + +void Websocket::Task() { + CURLcode res; + + { + std::scoped_lock lock(m_mutex); + res = curl_easy_perform(m_websocket); + } + if (res != CURLE_OK) { + m_state = State::Closed; + m_log->error("Error: {}", curl_easy_strerror(res)); + } else { + m_state = State::Open; + m_open_dispatcher.emit(); + + while (true) { + auto msg = ReceiveMessage(); + if (msg.has_value()) { + OnMessage(msg.value()); + } + } + } + + std::scoped_lock lock(m_mutex); + curl_easy_cleanup(m_websocket); +} + Websocket::type_signal_open Websocket::signal_open() { return m_signal_open; } diff --git a/src/discord/websocket.hpp b/src/discord/websocket.hpp index a77bf553..9bfdf65c 100644 --- a/src/discord/websocket.hpp +++ b/src/discord/websocket.hpp @@ -1,12 +1,10 @@ #pragma once -#include -#include +#include #include -#include #include #include -#include #include +#include class Websocket { public: @@ -23,15 +21,57 @@ class Websocket { void Stop(); void Stop(uint16_t code); + enum class Error { + recv_error, + select_error, + closing, + }; + + enum class State { + Closed, + Connecting, + Open, + Closing, + }; + + struct CloseInfo { + bool Remote; + uint16_t Code; + std::string Reason; + }; + private: - void OnMessage(const ix::WebSocketMessagePtr &msg); + struct WebSocketMessage { + enum class MessageType { + ping, + text, + binary, + close, + }; + + CloseInfo CloseInfo {}; + + std::vector Data; + MessageType Type; + }; - std::unique_ptr m_websocket; - std::string m_agent; + State m_state = State::Closed; + + void OnMessage(const WebSocketMessage &message); + std::expected ReceiveMessage(); + void Task(); + + mutable std::mutex m_mutex; + std::thread m_thread; + CURL *m_websocket = nullptr; + + std::atomic m_sent_close = false; + mutable std::mutex m_close_mutex; + std::condition_variable m_close_cv; public: using type_signal_open = sigc::signal; - using type_signal_close = sigc::signal; + using type_signal_close = sigc::signal; using type_signal_message = sigc::signal; type_signal_open signal_open(); @@ -45,9 +85,10 @@ class Websocket { bool m_print_messages = true; + CloseInfo m_close_info; + Glib::Dispatcher m_open_dispatcher; Glib::Dispatcher m_close_dispatcher; - ix::WebSocketCloseInfo m_close_info; std::shared_ptr m_log; }; diff --git a/src/remoteauth/remoteauthclient.cpp b/src/remoteauth/remoteauthclient.cpp index fb688888..dea19f81 100644 --- a/src/remoteauth/remoteauthclient.cpp +++ b/src/remoteauth/remoteauthclient.cpp @@ -10,7 +10,6 @@ #include "abaddon.hpp" #include "http.hpp" - // clang-format on RemoteAuthClient::RemoteAuthClient() @@ -280,16 +279,16 @@ void RemoteAuthClient::OnWebsocketOpen() { m_log->info("Websocket opened"); } -void RemoteAuthClient::OnWebsocketClose(const ix::WebSocketCloseInfo &info) { - if (info.remote) { - m_log->debug("Websocket closed (remote): {} ({})", info.code, info.reason); +void RemoteAuthClient::OnWebsocketClose(const Websocket::CloseInfo &info) { + if (info.Remote) { + m_log->debug("Websocket closed (remote): {} ({})", info.Code, info.Reason); if (m_connected) { - m_signal_error.emit("Error. Websocket closed (remote): " + std::to_string(info.code) + " (" + info.reason + ")"); + m_signal_error.emit("Error. Websocket closed (remote): " + std::to_string(info.Code) + " (" + info.Reason + ")"); } } else { - m_log->debug("Websocket closed (local): {} ({})", info.code, info.reason); + m_log->debug("Websocket closed (local): {} ({})", info.Code, info.Reason); if (m_connected) { - m_signal_error.emit("Error. Websocket closed (local): " + std::to_string(info.code) + " (" + info.reason + ")"); + m_signal_error.emit("Error. Websocket closed (local): " + std::to_string(info.Code) + " (" + info.Reason + ")"); } } } diff --git a/src/remoteauth/remoteauthclient.hpp b/src/remoteauth/remoteauthclient.hpp index d9114747..28e368e8 100644 --- a/src/remoteauth/remoteauthclient.hpp +++ b/src/remoteauth/remoteauthclient.hpp @@ -47,7 +47,7 @@ class RemoteAuthClient { std::vector Decrypt(const unsigned char *in, size_t inlen) const; void OnWebsocketOpen(); - void OnWebsocketClose(const ix::WebSocketCloseInfo &info); + void OnWebsocketClose(const Websocket::CloseInfo &info); void OnWebsocketMessage(const std::string &str); void HeartbeatThread(); From 81e7f8475377f4184750973b2374174c78c310f2 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Wed, 19 Feb 2025 02:53:52 -0500 Subject: [PATCH 2/4] change standard back to 17 --- CMakeLists.txt | 2 +- src/discord/websocket.cpp | 8 ++++---- src/discord/websocket.hpp | 9 +-------- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f6334282..10d667a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(abaddon) set(ABADDON_RESOURCE_DIR "${CMAKE_INSTALL_PREFIX}/share/abaddon" CACHE PATH "Fallback directory for resources on Linux") -set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") option(USE_LIBHANDY "Enable features that require libhandy (default)" ON) diff --git a/src/discord/websocket.cpp b/src/discord/websocket.cpp index 5c5c05fe..6cfeda66 100644 --- a/src/discord/websocket.cpp +++ b/src/discord/websocket.cpp @@ -145,7 +145,7 @@ void Websocket::OnMessage(const WebSocketMessage &message) { } } -std::expected Websocket::ReceiveMessage() { +std::optional Websocket::ReceiveMessage() { WebSocketMessage message; curl_socket_t socket; @@ -157,7 +157,7 @@ std::expected Websocket::ReceiveM while (m_state == State::Open || m_state == State::Closing) { if (m_state == State::Closing && !m_sent_close) { // if were closing and we didnt send the close then server already did - return std::unexpected(Error::closing); + return {}; } fd_set rfds; @@ -169,7 +169,7 @@ std::expected Websocket::ReceiveM tv.tv_usec = 0; if (select(socket + 1, &rfds, nullptr, nullptr, &tv) == -1) { - return std::unexpected(Websocket::Error::select_error); + return {}; } size_t rlen; @@ -183,7 +183,7 @@ std::expected Websocket::ReceiveM if (code == CURLE_AGAIN) { continue; } else { - return std::unexpected(Websocket::Error::recv_error); + return {}; } } diff --git a/src/discord/websocket.hpp b/src/discord/websocket.hpp index 9bfdf65c..6c2fada7 100644 --- a/src/discord/websocket.hpp +++ b/src/discord/websocket.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include #include @@ -21,12 +20,6 @@ class Websocket { void Stop(); void Stop(uint16_t code); - enum class Error { - recv_error, - select_error, - closing, - }; - enum class State { Closed, Connecting, @@ -58,7 +51,7 @@ class Websocket { State m_state = State::Closed; void OnMessage(const WebSocketMessage &message); - std::expected ReceiveMessage(); + std::optional ReceiveMessage(); void Task(); mutable std::mutex m_mutex; From f67b8fa72df6d48da75b63178287361412b56c14 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Wed, 19 Feb 2025 19:01:48 -0500 Subject: [PATCH 3/4] fix build --- src/discord/voiceclient.hpp | 6 ++++++ src/discord/websocket.cpp | 10 +++++----- src/discord/websocket.hpp | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/discord/voiceclient.hpp b/src/discord/voiceclient.hpp index bb3117e4..af4b94f7 100644 --- a/src/discord/voiceclient.hpp +++ b/src/discord/voiceclient.hpp @@ -13,6 +13,12 @@ #include #include #include + +#ifndef _WIN32 +#include +#include +#include +#endif // clang-format on enum class VoiceGatewayCloseCode : uint16_t { diff --git a/src/discord/websocket.cpp b/src/discord/websocket.cpp index 6cfeda66..c8e9bc86 100644 --- a/src/discord/websocket.cpp +++ b/src/discord/websocket.cpp @@ -128,14 +128,14 @@ void Websocket::OnMessage(const WebSocketMessage &message) { break; } case WebSocketMessage::MessageType::close: { - m_close_info = message.CloseInfo; + m_close_info = message.Close; m_close_info.Remote = !m_sent_close; m_log->debug( "Received close frame{}, dispatching. {} ({})", m_close_info.Remote ? " (Remote)" : "", - message.CloseInfo.Code, - message.CloseInfo.Reason); + message.Close.Code, + message.Close.Reason); m_close_cv.notify_all(); m_close_dispatcher.emit(); break; @@ -195,8 +195,8 @@ std::optional Websocket::ReceiveMessage() { message.Type = WebSocketMessage::MessageType::binary; } else if (meta->flags & CURLWS_CLOSE) { message.Type = WebSocketMessage::MessageType::close; - message.CloseInfo.Code = (static_cast(buffer[0]) << 8) | static_cast(buffer[1]); - message.CloseInfo.Reason = std::string(buffer + 2, rlen - 2); + message.Close.Code = (static_cast(buffer[0]) << 8) | static_cast(buffer[1]); + message.Close.Reason = std::string(buffer + 2, rlen - 2); if (m_sent_close) { m_state = State::Closed; } else { diff --git a/src/discord/websocket.hpp b/src/discord/websocket.hpp index 6c2fada7..2d951e1e 100644 --- a/src/discord/websocket.hpp +++ b/src/discord/websocket.hpp @@ -42,7 +42,7 @@ class Websocket { close, }; - CloseInfo CloseInfo {}; + CloseInfo Close {}; std::vector Data; MessageType Type; From 1c9e2ace8ec274be28d1e3d01297b497d222d27d Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Wed, 19 Feb 2025 19:20:47 -0500 Subject: [PATCH 4/4] update workflow --- .github/workflows/ci.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a3ef6a59..347ca27e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -193,19 +193,28 @@ jobs: cd deps git clone https://github.com/nlohmann/json cd json - git checkout bc889afb4c5bf1c0d8ee29ef35eaaf4c8bef8a5d + git checkout 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03 mkdir build cd build - cmake .. + cmake -DJSON_BuildTests=OFF .. make sudo make install sudo apt-get install libgtkmm-3.0-dev - sudo apt-get install libcurl4-gnutls-dev sudo apt-get install libopus-dev sudo apt-get install libsodium-dev sudo apt-get install libspdlog-dev sudo apt-get install libhandy-1-dev + - name: Build curl from source + run: | + sudo apt-get install libbrotli-dev libidn2-dev libnghttp2-dev libpsl-dev libzstd-dev zlib1g-dev libidn-dev + wget https://github.com/curl/curl/releases/download/curl-8_12_1/curl-8.12.1.tar.xz + tar -xf curl-8.12.1.tar.xz + cd curl-8.12.1 + cmake . + make + sudo make install + - name: Build uses: lukka/run-cmake@v3 env: