#pragma once #include #include #include #include #include "snowflake.hpp" #include "user.hpp" #include "role.hpp" #include "member.hpp" #include "channel.hpp" #include "guild.hpp" #include "usersettings.hpp" #include "message.hpp" #include "invite.hpp" #include "permissions.hpp" #include "emoji.hpp" #include "activity.hpp" #include "sticker.hpp" #include "ban.hpp" #include "auditlog.hpp" #include "relationship.hpp" #include "errors.hpp" // most stuff below should just be objects that get processed and thrown away immediately enum class GatewayOp : int { Event = 0, Heartbeat = 1, Identify = 2, UpdateStatus = 3, Resume = 6, Reconnect = 7, InvalidSession = 9, Hello = 10, HeartbeatAck = 11, LazyLoadRequest = 14, }; enum class GatewayEvent : int { READY, MESSAGE_CREATE, MESSAGE_DELETE, MESSAGE_UPDATE, GUILD_MEMBER_LIST_UPDATE, GUILD_CREATE, GUILD_DELETE, MESSAGE_DELETE_BULK, GUILD_MEMBER_UPDATE, PRESENCE_UPDATE, CHANNEL_DELETE, CHANNEL_UPDATE, CHANNEL_CREATE, GUILD_UPDATE, GUILD_ROLE_UPDATE, GUILD_ROLE_CREATE, GUILD_ROLE_DELETE, MESSAGE_REACTION_ADD, MESSAGE_REACTION_REMOVE, CHANNEL_RECIPIENT_ADD, CHANNEL_RECIPIENT_REMOVE, TYPING_START, GUILD_BAN_REMOVE, GUILD_BAN_ADD, INVITE_CREATE, INVITE_DELETE, USER_NOTE_UPDATE, READY_SUPPLEMENTAL, GUILD_EMOJIS_UPDATE, GUILD_JOIN_REQUEST_CREATE, GUILD_JOIN_REQUEST_UPDATE, GUILD_JOIN_REQUEST_DELETE, RELATIONSHIP_REMOVE, RELATIONSHIP_ADD, THREAD_CREATE, THREAD_UPDATE, THREAD_DELETE, THREAD_LIST_SYNC, THREAD_MEMBER_UPDATE, THREAD_MEMBERS_UPDATE, THREAD_MEMBER_LIST_UPDATE, MESSAGE_ACK, USER_GUILD_SETTINGS_UPDATE, }; enum class GatewayCloseCode : uint16_t { // standard Normal = 1000, GoingAway = 1001, ProtocolError = 1002, Unsupported = 1003, NoStatus = 1005, Abnormal = 1006, UnsupportedPayload = 1007, PolicyViolation = 1008, TooLarge = 1009, MandatoryExtension = 1010, ServerError = 1011, ServiceRestart = 1012, TryAgainLater = 1013, BadGateway = 1014, TLSHandshakeFailed = 1015, // discord UnknownError = 4000, UnknownOpcode = 4001, DecodeError = 4002, NotAuthenticated = 4003, AuthenticationFailed = 4004, AlreadyAuthenticated = 4005, InvalidSequence = 4007, RateLimited = 4008, SessionTimedOut = 4009, InvalidShard = 4010, ShardingRequired = 4011, InvalidAPIVersion = 4012, InvalidIntents = 4013, DisallowedIntents = 4014, // internal UserDisconnect = 4091, Reconnecting = 4092, }; struct GatewayMessage { GatewayOp Opcode; nlohmann::json Data; std::string Type; int Sequence = -1; 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 MessageDeleteData { Snowflake ID; // Snowflake ChannelID; // Snowflake GuildID; // opt friend void from_json(const nlohmann::json &j, MessageDeleteData &m); }; struct MessageDeleteBulkData { std::vector IDs; // Snowflake ChannelID; // Snowflake GuildID; // opt friend void from_json(const nlohmann::json &j, MessageDeleteBulkData &m); }; struct GuildMemberListUpdateMessage { struct Item { virtual ~Item() = default; std::string Type; }; struct GroupItem : Item { std::string ID; int Count; friend void from_json(const nlohmann::json &j, GroupItem &m); }; struct MemberItem : Item { UserData User; std::vector Roles; std::optional Presence; std::string PremiumSince; // opt std::string Nickname; // opt bool IsMuted; std::string JoinedAt; std::string HoistedRole; // null bool IsDefeaned; GuildMember GetAsMemberData() const; friend void from_json(const nlohmann::json &j, MemberItem &m); private: GuildMember m_member_data; }; struct OpObject { std::string Op; std::optional Index; std::optional>> Items; // SYNC std::optional> Range; // SYNC std::optional> OpItem; // UPDATE friend void from_json(const nlohmann::json &j, OpObject &m); }; int OnlineCount; int MemberCount; std::string ListIDHash; std::string GuildID; std::vector Groups; std::vector Ops; friend void from_json(const nlohmann::json &j, GuildMemberListUpdateMessage &m); }; struct LazyLoadRequestMessage { Snowflake GuildID; std::optional ShouldGetTyping; std::optional ShouldGetActivities; std::optional ShouldGetThreads; std::optional> Members; // snowflake? std::optional>>> Channels; // channel ID -> range of sidebar std::optional> ThreadIDs; friend void to_json(nlohmann::json &j, const LazyLoadRequestMessage &m); }; struct UpdateStatusMessage { int Since = 0; std::vector Activities; PresenceStatus Status; bool IsAFK = false; friend void to_json(nlohmann::json &j, const UpdateStatusMessage &m); }; struct ReadStateEntry { int MentionCount; Snowflake LastMessageID; Snowflake ID; // std::string LastPinTimestamp; iso friend void from_json(const nlohmann::json &j, ReadStateEntry &m); friend void to_json(nlohmann::json &j, const ReadStateEntry &m); }; struct ReadStateData { int Version; bool IsPartial; std::vector Entries; friend void from_json(const nlohmann::json &j, ReadStateData &m); }; struct MuteConfigData { std::optional EndTime; // nullopt is encoded as null int SelectedTimeWindow; friend void from_json(const nlohmann::json &j, MuteConfigData &m); friend void to_json(nlohmann::json &j, const MuteConfigData &m); }; struct UserGuildSettingsChannelOverride { bool Muted; MuteConfigData MuteConfig; int MessageNotifications; bool Collapsed; Snowflake ChannelID; friend void from_json(const nlohmann::json &j, UserGuildSettingsChannelOverride &m); friend void to_json(nlohmann::json &j, const UserGuildSettingsChannelOverride &m); }; struct UserGuildSettingsEntry { int Version; bool SuppressRoles; bool SuppressEveryone; bool Muted; MuteConfigData MuteConfig; bool MobilePush; int MessageNotifications; bool HideMutedChannels; Snowflake GuildID; std::vector ChannelOverrides; friend void from_json(const nlohmann::json &j, UserGuildSettingsEntry &m); friend void to_json(nlohmann::json &j, const UserGuildSettingsEntry &m); }; struct UserGuildSettingsData { int Version; bool IsPartial; std::vector Entries; friend void from_json(const nlohmann::json &j, UserGuildSettingsData &m); }; struct ReadyEventData { int GatewayVersion; UserData SelfUser; std::vector Guilds; std::string SessionID; std::vector PrivateChannels; // undocumented std::optional> Users; std::optional AnalyticsToken; std::optional FriendSuggestionCount; UserSettings Settings; std::optional>> MergedMembers; std::optional> Relationships; std::optional> GuildJoinRequests; ReadStateData ReadState; UserGuildSettingsData GuildSettings; // std::vector ConnectedAccounts; // opt // std::map Consents; // opt // std::vector Experiments; // opt // std::vector GuildExperiments; // opt // std::map Notes; // opt // std::vector Presences; // opt // std::vector ReadStates; // opt // Unknown Tutorial; // opt, null // std::vector UserGuildSettings; // opt friend void from_json(const nlohmann::json &j, ReadyEventData &m); }; struct MergedPresence { Snowflake UserID; std::optional LastModified; PresenceData Presence; friend void from_json(const nlohmann::json &j, MergedPresence &m); }; struct SupplementalMergedPresencesData { std::vector> Guilds; std::vector Friends; friend void from_json(const nlohmann::json &j, SupplementalMergedPresencesData &m); }; struct ReadySupplementalData { SupplementalMergedPresencesData MergedPresences; friend void from_json(const nlohmann::json &j, ReadySupplementalData &m); }; struct IdentifyProperties { std::string OS; std::string Browser; std::string Device; std::string SystemLocale; std::string BrowserUserAgent; std::string BrowserVersion; std::string OSVersion; std::string Referrer; std::string ReferringDomain; std::string ReferrerCurrent; std::string ReferringDomainCurrent; std::string ReleaseChannel; int ClientBuildNumber; std::string ClientEventSource; // empty -> null friend void to_json(nlohmann::json &j, const IdentifyProperties &m); }; struct ClientStateProperties { std::map GuildHashes; std::string HighestLastMessageID = "0"; int ReadStateVersion = 0; int UserGuildSettingsVersion = -1; friend void to_json(nlohmann::json &j, const ClientStateProperties &m); }; struct IdentifyMessage : GatewayMessage { std::string Token; IdentifyProperties Properties; PresenceData Presence; ClientStateProperties ClientState; bool DoesSupportCompression = false; int Capabilities; friend void to_json(nlohmann::json &j, const IdentifyMessage &m); }; struct HeartbeatMessage : GatewayMessage { int Sequence; friend void to_json(nlohmann::json &j, const HeartbeatMessage &m); }; struct CreateMessageObject { std::string Content; std::optional MessageReference; std::optional Nonce; friend void to_json(nlohmann::json &j, const CreateMessageObject &m); }; struct MessageEditObject { std::string Content; // opt, null std::vector Embeds; // opt, null int Flags = -1; // opt, null friend void to_json(nlohmann::json &j, const MessageEditObject &m); }; struct GuildMemberUpdateMessage { Snowflake GuildID; // std::vector Roles; // UserData User; // std::string Nick; // opt, null std::string JoinedAt; std::string PremiumSince; // opt, null friend void from_json(const nlohmann::json &j, GuildMemberUpdateMessage &m); }; struct ClientStatusData { std::optional Desktop; std::optional Mobile; std::optional Web; friend void from_json(const nlohmann::json &j, ClientStatusData &m); }; struct PresenceUpdateMessage { nlohmann::json User; // the client updates an existing object from this data std::optional GuildID; std::string StatusMessage; std::vector Activities; ClientStatusData ClientStatus; friend void from_json(const nlohmann::json &j, PresenceUpdateMessage &m); }; struct CreateDMObject { std::vector Recipients; friend void to_json(nlohmann::json &j, const CreateDMObject &m); }; struct ResumeMessage : GatewayMessage { std::string Token; std::string SessionID; int Sequence; friend void to_json(nlohmann::json &j, const ResumeMessage &m); }; struct GuildRoleUpdateObject { Snowflake GuildID; RoleData Role; friend void from_json(const nlohmann::json &j, GuildRoleUpdateObject &m); }; struct GuildRoleCreateObject { Snowflake GuildID; RoleData Role; friend void from_json(const nlohmann::json &j, GuildRoleCreateObject &m); }; struct GuildRoleDeleteObject { Snowflake GuildID; Snowflake RoleID; friend void from_json(const nlohmann::json &j, GuildRoleDeleteObject &m); }; struct MessageReactionAddObject { Snowflake UserID; Snowflake ChannelID; Snowflake MessageID; std::optional GuildID; std::optional Member; EmojiData Emoji; friend void from_json(const nlohmann::json &j, MessageReactionAddObject &m); }; struct MessageReactionRemoveObject { Snowflake UserID; Snowflake ChannelID; Snowflake MessageID; std::optional GuildID; EmojiData Emoji; friend void from_json(const nlohmann::json &j, MessageReactionRemoveObject &m); }; struct ChannelRecipientAdd { UserData User; Snowflake ChannelID; friend void from_json(const nlohmann::json &j, ChannelRecipientAdd &m); }; struct ChannelRecipientRemove { UserData User; Snowflake ChannelID; friend void from_json(const nlohmann::json &j, ChannelRecipientRemove &m); }; struct TypingStartObject { Snowflake ChannelID; std::optional GuildID; Snowflake UserID; uint64_t Timestamp; std::optional Member; friend void from_json(const nlohmann::json &j, TypingStartObject &m); }; // implement rest as needed struct ModifyGuildObject { std::optional Name; std::optional IconData; friend void to_json(nlohmann::json &j, const ModifyGuildObject &m); }; struct GuildBanRemoveObject { Snowflake GuildID; UserData User; friend void from_json(const nlohmann::json &j, GuildBanRemoveObject &m); }; struct GuildBanAddObject { Snowflake GuildID; UserData User; friend void from_json(const nlohmann::json &j, GuildBanAddObject &m); }; struct InviteCreateObject { Snowflake ChannelID; std::string Code; std::string CreatedAt; std::optional GuildID; std::optional Inviter; int MaxAge; int MaxUses; UserData TargetUser; std::optional TargetUserType; bool IsTemporary; int Uses; friend void from_json(const nlohmann::json &j, InviteCreateObject &m); }; struct InviteDeleteObject { Snowflake ChannelID; std::optional GuildID; std::string Code; friend void from_json(const nlohmann::json &j, InviteDeleteObject &m); }; struct ConnectionData { std::string ID; std::string Type; std::string Name; bool IsVerified; friend void from_json(const nlohmann::json &j, ConnectionData &m); }; struct MutualGuildData { Snowflake ID; std::optional Nick; // null friend void from_json(const nlohmann::json &j, MutualGuildData &m); }; struct UserProfileData { std::vector ConnectedAccounts; std::vector MutualGuilds; std::optional PremiumGuildSince; // null std::optional PremiumSince; // null UserData User; friend void from_json(const nlohmann::json &j, UserProfileData &m); }; struct UserNoteObject { // idk if these can be null or missing but i play it safe std::optional Note; std::optional NoteUserID; std::optional UserID; friend void from_json(const nlohmann::json &j, UserNoteObject &m); }; struct UserSetNoteObject { std::string Note; friend void to_json(nlohmann::json &j, const UserSetNoteObject &m); }; struct UserNoteUpdateMessage { std::string Note; Snowflake ID; friend void from_json(const nlohmann::json &j, UserNoteUpdateMessage &m); }; struct RelationshipsData { std::vector Users; friend void from_json(const nlohmann::json &j, RelationshipsData &m); }; struct ModifyGuildMemberObject { // std::optional Nick; // std::optional IsMuted; // std::optional IsDeaf; // std::optional ChannelID; std::optional> Roles; friend void to_json(nlohmann::json &j, const ModifyGuildMemberObject &m); }; struct ModifyGuildRoleObject { std::optional Name; std::optional Permissions; std::optional Color; std::optional IsHoisted; std::optional Mentionable; friend void to_json(nlohmann::json &j, const ModifyGuildRoleObject &m); }; struct ModifyGuildRolePositionsObject { struct PositionParam { Snowflake ID; std::optional Position; // no idea why this can be optional friend void to_json(nlohmann::json &j, const PositionParam &m); }; std::vector Positions; friend void to_json(nlohmann::json &j, const ModifyGuildRolePositionsObject &m); }; struct GuildEmojisUpdateObject { Snowflake GuildID; // std::vector Emojis; // GuildHashes, undocumented friend void from_json(const nlohmann::json &j, GuildEmojisUpdateObject &m); }; struct ModifyGuildEmojiObject { std::optional Name; // std::optional> Roles; friend void to_json(nlohmann::json &j, const ModifyGuildEmojiObject &m); }; struct GuildJoinRequestCreateData { GuildApplicationStatus Status; GuildApplicationData Request; Snowflake GuildID; friend void from_json(const nlohmann::json &j, GuildJoinRequestCreateData &m); }; using GuildJoinRequestUpdateData = GuildJoinRequestCreateData; struct GuildJoinRequestDeleteData { Snowflake UserID; Snowflake GuildID; friend void from_json(const nlohmann::json &j, GuildJoinRequestDeleteData &m); }; struct VerificationFieldObject { std::string Type; std::string Label; bool Required; std::vector Values; std::optional Response; // present in client to server friend void from_json(const nlohmann::json &j, VerificationFieldObject &m); friend void to_json(nlohmann::json &j, const VerificationFieldObject &m); }; struct VerificationGateInfoObject { std::optional Description; std::optional> VerificationFields; std::optional Version; std::optional Enabled; // present only in client to server in modify gate friend void from_json(const nlohmann::json &j, VerificationGateInfoObject &m); friend void to_json(nlohmann::json &j, const VerificationGateInfoObject &m); }; // not sure what the structure for this really is struct RateLimitedResponse { int Code; bool Global; std::optional Message; float RetryAfter; friend void from_json(const nlohmann::json &j, RateLimitedResponse &m); }; struct RelationshipRemoveData { Snowflake ID; RelationshipType Type; friend void from_json(const nlohmann::json &j, RelationshipRemoveData &m); }; struct RelationshipAddData { Snowflake ID; // Nickname; same deal as the other comment somewhere else RelationshipType Type; UserData User; // std::optional ShouldNotify; // i guess if the client should send a notification. not worth caring about friend void from_json(const nlohmann::json &j, RelationshipAddData &m); }; struct FriendRequestObject { std::string Username; int Discriminator; friend void to_json(nlohmann::json &j, const FriendRequestObject &m); }; struct PutRelationshipObject { std::optional Type; friend void to_json(nlohmann::json &j, const PutRelationshipObject &m); }; struct ThreadCreateData { ChannelData Channel; friend void from_json(const nlohmann::json &j, ThreadCreateData &m); }; struct ThreadDeleteData { Snowflake ID; Snowflake GuildID; Snowflake ParentID; ChannelType Type; friend void from_json(const nlohmann::json &j, ThreadDeleteData &m); }; // pretty different from docs struct ThreadListSyncData { std::vector Threads; Snowflake GuildID; // std::optional> MostRecentMessages; friend void from_json(const nlohmann::json &j, ThreadListSyncData &m); }; struct ThreadMembersUpdateData { Snowflake ID; Snowflake GuildID; int MemberCount; std::optional> AddedMembers; std::optional> RemovedMemberIDs; friend void from_json(const nlohmann::json &j, ThreadMembersUpdateData &m); }; struct ArchivedThreadsResponseData { std::vector Threads; std::vector Members; bool HasMore; friend void from_json(const nlohmann::json &j, ArchivedThreadsResponseData &m); }; struct ThreadMemberUpdateData { ThreadMemberObject Member; friend void from_json(const nlohmann::json &j, ThreadMemberUpdateData &m); }; struct ThreadUpdateData { ChannelData Thread; friend void from_json(const nlohmann::json &j, ThreadUpdateData &m); }; struct ThreadMemberListUpdateData { struct UserEntry { Snowflake UserID; // PresenceData Presence; GuildMember Member; friend void from_json(const nlohmann::json &j, UserEntry &m); }; Snowflake ThreadID; Snowflake GuildID; std::vector Members; friend void from_json(const nlohmann::json &j, ThreadMemberListUpdateData &m); }; struct ModifyChannelObject { std::optional Archived; std::optional Locked; friend void to_json(nlohmann::json &j, const ModifyChannelObject &m); }; struct MessageAckData { // int Version; // what is this ?!?!?!!? Snowflake MessageID; Snowflake ChannelID; friend void from_json(const nlohmann::json &j, MessageAckData &m); }; struct AckBulkData { std::vector ReadStates; friend void to_json(nlohmann::json &j, const AckBulkData &m); }; struct UserGuildSettingsUpdateData { UserGuildSettingsEntry Settings; friend void from_json(const nlohmann::json &j, UserGuildSettingsUpdateData &m); };