DiscordCoreAPI
A Discord bot library written in C++, with custom asynchronous coroutines.
Loading...
Searching...
No Matches
WebSocketEntities.hpp
Go to the documentation of this file.
1/*
2 DiscordCoreAPI, A bot library for Discord, written in C++, and featuring explicit multithreading through the usage of custom, asynchronous C++ CoRoutines.
3
4 Copyright 2021, 2022 Chris M. (RealTimeChris)
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 USA
20*/
21/// WebSocketEntities.hpp - Header for the webSocket related classes and
22/// structs. May 13, 2021 Chris M.
23/// https://discordcoreapi.com
24/// \file WebSocketEntities.hpp
25
26#pragma once
27
35
36namespace DiscordCoreInternal {
37
38 class DiscordCoreAPI_Dll EventConverter {
39 public:
40 EventConverter(std::string eventNew);
41
42 operator int32_t();
43
44 protected:
45 std::string eventValue{};
46 };
47
48 /// \brief For the opcodes that could be sent/received via Discord's websockets.
49 enum class WebSocketOpCodes {
50 Dispatch = 0,///< An event was dispatched.
51 Heartbeat = 1,///< Fired periodically by the client to keep the connection alive.
52 Identify = 2,///< Starts a new session during the initial handshake.
53 Presence_Update = 3,///< Update the client's presence.
54 Voice_State_Update = 4,///< Used to join/leave or move between voice channels.
55 Resume = 6,///< Resume a previous session that was disconnected.
56 Reconnect = 7,///< You should attempt to reconnect and resume immediately.
57 Request_Guild_Members = 8,///< Request information about offline guild members in a large guild.
58 Invalid_Session = 9,/// The session has been invalidated. You should reconnect and identify/resume accordingly.
59 Hello = 10,///< Sent immediately after connecting, contains the heartbeat_interval to use.
60 Heartbeat_ACK = 11,///<Sent in response to receiving a heartbeat to acknowledge that it has been received.
61 };
62
63 enum class WebSocketType { Normal = 0, Voice = 1 };
64
65 enum class WebSocketState {
66 Connecting = 0,
67 Upgrading = 1,
70 Authenticated = 4,
71 Disconnected = 5
72 };
73
74 class DiscordCoreAPI_Dll WebSocketCore : public ErlParser, public TCPSSLClient {
75 public:
76 WebSocketCore(DiscordCoreAPI::ConfigManager* configManagerNew, WebSocketType typeOfWebSocketNew);
77
78 bool connect(const std::string& baseUrl, const std::string& relativePath, const uint16_t portNew, bool doWePrintErrorsNew,
79 bool areWeAStandaloneSocketNew) noexcept;
80
81 void createHeader(std::string& outBuffer, WebSocketOpCode opCode) noexcept;
82
83 virtual bool onMessageReceived(std::string_view message) noexcept = 0;
84
85 bool sendMessage(std::string& dataToSend, bool priority) noexcept;
86
87 void parseConnectionHeaders(std::string_view stringNew) noexcept;
88
89 bool checkForAndSendHeartBeat(bool = false) noexcept;
90
91 virtual void onClosed() noexcept = 0;
92
93 void parseMessage() noexcept;
94
95 void handleBuffer() noexcept;
96
97 virtual ~WebSocketCore() noexcept = default;
98
99 protected:
100 std::unique_ptr<DiscordCoreAPI::ConnectionPackage> connections{ nullptr };
101 DiscordCoreAPI::StopWatch<Milliseconds> heartBeatStopWatch{ 20000ms };
102 DiscordCoreAPI::ConfigManager* configManager{};
103 std::atomic<WebSocketState> currentState{};
104 bool haveWeReceivedHeartbeatAck{ true };
105 const uint32_t maxReconnectTries{ 10 };
106 uint32_t currentReconnectTries{};
107 uint32_t lastNumberReceived{};
108 WebSocketClose closeCode{ 0 };
109 StringBuffer currentMessage{};
110 WebSocketOpCode dataOpCode{};
111 bool areWeHeartBeating{};
112 uint64_t messageLength{};
113 uint64_t messageOffset{};
114 WebSocketType wsType{};
115 bool areWeResuming{};
116 uint32_t shard[2]{};
117 };
118
119 class DiscordCoreAPI_Dll WebSocketClient : public WebSocketCore {
120 public:
125 friend class DiscordCoreAPI::BotUser;
126 friend class BaseSocketAgent;
127 friend class WebSocketCore;
128 friend class TCPSSLClient;
129
130 WebSocketClient(DiscordCoreAPI::DiscordCoreClient* client, int32_t currentShardNew, std::atomic_bool* doWeQuitNew);
131
132 void getVoiceConnectionData(const DiscordCoreAPI::VoiceConnectInitData& doWeCollect) noexcept;
133
134 bool onMessageReceived(std::string_view message) noexcept;
135
136 void disconnect() noexcept;
137
138 void onClosed() noexcept;
139
140 virtual ~WebSocketClient() noexcept;
141
142 protected:
143 std::unordered_map<uint64_t, DiscordCoreAPI::UnboundedMessageBlock<VoiceConnectionData>*> voiceConnectionDataBuffersMap{};
144 DiscordCoreAPI::DiscordCoreClient* discordCoreClient{ nullptr };
145 VoiceConnectionData voiceConnectionData{};
146 std::atomic_bool* doWeQuit{ nullptr };
147 DiscordCoreAPI::Snowflake userId{};
148 bool serverUpdateCollected{};
149 bool stateUpdateCollected{};
150 Jsonifier::Parser parser{};
151 bool areWeCollectingData{};
152 std::string resumeUrl{};
153 std::string sessionId{};
154 };
155
156 class DiscordCoreAPI_Dll BaseSocketAgent {
157 public:
159 friend class DiscordCoreAPI::BotUser;
160
161 BaseSocketAgent(DiscordCoreAPI::DiscordCoreClient* discordCoreClientNew, std::atomic_bool* doWeQuitNew,
162 int32_t currentBaseSocket) noexcept;
163
164 bool waitForState(DiscordCoreAPI::ConnectionPackage& packageNew, WebSocketState state) noexcept;
165
166 void connect(DiscordCoreAPI::ConnectionPackage) noexcept;
167
168 std::jthread* getTheTask() noexcept;
169
170 ~BaseSocketAgent() noexcept;
171
172 protected:
173 std::unordered_map<uint32_t, std::unique_ptr<WebSocketClient>> shardMap{};
174 DiscordCoreAPI::DiscordCoreClient* discordCoreClient{ nullptr };
175 std::unique_ptr<std::jthread> taskThread{ nullptr };
176 DiscordCoreAPI::ConfigManager* configManager{};
177 std::atomic_bool* doWeQuit{ nullptr };
178 uint32_t currentBaseSocketAgent{};
179 std::mutex accessMutex{};
180
181 void run(std::stop_token) noexcept;
182 };
183
184}// namespace DiscordCoreInternal
WebSocketOpCodes
For the opcodes that could be sent/received via Discord's websockets.
@ Presence_Update
Update the client's presence.
@ Dispatch
An event was dispatched.
@ Reconnect
You should attempt to reconnect and resume immediately.
@ Request_Guild_Members
Request information about offline guild members in a large guild.
@ Voice_State_Update
Used to join/leave or move between voice channels.
The main namespace for this library.
@ Sending_Identify
Sending the identify payload.
@ Collecting_Hello
Collecting the client hello.
@ Connecting
Connecting - it hasn't started or it's reconnecting.
DiscordCoreClient - The main class for this library.
Data that is received as part of a voice state update event.
Data that is received as part of a voice server update event.
A type of User, to represent the Bot and some of its associated endpoints.
For connecting to a voice-channel. "streamInfo" is used when a socket is created to connect this bot ...
Definition: Utilities.hpp:859
VoiceConnection class - represents the connection to a given voice Channel.