diff options
author | ouwou <26526779+ouwou@users.noreply.github.com> | 2020-08-17 02:40:03 -0400 |
---|---|---|
committer | ouwou <26526779+ouwou@users.noreply.github.com> | 2020-08-17 02:40:03 -0400 |
commit | 18af78e6af49821f8c7adb5b4325d75c8bf4fd03 (patch) | |
tree | 2a2812d604fa0b00891613e868a79972159886aa /discord/discord.hpp | |
parent | 212511e29d01af9b096e91371956b28de834bd13 (diff) | |
download | abaddon-portaudio-18af78e6af49821f8c7adb5b4325d75c8bf4fd03.tar.gz abaddon-portaudio-18af78e6af49821f8c7adb5b4325d75c8bf4fd03.zip |
connect and heartbeat
Diffstat (limited to 'discord/discord.hpp')
-rw-r--r-- | discord/discord.hpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/discord/discord.hpp b/discord/discord.hpp new file mode 100644 index 0000000..692d57b --- /dev/null +++ b/discord/discord.hpp @@ -0,0 +1,75 @@ +#pragma once +#include "websocket.hpp" +#include <nlohmann/json.hpp> +#include <thread> + +enum class GatewayOp : int { + Heartbeat = 1, + Hello = 10, + HeartbeatAck = 11, +}; + +struct GatewayMessage { + GatewayOp Opcode; + nlohmann::json Data; + std::string Type; + + friend void from_json(const nlohmann::json &j, GatewayMessage &m); +}; + +struct HelloMessageData { + int HeartbeatInterval; + + friend void from_json(const nlohmann::json &j, HelloMessageData &m); +}; + +struct HeartbeatMessage : GatewayMessage { + int Sequence; + + friend void to_json(nlohmann::json &j, const HeartbeatMessage &m); +}; + +// https://stackoverflow.com/questions/29775153/stopping-long-sleep-threads/29775639#29775639 +class HeartbeatWaiter { +public: + template<class R, class P> + bool wait_for(std::chrono::duration<R, P> const &time) const { + std::unique_lock<std::mutex> lock(m); + return !cv.wait_for(lock, time, [&] { return terminate; }); + } + void kill() { + std::unique_lock<std::mutex> lock(m); + terminate = true; + cv.notify_all(); + } + +private: + mutable std::condition_variable cv; + mutable std::mutex m; + bool terminate = false; +}; + +class DiscordClient { +public: + static const constexpr char *DiscordGateway = "wss://gateway.discord.gg/?v=6&encoding=json"; + static const constexpr char *DiscordAPI = "https://discord.com/api"; + +public: + DiscordClient(); + void Start(); + void Stop(); + bool IsStarted() const; + +private: + void HandleGatewayMessage(nlohmann::json msg); + void HeartbeatThread(); + + Websocket m_websocket; + bool m_client_connected = false; + + std::thread m_heartbeat_thread; + int m_last_sequence = -1; + int m_heartbeat_msec = 0; + HeartbeatWaiter m_heartbeat_waiter; + bool m_heartbeat_acked = true; +}; |