diff --git a/3rdParty/discord_social_sdk/cdiscord.h b/3rdParty/discord_social_sdk/cdiscord.h index 814c844540..9c027a967e 100644 --- a/3rdParty/discord_social_sdk/cdiscord.h +++ b/3rdParty/discord_social_sdk/cdiscord.h @@ -36,7 +36,6 @@ typedef struct Discord_Allocator { Discord_FreeFn fnFree; } Discord_Allocator; -DISCORD_API void Discord_SetAllocator(Discord_Allocator* allocator); DISCORD_API void* Discord_Alloc(size_t size); DISCORD_API void Discord_Free(void* ptr); DISCORD_API void Discord_FreeProperties(Discord_Properties props); @@ -46,6 +45,7 @@ DISCORD_API void Discord_ResetCallbacks(); DISCORD_API void Discord_RunCallbacks(); typedef enum Discord_ActivityActionTypes { + Discord_ActivityActionTypes_Invalid = 0, Discord_ActivityActionTypes_Join = 1, Discord_ActivityActionTypes_JoinRequest = 5, Discord_ActivityActionTypes_forceint = 0x7FFFFFFF @@ -176,6 +176,26 @@ typedef enum Discord_IntegrationType { Discord_IntegrationType_forceint = 0x7FFFFFFF } Discord_IntegrationType; +typedef enum Discord_ChannelType { + Discord_ChannelType_GuildText = 0, + Discord_ChannelType_Dm = 1, + Discord_ChannelType_GuildVoice = 2, + Discord_ChannelType_GroupDm = 3, + Discord_ChannelType_GuildCategory = 4, + Discord_ChannelType_GuildNews = 5, + Discord_ChannelType_GuildStore = 6, + Discord_ChannelType_GuildNewsThread = 10, + Discord_ChannelType_GuildPublicThread = 11, + Discord_ChannelType_GuildPrivateThread = 12, + Discord_ChannelType_GuildStageVoice = 13, + Discord_ChannelType_GuildDirectory = 14, + Discord_ChannelType_GuildForum = 15, + Discord_ChannelType_GuildMedia = 16, + Discord_ChannelType_Lobby = 17, + Discord_ChannelType_EphemeralDm = 18, + Discord_ChannelType_forceint = 0x7FFFFFFF +} Discord_ChannelType; + typedef enum Discord_AdditionalContentType { Discord_AdditionalContentType_Other = 0, Discord_AdditionalContentType_Attachment = 1, @@ -187,6 +207,12 @@ typedef enum Discord_AdditionalContentType { Discord_AdditionalContentType_forceint = 0x7FFFFFFF } Discord_AdditionalContentType; +typedef enum Discord_VoiceInputModeType { + Discord_VoiceInputModeType_VoiceActivity = 0, + Discord_VoiceInputModeType_PushToTalk = 1, + Discord_VoiceInputModeType_forceint = 0x7FFFFFFF +} Discord_VoiceInputModeType; + typedef enum Discord_AudioSystem { Discord_AudioSystem_Standard = 0, Discord_AudioSystem_Game = 1, @@ -221,26 +247,6 @@ typedef enum Discord_Call_Status { Discord_Call_Status_forceint = 0x7FFFFFFF } Discord_Call_Status; -typedef enum Discord_ChannelType { - Discord_ChannelType_GuildText = 0, - Discord_ChannelType_Dm = 1, - Discord_ChannelType_GuildVoice = 2, - Discord_ChannelType_GroupDm = 3, - Discord_ChannelType_GuildCategory = 4, - Discord_ChannelType_GuildNews = 5, - Discord_ChannelType_GuildStore = 6, - Discord_ChannelType_GuildNewsThread = 10, - Discord_ChannelType_GuildPublicThread = 11, - Discord_ChannelType_GuildPrivateThread = 12, - Discord_ChannelType_GuildStageVoice = 13, - Discord_ChannelType_GuildDirectory = 14, - Discord_ChannelType_GuildForum = 15, - Discord_ChannelType_GuildMedia = 16, - Discord_ChannelType_Lobby = 17, - Discord_ChannelType_EphemeralDm = 18, - Discord_ChannelType_forceint = 0x7FFFFFFF -} Discord_ChannelType; - typedef enum Discord_RelationshipType { Discord_RelationshipType_None = 0, Discord_RelationshipType_Friend = 1, @@ -252,6 +258,17 @@ typedef enum Discord_RelationshipType { Discord_RelationshipType_forceint = 0x7FFFFFFF } Discord_RelationshipType; +typedef enum Discord_ExternalIdentityProviderType { + Discord_ExternalIdentityProviderType_OIDC = 0, + Discord_ExternalIdentityProviderType_EpicOnlineServices = 1, + Discord_ExternalIdentityProviderType_Steam = 2, + Discord_ExternalIdentityProviderType_Unity = 3, + Discord_ExternalIdentityProviderType_DiscordBot = 4, + Discord_ExternalIdentityProviderType_None = 5, + Discord_ExternalIdentityProviderType_Unknown = 6, + Discord_ExternalIdentityProviderType_forceint = 0x7FFFFFFF +} Discord_ExternalIdentityProviderType; + typedef enum Discord_UserHandle_AvatarType { Discord_UserHandle_AvatarType_Gif = 0, Discord_UserHandle_AvatarType_Webp = 1, @@ -315,6 +332,9 @@ typedef enum Discord_AuthenticationExternalAuthType { Discord_AuthenticationExternalAuthType_EpicOnlineServicesIdToken = 2, Discord_AuthenticationExternalAuthType_SteamSessionTicket = 3, Discord_AuthenticationExternalAuthType_UnityServicesIdToken = 4, + Discord_AuthenticationExternalAuthType_DiscordBotIssuedAccessToken = 5, + Discord_AuthenticationExternalAuthType_AppleIdToken = 6, + Discord_AuthenticationExternalAuthType_PlayStationNetworkIdToken = 7, Discord_AuthenticationExternalAuthType_forceint = 0x7FFFFFFF } Discord_AuthenticationExternalAuthType; @@ -355,12 +375,14 @@ typedef struct Discord_GuildChannel Discord_GuildChannel; typedef struct Discord_LinkedLobby Discord_LinkedLobby; typedef struct Discord_LinkedChannel Discord_LinkedChannel; typedef struct Discord_RelationshipHandle Discord_RelationshipHandle; +typedef struct Discord_UserApplicationProfileHandle Discord_UserApplicationProfileHandle; typedef struct Discord_UserHandle Discord_UserHandle; typedef struct Discord_LobbyMemberHandle Discord_LobbyMemberHandle; typedef struct Discord_LobbyHandle Discord_LobbyHandle; typedef struct Discord_AdditionalContent Discord_AdditionalContent; typedef struct Discord_MessageHandle Discord_MessageHandle; typedef struct Discord_AudioDevice Discord_AudioDevice; +typedef struct Discord_VoiceSettings Discord_VoiceSettings; typedef struct Discord_UserMessageSummary Discord_UserMessageSummary; typedef struct Discord_ClientCreateOptions Discord_ClientCreateOptions; typedef struct Discord_Client Discord_Client; @@ -377,6 +399,10 @@ typedef struct Discord_UInt64Span { uint64_t* ptr; size_t size; } Discord_UInt64Span; +typedef struct Discord_UserApplicationProfileHandleSpan { + Discord_UserApplicationProfileHandle* ptr; + size_t size; +} Discord_UserApplicationProfileHandleSpan; typedef struct Discord_LobbyMemberHandleSpan { Discord_LobbyMemberHandle* ptr; size_t size; @@ -432,6 +458,9 @@ typedef void (*Discord_Client_GetInputDevicesCallback)(Discord_AudioDeviceSpan d void* userData); typedef void (*Discord_Client_GetOutputDevicesCallback)(Discord_AudioDeviceSpan devices, void* userData); +typedef void (*Discord_Client_GetVoiceSettingsCallback)(Discord_ClientResult* result, + Discord_VoiceSettings* settings, + void* userData); typedef void (*Discord_Client_DeviceChangeCallback)(Discord_AudioDeviceSpan inputDevices, Discord_AudioDeviceSpan outputDevices, void* userData); @@ -443,6 +472,8 @@ typedef void (*Discord_Client_VoiceParticipantChangedCallback)(uint64_t lobbyId, uint64_t memberId, bool added, void* userData); +typedef void (*Discord_Client_VoiceSettingsUpdatedCallback)(Discord_VoiceSettings* settings, + void* userData); typedef void (*Discord_Client_UserAudioReceivedCallback)(uint64_t userId, int16_t* data, uint64_t samplesPerChannel, @@ -476,6 +507,7 @@ typedef void (*Discord_Client_TokenExchangeCallback)(Discord_ClientResult* resul int32_t expiresIn, Discord_String scopes, void* userData); +typedef void (*Discord_Client_AuthorizeRequestCallback)(void* userData); typedef void (*Discord_Client_RevokeTokenCallback)(Discord_ClientResult* result, void* userData); typedef void (*Discord_Client_AuthorizeDeviceScreenClosedCallback)(void* userData); typedef void (*Discord_Client_TokenExpirationCallback)(void* userData); @@ -547,6 +579,7 @@ typedef void (*Discord_Client_LobbyMemberUpdatedCallback)(uint64_t lobbyId, uint64_t memberId, void* userData); typedef void (*Discord_Client_LobbyUpdatedCallback)(uint64_t lobbyId, void* userData); +typedef void (*Discord_Client_IsDiscordAppInstalledCallback)(bool installed, void* userData); typedef void (*Discord_Client_AcceptActivityInviteCallback)(Discord_ClientResult* result, Discord_String joinSecret, void* userData); @@ -641,6 +674,10 @@ void DISCORD_API Discord_ActivityAssets_SetSmallUrl(Discord_ActivityAssets* self Discord_String* value); bool DISCORD_API Discord_ActivityAssets_SmallUrl(Discord_ActivityAssets* self, Discord_String* returnValue); +void DISCORD_API Discord_ActivityAssets_SetInviteCoverImage(Discord_ActivityAssets* self, + Discord_String* value); +bool DISCORD_API Discord_ActivityAssets_InviteCoverImage(Discord_ActivityAssets* self, + Discord_String* returnValue); struct Discord_ActivityTimestamps { void* opaque; }; @@ -976,6 +1013,13 @@ void DISCORD_API Discord_GuildChannel_SetId(Discord_GuildChannel* self, uint64_t uint64_t DISCORD_API Discord_GuildChannel_Id(Discord_GuildChannel* self); void DISCORD_API Discord_GuildChannel_SetName(Discord_GuildChannel* self, Discord_String value); void DISCORD_API Discord_GuildChannel_Name(Discord_GuildChannel* self, Discord_String* returnValue); +void DISCORD_API Discord_GuildChannel_SetType(Discord_GuildChannel* self, + Discord_ChannelType value); +Discord_ChannelType DISCORD_API Discord_GuildChannel_Type(Discord_GuildChannel* self); +void DISCORD_API Discord_GuildChannel_SetPosition(Discord_GuildChannel* self, int32_t value); +int32_t DISCORD_API Discord_GuildChannel_Position(Discord_GuildChannel* self); +void DISCORD_API Discord_GuildChannel_SetParentId(Discord_GuildChannel* self, uint64_t* value); +bool DISCORD_API Discord_GuildChannel_ParentId(Discord_GuildChannel* self, uint64_t* returnValue); void DISCORD_API Discord_GuildChannel_SetIsLinkable(Discord_GuildChannel* self, bool value); bool DISCORD_API Discord_GuildChannel_IsLinkable(Discord_GuildChannel* self); void DISCORD_API @@ -1027,6 +1071,32 @@ uint64_t DISCORD_API Discord_RelationshipHandle_Id(Discord_RelationshipHandle* s bool DISCORD_API Discord_RelationshipHandle_IsSpamRequest(Discord_RelationshipHandle* self); bool DISCORD_API Discord_RelationshipHandle_User(Discord_RelationshipHandle* self, Discord_UserHandle* returnValue); +struct Discord_UserApplicationProfileHandle { + void* opaque; +}; + +void DISCORD_API +Discord_UserApplicationProfileHandle_Drop(Discord_UserApplicationProfileHandle* self); +void DISCORD_API +Discord_UserApplicationProfileHandle_Clone(Discord_UserApplicationProfileHandle* self, + Discord_UserApplicationProfileHandle const* other); +void DISCORD_API +Discord_UserApplicationProfileHandle_AvatarHash(Discord_UserApplicationProfileHandle* self, + Discord_String* returnValue); +void DISCORD_API +Discord_UserApplicationProfileHandle_Metadata(Discord_UserApplicationProfileHandle* self, + Discord_String* returnValue); +bool DISCORD_API +Discord_UserApplicationProfileHandle_ProviderId(Discord_UserApplicationProfileHandle* self, + Discord_String* returnValue); +void DISCORD_API Discord_UserApplicationProfileHandle_ProviderIssuedUserId( + Discord_UserApplicationProfileHandle* self, + Discord_String* returnValue); +Discord_ExternalIdentityProviderType DISCORD_API +Discord_UserApplicationProfileHandle_ProviderType(Discord_UserApplicationProfileHandle* self); +void DISCORD_API +Discord_UserApplicationProfileHandle_Username(Discord_UserApplicationProfileHandle* self, + Discord_String* returnValue); struct Discord_UserHandle { void* opaque; }; @@ -1051,6 +1121,9 @@ bool DISCORD_API Discord_UserHandle_IsProvisional(Discord_UserHandle* self); void DISCORD_API Discord_UserHandle_Relationship(Discord_UserHandle* self, Discord_RelationshipHandle* returnValue); Discord_StatusType DISCORD_API Discord_UserHandle_Status(Discord_UserHandle* self); +void DISCORD_API +Discord_UserHandle_UserApplicationProfiles(Discord_UserHandle* self, + Discord_UserApplicationProfileHandleSpan* returnValue); void DISCORD_API Discord_UserHandle_Username(Discord_UserHandle* self, Discord_String* returnValue); struct Discord_LobbyMemberHandle { void* opaque; @@ -1118,6 +1191,8 @@ void DISCORD_API Discord_MessageHandle_Clone(Discord_MessageHandle* self, Discord_MessageHandle const* other); bool DISCORD_API Discord_MessageHandle_AdditionalContent(Discord_MessageHandle* self, Discord_AdditionalContent* returnValue); +bool DISCORD_API Discord_MessageHandle_AdditionalName(Discord_MessageHandle* self, + Discord_String* returnValue); bool DISCORD_API Discord_MessageHandle_ApplicationId(Discord_MessageHandle* self, uint64_t* returnValue); bool DISCORD_API Discord_MessageHandle_Author(Discord_MessageHandle* self, @@ -1136,6 +1211,8 @@ bool DISCORD_API Discord_MessageHandle_Lobby(Discord_MessageHandle* self, Discord_LobbyHandle* returnValue); void DISCORD_API Discord_MessageHandle_Metadata(Discord_MessageHandle* self, Discord_Properties* returnValue); +void DISCORD_API Discord_MessageHandle_ModerationMetadata(Discord_MessageHandle* self, + Discord_Properties* returnValue); void DISCORD_API Discord_MessageHandle_RawContent(Discord_MessageHandle* self, Discord_String* returnValue); bool DISCORD_API Discord_MessageHandle_Recipient(Discord_MessageHandle* self, @@ -1158,6 +1235,37 @@ void DISCORD_API Discord_AudioDevice_SetName(Discord_AudioDevice* self, Discord_ void DISCORD_API Discord_AudioDevice_Name(Discord_AudioDevice* self, Discord_String* returnValue); void DISCORD_API Discord_AudioDevice_SetIsDefault(Discord_AudioDevice* self, bool value); bool DISCORD_API Discord_AudioDevice_IsDefault(Discord_AudioDevice* self); +struct Discord_VoiceSettings { + void* opaque; +}; + +void DISCORD_API Discord_VoiceSettings_Drop(Discord_VoiceSettings* self); +void DISCORD_API Discord_VoiceSettings_Clone(Discord_VoiceSettings* self, + Discord_VoiceSettings const* arg0); +void DISCORD_API Discord_VoiceSettings_SetSelfMute(Discord_VoiceSettings* self, bool value); +bool DISCORD_API Discord_VoiceSettings_SelfMute(Discord_VoiceSettings* self); +void DISCORD_API Discord_VoiceSettings_SetSelfDeaf(Discord_VoiceSettings* self, bool value); +bool DISCORD_API Discord_VoiceSettings_SelfDeaf(Discord_VoiceSettings* self); +void DISCORD_API Discord_VoiceSettings_SetInputMode(Discord_VoiceSettings* self, + Discord_VoiceInputModeType value); +Discord_VoiceInputModeType DISCORD_API Discord_VoiceSettings_InputMode(Discord_VoiceSettings* self); +void DISCORD_API Discord_VoiceSettings_SetPttKey(Discord_VoiceSettings* self, Discord_String value); +void DISCORD_API Discord_VoiceSettings_PttKey(Discord_VoiceSettings* self, + Discord_String* returnValue); +void DISCORD_API Discord_VoiceSettings_SetInputVolume(Discord_VoiceSettings* self, float value); +float DISCORD_API Discord_VoiceSettings_InputVolume(Discord_VoiceSettings* self); +void DISCORD_API Discord_VoiceSettings_SetOutputVolume(Discord_VoiceSettings* self, float value); +float DISCORD_API Discord_VoiceSettings_OutputVolume(Discord_VoiceSettings* self); +void DISCORD_API Discord_VoiceSettings_SetAutomaticGainControl(Discord_VoiceSettings* self, + bool value); +bool DISCORD_API Discord_VoiceSettings_AutomaticGainControl(Discord_VoiceSettings* self); +void DISCORD_API Discord_VoiceSettings_SetEchoCancellation(Discord_VoiceSettings* self, bool value); +bool DISCORD_API Discord_VoiceSettings_EchoCancellation(Discord_VoiceSettings* self); +void DISCORD_API Discord_VoiceSettings_SetNoiseSuppression(Discord_VoiceSettings* self, bool value); +bool DISCORD_API Discord_VoiceSettings_NoiseSuppression(Discord_VoiceSettings* self); +void DISCORD_API Discord_VoiceSettings_SetNoiseCancellation(Discord_VoiceSettings* self, + bool value); +bool DISCORD_API Discord_VoiceSettings_NoiseCancellation(Discord_VoiceSettings* self); struct Discord_UserMessageSummary { void* opaque; }; @@ -1193,6 +1301,10 @@ void DISCORD_API Discord_ClientCreateOptions_SetExperimentalAndroidPreventCommsF bool value); bool DISCORD_API Discord_ClientCreateOptions_ExperimentalAndroidPreventCommsForBluetooth( Discord_ClientCreateOptions* self); +void DISCORD_API Discord_ClientCreateOptions_SetCpuAffinityMask(Discord_ClientCreateOptions* self, + uint64_t* value); +bool DISCORD_API Discord_ClientCreateOptions_CpuAffinityMask(Discord_ClientCreateOptions* self, + uint64_t* returnValue); struct Discord_Client { void* opaque; }; @@ -1207,6 +1319,8 @@ void DISCORD_API Discord_Client_Drop(Discord_Client* self); void DISCORD_API Discord_Client_ErrorToString(Discord_Client_Error type, Discord_String* returnValue); uint64_t DISCORD_API Discord_Client_GetApplicationId(Discord_Client* self); +void DISCORD_API Discord_Client_GetCurrentUser(Discord_Client* self, + Discord_UserHandle* returnValue); void DISCORD_API Discord_Client_GetDefaultAudioDeviceId(Discord_String* returnValue); void DISCORD_API Discord_Client_GetDefaultCommunicationScopes(Discord_String* returnValue); void DISCORD_API Discord_Client_GetDefaultPresenceScopes(Discord_String* returnValue); @@ -1255,6 +1369,10 @@ void DISCORD_API Discord_Client_GetOutputDevices(Discord_Client* self, float DISCORD_API Discord_Client_GetOutputVolume(Discord_Client* self); bool DISCORD_API Discord_Client_GetSelfDeafAll(Discord_Client* self); bool DISCORD_API Discord_Client_GetSelfMuteAll(Discord_Client* self); +void DISCORD_API Discord_Client_GetVoiceSettings(Discord_Client* self, + Discord_Client_GetVoiceSettingsCallback cb, + Discord_FreeFn cb__userDataFree, + void* cb__userData); void DISCORD_API Discord_Client_SetAecDump(Discord_Client* self, bool on); void DISCORD_API Discord_Client_SetAutomaticGainControl(Discord_Client* self, bool on); void DISCORD_API @@ -1277,6 +1395,7 @@ Discord_Client_SetNoAudioInputCallback(Discord_Client* self, Discord_FreeFn callback__userDataFree, void* callback__userData); void DISCORD_API Discord_Client_SetNoAudioInputThreshold(Discord_Client* self, float dBFSThreshold); +void DISCORD_API Discord_Client_SetNoiseCancellation(Discord_Client* self, bool on); void DISCORD_API Discord_Client_SetNoiseSuppression(Discord_Client* self, bool on); void DISCORD_API Discord_Client_SetOpusHardwareCoding(Discord_Client* self, bool encode, @@ -1298,6 +1417,11 @@ Discord_Client_SetVoiceParticipantChangedCallback(Discord_Client* self, Discord_Client_VoiceParticipantChangedCallback cb, Discord_FreeFn cb__userDataFree, void* cb__userData); +void DISCORD_API +Discord_Client_SetVoiceSettingsUpdatedCallback(Discord_Client* self, + Discord_Client_VoiceSettingsUpdatedCallback callback, + Discord_FreeFn callback__userDataFree, + void* callback__userData); bool DISCORD_API Discord_Client_ShowAudioRoutePicker(Discord_Client* self); bool DISCORD_API Discord_Client_StartCall(Discord_Client* self, uint64_t channelId, @@ -1387,6 +1511,12 @@ void DISCORD_API Discord_Client_RefreshToken(Discord_Client* self, Discord_Client_TokenExchangeCallback callback, Discord_FreeFn callback__userDataFree, void* callback__userData); +void DISCORD_API +Discord_Client_RegisterAuthorizeRequestCallback(Discord_Client* self, + Discord_Client_AuthorizeRequestCallback callback, + Discord_FreeFn callback__userDataFree, + void* callback__userData); +void DISCORD_API Discord_Client_RemoveAuthorizeRequestCallback(Discord_Client* self); void DISCORD_API Discord_Client_RevokeToken(Discord_Client* self, uint64_t applicationId, Discord_String token, @@ -1622,6 +1752,11 @@ Discord_Client_UnlinkChannelFromLobby(Discord_Client* self, Discord_Client_LinkOrUnlinkChannelCallback callback, Discord_FreeFn callback__userDataFree, void* callback__userData); +void DISCORD_API +Discord_Client_IsDiscordAppInstalled(Discord_Client* self, + Discord_Client_IsDiscordAppInstalledCallback callback, + Discord_FreeFn callback__userDataFree, + void* callback__userData); void DISCORD_API Discord_Client_AcceptActivityInvite(Discord_Client* self, Discord_ActivityInvite* invite, Discord_Client_AcceptActivityInviteCallback cb, @@ -1783,8 +1918,6 @@ void DISCORD_API Discord_Client_UnblockUser(Discord_Client* self, Discord_Client_UpdateRelationshipCallback cb, Discord_FreeFn cb__userDataFree, void* cb__userData); -void DISCORD_API Discord_Client_GetCurrentUser(Discord_Client* self, - Discord_UserHandle* returnValue); bool DISCORD_API Discord_Client_GetCurrentUserV2(Discord_Client* self, Discord_UserHandle* returnValue); void DISCORD_API Discord_Client_GetDiscordClientConnectedUser( diff --git a/3rdParty/discord_social_sdk/discordpp.h b/3rdParty/discord_social_sdk/discordpp.h index 86d0055c07..44b42cf8dc 100644 --- a/3rdParty/discord_social_sdk/discordpp.h +++ b/3rdParty/discord_social_sdk/discordpp.h @@ -40,6 +40,9 @@ inline void RunCallbacks() /// See https://discord.com/developers/docs/rich-presence/overview for more information. enum class ActivityActionTypes { + /// \brief Invalid + Invalid = 0, + /// \brief Join Join = 1, @@ -403,54 +406,6 @@ enum class IntegrationType { UserInstall = 1, }; -/// \brief Represents the type of additional content contained in a message. -enum class AdditionalContentType { - - /// \brief Other - Other = 0, - - /// \brief Attachment - Attachment = 1, - - /// \brief Poll - Poll = 2, - - /// \brief VoiceMessage - VoiceMessage = 3, - - /// \brief Thread - Thread = 4, - - /// \brief Embed - Embed = 5, - - /// \brief Sticker - Sticker = 6, -}; - -/// \brief The Discord Voice audio system to use. -enum class AudioSystem { - - /// \brief Use the standard audio system. - Standard = 0, - - /// \brief Use the game audio system. - Game = 1, -}; - -/// \brief Represents whether a voice call is using push to talk or auto voice detection -enum class AudioModeType { - - /// \brief MODE_UNINIT - MODE_UNINIT = 0, - - /// \brief MODE_VAD - MODE_VAD = 1, - - /// \brief MODE_PTT - MODE_PTT = 2, -}; - /// \brief Enum that represents the various channel types on Discord. /// /// For more information see: https://discord.com/developers/docs/resources/channel @@ -505,6 +460,64 @@ enum class ChannelType { EphemeralDm = 18, }; +/// \brief Represents the type of additional content contained in a message. +enum class AdditionalContentType { + + /// \brief Other + Other = 0, + + /// \brief Attachment + Attachment = 1, + + /// \brief Poll + Poll = 2, + + /// \brief VoiceMessage + VoiceMessage = 3, + + /// \brief Thread + Thread = 4, + + /// \brief Embed + Embed = 5, + + /// \brief Sticker + Sticker = 6, +}; + +/// \brief Describes how the Discord client decides when to transmit the user's microphone audio. +enum class VoiceInputModeType { + + /// \brief Transmit when voice activity is detected. + VoiceActivity = 0, + + /// \brief Transmit while the push-to-talk shortcut is held. + PushToTalk = 1, +}; + +/// \brief The Discord Voice audio system to use. +enum class AudioSystem { + + /// \brief Use the standard audio system. + Standard = 0, + + /// \brief Use the game audio system. + Game = 1, +}; + +/// \brief Represents whether a voice call is using push to talk or auto voice detection +enum class AudioModeType { + + /// \brief MODE_UNINIT + MODE_UNINIT = 0, + + /// \brief MODE_VAD + MODE_VAD = 1, + + /// \brief MODE_PTT + MODE_PTT = 2, +}; + /// \brief Enum that represents the possible types of relationships that can exist between two users enum class RelationshipType { @@ -534,6 +547,31 @@ enum class RelationshipType { Suggestion = 6, }; +/// \brief The type of external identity provider. +enum class ExternalIdentityProviderType { + + /// \brief OIDC + OIDC = 0, + + /// \brief EpicOnlineServices + EpicOnlineServices = 1, + + /// \brief Steam + Steam = 2, + + /// \brief Unity + Unity = 3, + + /// \brief DiscordBot + DiscordBot = 4, + + /// \brief None + None = 5, + + /// \brief Unknown + Unknown = 6, +}; + /// \brief Enum that specifies the various online statuses for a user. /// /// Generally a user is online or offline, but in Discord users are able to further customize their @@ -608,6 +646,15 @@ enum class AuthenticationExternalAuthType { /// \brief UnityServicesIdToken UnityServicesIdToken = 4, + + /// \brief DiscordBotIssuedAccessToken + DiscordBotIssuedAccessToken = 5, + + /// \brief AppleIdToken + AppleIdToken = 6, + + /// \brief PlayStationNetworkIdToken + PlayStationNetworkIdToken = 7, }; /// \brief Enum that represents the various log levels supported by the SDK. @@ -663,12 +710,14 @@ class GuildChannel; class LinkedLobby; class LinkedChannel; class RelationshipHandle; +class UserApplicationProfileHandle; class UserHandle; class LobbyMemberHandle; class LobbyHandle; class AdditionalContent; class MessageHandle; class AudioDevice; +class VoiceSettings; class UserMessageSummary; class ClientCreateOptions; class Client; @@ -851,6 +900,14 @@ class ActivityAssets { std::optional SmallUrl() const; /// Setter for ActivityAssets::SmallUrl. void SetSmallUrl(std::optional SmallUrl); + + /// \brief The invite cover image identifier or URL, rendered as a banner image on activity + /// invites. + /// + /// If specified, must be a string between 1 and 300 characters. + std::optional InviteCoverImage() const; + /// Setter for ActivityAssets::InviteCoverImage. + void SetInviteCoverImage(std::optional InviteCoverImage); }; /// \brief \see Activity @@ -1284,7 +1341,7 @@ class Activity { /// \brief The name of the game or application that the activity is associated with. /// - /// This field cannot be set by the SDK, and will always be the name of the current game. + /// This field defaults to the name of the current game. std::string Name() const; /// Setter for Activity::Name. void SetName(std::string Name); @@ -1990,7 +2047,7 @@ class Call { /// call. /// /// If using push to talk you should call SetPTTActive() whenever the user presses their - /// confused push to talk key. + /// configured push to talk key. void SetAudioMode(discordpp::AudioModeType audioMode); /// \brief Locally mutes the given userId, so that the current user cannot hear them anymore. @@ -2205,6 +2262,21 @@ class GuildChannel { /// Setter for GuildChannel::Name. void SetName(std::string Name); + /// \brief The type of the channel. + discordpp::ChannelType Type() const; + /// Setter for GuildChannel::Type. + void SetType(discordpp::ChannelType Type); + + /// \brief The position of the channel in the guild's channel list. + int32_t Position() const; + /// Setter for GuildChannel::Position. + void SetPosition(int32_t Position); + + /// \brief The id of the parent category channel, if any. + std::optional ParentId() const; + /// Setter for GuildChannel::ParentId. + void SetParentId(std::optional ParentId); + /// \brief Whether the current user is able to link this channel to a lobby. /// /// For this to be true: @@ -2421,6 +2493,66 @@ class RelationshipHandle { std::optional User() const; }; +/// \brief A UserApplicationProfileHandle represents a profile from an external identity provider, +/// such as Steam or Epic Online Services. +/// +/// Handle objects in the SDK hold a reference both to the underlying data, and to the SDK instance. +/// Changes to the underlying data will generally be available on existing handles objects without +/// having to re-create them. If the SDK instance is destroyed, but you still have a reference to a +/// handle object, note that it will return the default value for all method calls (ie an empty +/// string for methods that return a string). +class UserApplicationProfileHandle { + /// \cond + mutable Discord_UserApplicationProfileHandle instance_{}; + DiscordObjectState state_ = DiscordObjectState::Invalid; + /// \endcond + +public: + /// \cond + Discord_UserApplicationProfileHandle* instance() const { return &instance_; } + /// \endcond + /// \cond + explicit UserApplicationProfileHandle(Discord_UserApplicationProfileHandle instance, + DiscordObjectState state); + ~UserApplicationProfileHandle(); + /// \endcond + /// Move constructor for UserApplicationProfileHandle + UserApplicationProfileHandle(UserApplicationProfileHandle&& other) noexcept; + /// Move assignment operator for UserApplicationProfileHandle + UserApplicationProfileHandle& operator=(UserApplicationProfileHandle&& other) noexcept; + /// Uninitialized instance of UserApplicationProfileHandle + static const UserApplicationProfileHandle nullobj; + /// Returns true if the instance contains a valid object + operator bool() const { return state_ != DiscordObjectState::Invalid; } + + /// Copy constructor for UserApplicationProfileHandle + UserApplicationProfileHandle(const UserApplicationProfileHandle& other); + /// Copy assignment operator for UserApplicationProfileHandle + UserApplicationProfileHandle& operator=(const UserApplicationProfileHandle& other); + + /// \cond + void Drop(); + /// \endcond + + /// \brief Returns the user's in-game avatar hash. + std::string AvatarHash() const; + + /// \brief Returns any metadata set by the developer. + std::string Metadata() const; + + /// \brief Returns the user's external identity provider ID if it exists. + std::optional ProviderId() const; + + /// \brief Returns the user's external identity provider issued user ID. + std::string ProviderIssuedUserId() const; + + /// \brief Returns the type of the external identity provider. + discordpp::ExternalIdentityProviderType ProviderType() const; + + /// \brief Returns the user's in-game username. + std::string Username() const; +}; + /// \brief A UserHandle represents a single user on Discord that the SDK knows about and contains /// basic account information for them such as id, name, and avatar, as well as their "status" /// information which includes both whether they are online/offline/etc as well as whether they are @@ -2531,6 +2663,11 @@ class UserHandle { /// \brief Returns the user's online/offline/idle status. discordpp::StatusType Status() const; + /// \brief Returns a list of UserApplicationProfileHandles for this user. Currently, a user can + /// only have a single profile per application, so this list will always contain at most one + /// UserApplicationProfileHandle. + std::vector UserApplicationProfiles() const; + /// \brief Returns the globally unique username of this user. /// /// For provisional accounts this is an auto-generated string. @@ -2617,8 +2754,9 @@ class LobbyMemberHandle { /// just an arbitrary, developer-controlled group of users that can communicate with each other. /// /// ## Managing Lobbies -/// Lobbies can be managed through a set of @ref server_apis that are documented elsewhere, which -/// allow you to create lobbies, add and remove users from lobbies, and delete them. +/// Lobbies can be managed through a set of [Server +/// APIs](https://docs.discord.com/developers/resources/lobby), which allow you to create lobbies, +/// add and remove users from lobbies, and delete them. /// /// There is also an API to create lobbies without any server side component using the /// Client::CreateOrJoinLobby function, which accepts a game-generated secret and will join the user @@ -2640,10 +2778,11 @@ class LobbyMemberHandle { /// status is set to Ready). Additionally, lobbies that are linked to a channel on Discord will not /// be auto deleted. /// -/// You can also use the @ref server_apis to customize this timeout, it can be raised to as high as -/// 7 days, meaning the lobby only gets deleted if no one connects to it for an entire week. This -/// should give a good amount of permanence to lobbies when needed, but there may be rare cases -/// where a lobby does need to be "rebuilt" if everyone is offline for an extended period. +/// You can also use the [Server APIs](https://docs.discord.com/developers/resources/lobby) to +/// customize this timeout, it can be raised to as high as 7 days, meaning the lobby only gets +/// deleted if no one connects to it for an entire week. This should give a good amount of +/// permanence to lobbies when needed, but there may be rare cases where a lobby does need to be +/// "rebuilt" if everyone is offline for an extended period. /// /// # Membership Limits /// Lobbies may have a maximum of 1,000 members, and each user may be in a maximum of 200 lobbies @@ -2911,6 +3050,12 @@ class MessageHandle { /// this method will return information about that content. std::optional AdditionalContent() const; + /// \brief Returns an additional display name for this message, if one was set. + /// + /// This is an optional, game-provided name (such as a character name) that the game or lobby + /// integration associated with the author for this lobby. + std::optional AdditionalName() const; + /// \brief Returns the application ID associated with this message, if any. You can use /// this to identify if the mesage was sent from another child application in /// your catalog. @@ -2960,6 +3105,14 @@ class MessageHandle { /// renders in game. std::unordered_map Metadata() const; + /// \brief Returns any moderation metadata the developer set on this message. + /// + /// Moderation metadata is just a set of simple string key/value pairs. + /// An example use case might be to include a flag that indicates the moderation status of the + /// message. Another example would be to include a re-written message that is more appropriate + /// for the game's audience. + std::unordered_map ModerationMetadata() const; + /// \brief Returns the content of this message, if any, but without replacing any markup from /// emojis and mentions. /// @@ -3039,6 +3192,94 @@ class AudioDevice { void SetIsDefault(bool IsDefault); }; +/// \brief A read-only snapshot of the user's voice settings in the connected Discord desktop +/// client. +/// +/// These belong to the Discord client, not to any individual Call. +class VoiceSettings { + /// \cond + mutable Discord_VoiceSettings instance_{}; + DiscordObjectState state_ = DiscordObjectState::Invalid; + /// \endcond + +public: + /// \cond + Discord_VoiceSettings* instance() const { return &instance_; } + /// \endcond + /// \cond + explicit VoiceSettings(Discord_VoiceSettings instance, DiscordObjectState state); + ~VoiceSettings(); + /// \endcond + /// Move constructor for VoiceSettings + VoiceSettings(VoiceSettings&& other) noexcept; + /// Move assignment operator for VoiceSettings + VoiceSettings& operator=(VoiceSettings&& other) noexcept; + /// Uninitialized instance of VoiceSettings + static const VoiceSettings nullobj; + /// Returns true if the instance contains a valid object + operator bool() const { return state_ != DiscordObjectState::Invalid; } + + /// Copy constructor for VoiceSettings + VoiceSettings(const VoiceSettings& arg0); + /// Copy assignment operator for VoiceSettings + VoiceSettings& operator=(const VoiceSettings& arg0); + + /// \cond + void Drop(); + /// \endcond + + /// \brief Self-mute state. + bool SelfMute() const; + /// Setter for VoiceSettings::SelfMute. + void SetSelfMute(bool SelfMute); + + /// \brief Self-deafen state. + bool SelfDeaf() const; + /// Setter for VoiceSettings::SelfDeaf. + void SetSelfDeaf(bool SelfDeaf); + + /// \brief When the client transmits microphone audio. + discordpp::VoiceInputModeType InputMode() const; + /// Setter for VoiceSettings::InputMode. + void SetInputMode(discordpp::VoiceInputModeType InputMode); + + /// \brief Display string for the push-to-talk key, such as "SHIFT + F". Empty when nothing is + /// bound. + std::string PttKey() const; + /// Setter for VoiceSettings::PttKey. + void SetPttKey(std::string PttKey); + + /// \brief Microphone volume, ranging from 0 to 100. + float InputVolume() const; + /// Setter for VoiceSettings::InputVolume. + void SetInputVolume(float InputVolume); + + /// \brief Speaker volume, ranging from 0 to 200. + float OutputVolume() const; + /// Setter for VoiceSettings::OutputVolume. + void SetOutputVolume(float OutputVolume); + + /// \brief Automatic gain control state. + bool AutomaticGainControl() const; + /// Setter for VoiceSettings::AutomaticGainControl. + void SetAutomaticGainControl(bool AutomaticGainControl); + + /// \brief Echo cancellation state. + bool EchoCancellation() const; + /// Setter for VoiceSettings::EchoCancellation. + void SetEchoCancellation(bool EchoCancellation); + + /// \brief Noise suppression state. + bool NoiseSuppression() const; + /// Setter for VoiceSettings::NoiseSuppression. + void SetNoiseSuppression(bool NoiseSuppression); + + /// \brief Noise cancellation state. + bool NoiseCancellation() const; + /// Setter for VoiceSettings::NoiseCancellation. + void SetNoiseCancellation(bool NoiseCancellation); +}; + /// \brief Represents a summary of a DM conversation with a user. class UserMessageSummary { /// \cond @@ -3150,6 +3391,12 @@ class ClientCreateOptions { /// Setter for ClientCreateOptions::ExperimentalAndroidPreventCommsForBluetooth. void SetExperimentalAndroidPreventCommsForBluetooth( bool ExperimentalAndroidPreventCommsForBluetooth); + + /// \brief CPU affinity mask hint for certain platforms. Depending on platform support, may or + /// may not be ignored. + std::optional CpuAffinityMask() const; + /// Setter for ClientCreateOptions::CpuAffinityMask. + void SetCpuAffinityMask(std::optional CpuAffinityMask); }; /// \brief The Client class is the main entry point for the Discord SDK. All functionality is @@ -3256,6 +3503,10 @@ class Client { using GetOutputDevicesCallback = std::function devices)>; + /// \brief Callback function for Client::GetVoiceSettings. + using GetVoiceSettingsCallback = + std::function; + /// \brief Callback function for Client::SetDeviceChangeCallback. using DeviceChangeCallback = std::function inputDevices, @@ -3274,6 +3525,9 @@ class Client { using VoiceParticipantChangedCallback = std::function; + /// \brief Callback function for Client::SetVoiceSettingsUpdatedCallback. + using VoiceSettingsUpdatedCallback = std::function; + /// \brief Callback function for Client::StartCallWithAudioCallbacks. /// /// The audio samples in `data` can be modified in-place to achieve simple DSP effects. @@ -3319,6 +3573,13 @@ class Client { int32_t expiresIn, std::string scopes)>; + /// \brief Callback invoked when a user requests to initiate the authorization flow from the + /// discord app + /// + /// The callback receives no args and must call the functions needed to initiate the auth flow + /// as if the user had clicked the account link button in the game + using AuthorizeRequestCallback = std::function; + /// \brief Callback function for the Client::RevokeToken method. using RevokeTokenCallback = std::function; @@ -3438,6 +3699,9 @@ class Client { /// \brief Callback function for Client::SetLobbyUpdatedCallback. using LobbyUpdatedCallback = std::function; + /// \brief Callback invoked when the IsDiscordAppInstalled function completes. + using IsDiscordAppInstalledCallback = std::function; + /// \brief Callback function for Client::AcceptActivityInvite. using AcceptActivityInviteCallback = std::function; @@ -3536,6 +3800,12 @@ class Client { /// Client::Connect. When calling Client::Connect, the application ID is set automatically uint64_t GetApplicationId(); + /// \brief (deprecated) + /// + /// \deprecated Please use GetCurrentUserV2 instead. This will be removed in a future version. + [[deprecated("Please use GetCurrentUserV2 instead. This will be removed in a future version.")]] + discordpp::UserHandle GetCurrentUser() const; + /// \brief Returns the ID of the system default audio device if the user has not explicitly /// chosen one. static std::string GetDefaultAudioDeviceId(); @@ -3636,6 +3906,12 @@ class Client { /// \brief Returns whether the current user's microphone is muted in all calls. bool GetSelfMuteAll() const; + /// \brief Asynchronously fetches the user's current voice settings from the connected Discord + /// client. + /// + /// Requires a running Discord desktop client and an approved Social SDK integration. + void GetVoiceSettings(discordpp::Client::GetVoiceSettingsCallback cb); + /// \brief Enables or disables AEC diagnostic recording. /// /// Used to diagnose issues with acoustic echo cancellation. The input and output waveform data @@ -3700,6 +3976,11 @@ class Client { /// [-100.0, 100.0] It defaults to -100.0, so is disabled. void SetNoAudioInputThreshold(float dBFSThreshold); + /// \brief Enables or disables Krisp noise cancellation. + /// + /// Defaults to off. When enabled, noise suppression is automatically disabled. + void SetNoiseCancellation(bool on); + /// \brief Enables basic background noise suppression. /// /// Defaults to on. @@ -3758,6 +4039,13 @@ class Client { /// to. void SetVoiceParticipantChangedCallback(discordpp::Client::VoiceParticipantChangedCallback cb); + /// \brief Sets a callback to be invoked whenever the user's voice settings change in the + /// connected Discord client. Pass an empty std::function to stop receiving updates. + /// + /// Requires the same access as Client::GetVoiceSettings. The callback never fires if the + /// client refuses the subscription. + void SetVoiceSettingsUpdatedCallback(discordpp::Client::VoiceSettingsUpdatedCallback callback); + /// \brief On iOS devices, show the system audio route picker. bool ShowAudioRoutePicker(); @@ -3864,7 +4152,7 @@ class Client { /// for you when performing the authorization. You can override state if you want for your own /// flow, but please be mindful to keep it a secure, random value. /// - If you are using the Client::GetToken function you will need to provide a "code challenge" - /// or "code verifier". We'll spare you the boring details of how that works (woo… crypto), as + /// or "code verifier". We'll spare you the boring details of how that works (woo... crypto), as /// we've made a simple function to create these for you, /// Client::CreateAuthorizationCodeVerifier. That returns a struct with two items, a `challenge` /// value to pass into this function and a `verifier` value to pass into Client::GetToken. @@ -4157,6 +4445,24 @@ class Client { std::string const& refreshToken, discordpp::Client::TokenExchangeCallback callback); + /// \brief Registers a callback to be invoked when a user requests to initiate the authorization + /// flow. + /// + /// When you register this callback, the Discord app will show new entry points to allow users + /// to initiate the authorization flow. + /// + /// This function is tied to upcoming Discord client functionality experiments that will be + /// rolled out to a percentage of Discord users over time. More documentation and implementation + /// details to come as the client experiments run. + void RegisterAuthorizeRequestCallback(discordpp::Client::AuthorizeRequestCallback callback); + + /// \brief Stops listening for the AUTHORIZE_REQUEST event and removes the registered callback + /// + /// This function is tied to upcoming Discord client functionality experiments that will be + /// rolled out to a percentage of Discord users over time. More documentation and implementation + /// details to come as the client experiments run. + void RemoveAuthorizeRequestCallback(); + /// \brief Revoke all application access/refresh tokens associated with a user with any valid /// access/refresh token. This will invalidate all tokens and they cannot be used again. This /// is useful if you want to log the user out of the game and invalidate their session. @@ -4304,14 +4610,17 @@ class Client { /// \brief Retrieves messages from the DM conversation with the specified user. /// /// Returns a list of MessageHandle representing the recent messages in the conversation with - /// the recipient, with a maximum number specified by the limit parameter. The messages are + /// the recipient, with a with a maximum of 200 messages and up to 72 hours. The messages are /// returned in reverse chronological order (newest first). This function checks the local cache /// first and only makes an HTTP request to Discord's API if there are not enough cached /// messages available. /// /// If limit is greater than 0, restricts the number of messages returned. If limit is 0 - /// or negative, the limit parameter is omitted from the request. This is intended for + /// or negative, the limit parameter is 200 messages and 72 hours. This is intended for /// games to load message history when users open a DM conversation. + /// + /// If either user hasn't played the game, there will be no channel between them and + /// this function will return a 404 `discordpp::ErrorType::HTTPError` error. void GetUserMessagesWithLimit(uint64_t recipientId, int32_t limit, discordpp::Client::UserMessagesWithLimitCallback cb); @@ -4548,6 +4857,8 @@ class Client { discordpp::Client::CreateOrJoinLobbyCallback callback); /// \brief Fetches all of the channels that the current user can access in the given guild. + /// Channels are sorted by their `position` field, which matches what you see in the Discord + /// client. /// /// The purpose of this is to power the channel linking flow for linking a Discord channel to an /// in-game lobby. So this function can be used to power a UI to let the user pick which channel @@ -4661,6 +4972,25 @@ class Client { discordpp::Client::LinkOrUnlinkChannelCallback callback); /// @} + /// @name Mobile + /// @{ + + /// \brief Checks whether the Discord mobile app is installed on this device. + /// On desktop platforms, always returns false. + /// + /// This check does not require a client connection and can be called at any time. + /// + /// This can be used to provide UI hints to users about whether they can authorize via the + /// Discord app, or whether they will need to use a web browser flow. + /// + /// Platform Requirements: + /// - iOS: Your app must include "discord" in the LSApplicationQueriesSchemes array + /// in your Info.plist for this check to work correctly. + /// - Android: Your app must include "com.discord" in the `queries` element + /// in your AndroidManifest.xml (required for Android 11+). + void IsDiscordAppInstalled(discordpp::Client::IsDiscordAppInstalledCallback callback); + /// @} + /// @name Presence /// @{ @@ -4706,8 +5036,8 @@ class Client { /// \brief Sends a Discord activity invite to the specified user. /// - /// The invite is sent as a message on Discord, which means it can be sent in the following - /// situations: + /// The invite is sent as a message on Discord, which means it can be sent if any + /// of the following are true: /// - Both users are online and in the game and have not blocked each other /// - Both users are friends with each other /// - Both users share a mutual Discord server and have previously DM'd each other on Discord @@ -4975,18 +5305,7 @@ class Client { /// @name Users /// @{ - /// \brief Returns the user associated with the current client. - /// - /// **Must not be called before the Client::GetStatus has changed to Status::Ready.** - /// If the client has disconnected, or is in the process of reconnecting, it will return the - /// previous value of the user, even if the auth token has changed since then. Wait for - /// client.GetStatus() to change to Ready before accessing it again. - /// If accessed before the client is ready, it will return a dummy object. - discordpp::UserHandle GetCurrentUser() const; - - /// \brief Returns the UserHandle associated with the current user, if one is available. - /// - /// Unlike GetCurrentUser(), this method returns std::nullopt instead of a dummy object + /// \brief Unlike GetCurrentUser(), this method returns std::nullopt instead of a dummy object /// when no user is authenticated or available. This provides clearer intent about when /// the user data is actually available. std::optional GetCurrentUserV2() const; @@ -5070,6 +5389,8 @@ class CallInfoHandle { inline const char* EnumToString(discordpp::ActivityActionTypes value) { switch (value) { + case discordpp::ActivityActionTypes::Invalid: + return "Invalid"; case discordpp::ActivityActionTypes::Join: return "Join"; case discordpp::ActivityActionTypes::JoinRequest: @@ -5328,45 +5649,97 @@ inline const char* EnumToString(discordpp::IntegrationType value) return "unknown"; } } -/// Converts a discordpp::AdditionalContentType to a string. -inline const char* EnumToString(discordpp::AdditionalContentType value) -{ - switch (value) { - case discordpp::AdditionalContentType::Other: - return "Other"; - case discordpp::AdditionalContentType::Attachment: - return "Attachment"; - case discordpp::AdditionalContentType::Poll: - return "Poll"; - case discordpp::AdditionalContentType::VoiceMessage: - return "VoiceMessage"; - case discordpp::AdditionalContentType::Thread: - return "Thread"; - case discordpp::AdditionalContentType::Embed: - return "Embed"; - case discordpp::AdditionalContentType::Sticker: - return "Sticker"; - default: - return "unknown"; - } -} -/// Converts a discordpp::AudioSystem to a string. -inline const char* EnumToString(discordpp::AudioSystem value) -{ - switch (value) { - case discordpp::AudioSystem::Standard: - return "Standard"; - case discordpp::AudioSystem::Game: - return "Game"; - default: - return "unknown"; - } -} -/// Converts a discordpp::Call::Error to a string. -inline const char* EnumToString(discordpp::Call::Error value) +/// Converts a discordpp::ChannelType to a string. +inline const char* EnumToString(discordpp::ChannelType value) { switch (value) { - case discordpp::Call::Error::None: + case discordpp::ChannelType::GuildText: + return "GuildText"; + case discordpp::ChannelType::Dm: + return "Dm"; + case discordpp::ChannelType::GuildVoice: + return "GuildVoice"; + case discordpp::ChannelType::GroupDm: + return "GroupDm"; + case discordpp::ChannelType::GuildCategory: + return "GuildCategory"; + case discordpp::ChannelType::GuildNews: + return "GuildNews"; + case discordpp::ChannelType::GuildStore: + return "GuildStore"; + case discordpp::ChannelType::GuildNewsThread: + return "GuildNewsThread"; + case discordpp::ChannelType::GuildPublicThread: + return "GuildPublicThread"; + case discordpp::ChannelType::GuildPrivateThread: + return "GuildPrivateThread"; + case discordpp::ChannelType::GuildStageVoice: + return "GuildStageVoice"; + case discordpp::ChannelType::GuildDirectory: + return "GuildDirectory"; + case discordpp::ChannelType::GuildForum: + return "GuildForum"; + case discordpp::ChannelType::GuildMedia: + return "GuildMedia"; + case discordpp::ChannelType::Lobby: + return "Lobby"; + case discordpp::ChannelType::EphemeralDm: + return "EphemeralDm"; + default: + return "unknown"; + } +} +/// Converts a discordpp::AdditionalContentType to a string. +inline const char* EnumToString(discordpp::AdditionalContentType value) +{ + switch (value) { + case discordpp::AdditionalContentType::Other: + return "Other"; + case discordpp::AdditionalContentType::Attachment: + return "Attachment"; + case discordpp::AdditionalContentType::Poll: + return "Poll"; + case discordpp::AdditionalContentType::VoiceMessage: + return "VoiceMessage"; + case discordpp::AdditionalContentType::Thread: + return "Thread"; + case discordpp::AdditionalContentType::Embed: + return "Embed"; + case discordpp::AdditionalContentType::Sticker: + return "Sticker"; + default: + return "unknown"; + } +} +/// Converts a discordpp::VoiceInputModeType to a string. +inline const char* EnumToString(discordpp::VoiceInputModeType value) +{ + switch (value) { + case discordpp::VoiceInputModeType::VoiceActivity: + return "VoiceActivity"; + case discordpp::VoiceInputModeType::PushToTalk: + return "PushToTalk"; + default: + return "unknown"; + } +} +/// Converts a discordpp::AudioSystem to a string. +inline const char* EnumToString(discordpp::AudioSystem value) +{ + switch (value) { + case discordpp::AudioSystem::Standard: + return "Standard"; + case discordpp::AudioSystem::Game: + return "Game"; + default: + return "unknown"; + } +} +/// Converts a discordpp::Call::Error to a string. +inline const char* EnumToString(discordpp::Call::Error value) +{ + switch (value) { + case discordpp::Call::Error::None: return "None"; case discordpp::Call::Error::SignalingConnectionFailed: return "SignalingConnectionFailed"; @@ -5418,46 +5791,6 @@ inline const char* EnumToString(discordpp::Call::Status value) return "unknown"; } } -/// Converts a discordpp::ChannelType to a string. -inline const char* EnumToString(discordpp::ChannelType value) -{ - switch (value) { - case discordpp::ChannelType::GuildText: - return "GuildText"; - case discordpp::ChannelType::Dm: - return "Dm"; - case discordpp::ChannelType::GuildVoice: - return "GuildVoice"; - case discordpp::ChannelType::GroupDm: - return "GroupDm"; - case discordpp::ChannelType::GuildCategory: - return "GuildCategory"; - case discordpp::ChannelType::GuildNews: - return "GuildNews"; - case discordpp::ChannelType::GuildStore: - return "GuildStore"; - case discordpp::ChannelType::GuildNewsThread: - return "GuildNewsThread"; - case discordpp::ChannelType::GuildPublicThread: - return "GuildPublicThread"; - case discordpp::ChannelType::GuildPrivateThread: - return "GuildPrivateThread"; - case discordpp::ChannelType::GuildStageVoice: - return "GuildStageVoice"; - case discordpp::ChannelType::GuildDirectory: - return "GuildDirectory"; - case discordpp::ChannelType::GuildForum: - return "GuildForum"; - case discordpp::ChannelType::GuildMedia: - return "GuildMedia"; - case discordpp::ChannelType::Lobby: - return "Lobby"; - case discordpp::ChannelType::EphemeralDm: - return "EphemeralDm"; - default: - return "unknown"; - } -} /// Converts a discordpp::RelationshipType to a string. inline const char* EnumToString(discordpp::RelationshipType value) { @@ -5480,6 +5813,28 @@ inline const char* EnumToString(discordpp::RelationshipType value) return "unknown"; } } +/// Converts a discordpp::ExternalIdentityProviderType to a string. +inline const char* EnumToString(discordpp::ExternalIdentityProviderType value) +{ + switch (value) { + case discordpp::ExternalIdentityProviderType::OIDC: + return "OIDC"; + case discordpp::ExternalIdentityProviderType::EpicOnlineServices: + return "EpicOnlineServices"; + case discordpp::ExternalIdentityProviderType::Steam: + return "Steam"; + case discordpp::ExternalIdentityProviderType::Unity: + return "Unity"; + case discordpp::ExternalIdentityProviderType::DiscordBot: + return "DiscordBot"; + case discordpp::ExternalIdentityProviderType::None: + return "None"; + case discordpp::ExternalIdentityProviderType::Unknown: + return "Unknown"; + default: + return "unknown"; + } +} /// Converts a discordpp::UserHandle::AvatarType to a string. inline const char* EnumToString(discordpp::UserHandle::AvatarType value) { @@ -5608,6 +5963,12 @@ inline const char* EnumToString(discordpp::AuthenticationExternalAuthType value) return "SteamSessionTicket"; case discordpp::AuthenticationExternalAuthType::UnityServicesIdToken: return "UnityServicesIdToken"; + case discordpp::AuthenticationExternalAuthType::DiscordBotIssuedAccessToken: + return "DiscordBotIssuedAccessToken"; + case discordpp::AuthenticationExternalAuthType::AppleIdToken: + return "AppleIdToken"; + case discordpp::AuthenticationExternalAuthType::PlayStationNetworkIdToken: + return "PlayStationNetworkIdToken"; default: return "unknown"; } @@ -6134,6 +6495,31 @@ void ActivityAssets::SetSmallUrl(std::optional SmallUrl) Discord_ActivityAssets_SetSmallUrl(&instance_, (SmallUrl.has_value() ? &SmallUrl__str : nullptr)); } +std::optional ActivityAssets::InviteCoverImage() const +{ + assert(state_ == DiscordObjectState::Owned); + bool returnIsNonNull__; + Discord_String returnValueNative__; + returnIsNonNull__ = Discord_ActivityAssets_InviteCoverImage(&instance_, &returnValueNative__); + if (!returnIsNonNull__) { + return {}; + } + std::string returnValue__(reinterpret_cast(returnValueNative__.ptr), + returnValueNative__.size); + Discord_Free(returnValueNative__.ptr); + return returnValue__; +} +void ActivityAssets::SetInviteCoverImage(std::optional InviteCoverImage) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_String InviteCoverImage__str{}; + if (InviteCoverImage.has_value()) { + InviteCoverImage__str.ptr = reinterpret_cast(InviteCoverImage->data()); + InviteCoverImage__str.size = InviteCoverImage->size(); + } + Discord_ActivityAssets_SetInviteCoverImage( + &instance_, (InviteCoverImage.has_value() ? &InviteCoverImage__str : nullptr)); +} const ActivityTimestamps ActivityTimestamps::nullobj{{}, DiscordObjectState::Invalid}; ActivityTimestamps::~ActivityTimestamps() { @@ -8286,6 +8672,46 @@ void GuildChannel::SetName(std::string Name) Discord_String Name__str{(uint8_t*)(Name.data()), Name.size()}; Discord_GuildChannel_SetName(&instance_, Name__str); } +discordpp::ChannelType GuildChannel::Type() const +{ + assert(state_ == DiscordObjectState::Owned); + Discord_ChannelType returnValue__; + returnValue__ = Discord_GuildChannel_Type(&instance_); + return static_cast(returnValue__); +} +void GuildChannel::SetType(discordpp::ChannelType Type) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_GuildChannel_SetType(&instance_, static_cast(Type)); +} +int32_t GuildChannel::Position() const +{ + assert(state_ == DiscordObjectState::Owned); + int32_t returnValue__; + returnValue__ = Discord_GuildChannel_Position(&instance_); + return returnValue__; +} +void GuildChannel::SetPosition(int32_t Position) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_GuildChannel_SetPosition(&instance_, Position); +} +std::optional GuildChannel::ParentId() const +{ + assert(state_ == DiscordObjectState::Owned); + bool returnIsNonNull__; + uint64_t returnValue__; + returnIsNonNull__ = Discord_GuildChannel_ParentId(&instance_, &returnValue__); + if (!returnIsNonNull__) { + return std::nullopt; + } + return returnValue__; +} +void GuildChannel::SetParentId(std::optional ParentId) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_GuildChannel_SetParentId(&instance_, (ParentId.has_value() ? &*ParentId : nullptr)); +} bool GuildChannel::IsLinkable() const { assert(state_ == DiscordObjectState::Owned); @@ -8632,6 +9058,140 @@ std::optional RelationshipHandle::User() const discordpp::UserHandle returnValue__(returnValueNative__, DiscordObjectState::Owned); return returnValue__; } +const UserApplicationProfileHandle UserApplicationProfileHandle::nullobj{ + {}, + DiscordObjectState::Invalid}; +UserApplicationProfileHandle::~UserApplicationProfileHandle() +{ + if (state_ == DiscordObjectState::Owned) { + Drop(); + state_ = DiscordObjectState::Invalid; + } +} +UserApplicationProfileHandle::UserApplicationProfileHandle( + UserApplicationProfileHandle&& other) noexcept + : instance_(other.instance_) + , state_(other.state_) +{ + other.state_ = DiscordObjectState::Invalid; +} +UserApplicationProfileHandle& UserApplicationProfileHandle::operator=( + UserApplicationProfileHandle&& other) noexcept +{ + if (this != &other) { + if (state_ == DiscordObjectState::Owned) { + Drop(); + } + instance_ = other.instance_; + state_ = other.state_; + other.state_ = DiscordObjectState::Invalid; + } + return *this; +} +UserApplicationProfileHandle::UserApplicationProfileHandle( + const UserApplicationProfileHandle& other) + : instance_{} + , state_(DiscordObjectState::Invalid) +{ + if (other.state_ == DiscordObjectState::Owned) { + Discord_UserApplicationProfileHandle_Clone(&instance_, other.instance()); + + state_ = DiscordObjectState::Owned; + } +} +UserApplicationProfileHandle& UserApplicationProfileHandle::operator=( + const UserApplicationProfileHandle& other) +{ + if (this != &other) { + if (state_ == DiscordObjectState::Owned) { + Drop(); + state_ = DiscordObjectState::Invalid; + } + if (other.state_ == DiscordObjectState::Owned) { + Discord_UserApplicationProfileHandle_Clone(&instance_, other.instance()); + + state_ = DiscordObjectState::Owned; + } + } + return *this; +} +UserApplicationProfileHandle::UserApplicationProfileHandle( + Discord_UserApplicationProfileHandle instance, + DiscordObjectState state) + : instance_(instance) + , state_(state) +{ +} +void UserApplicationProfileHandle::Drop() +{ + if (state_ != DiscordObjectState::Owned) { + return; + } + Discord_UserApplicationProfileHandle_Drop(&instance_); + state_ = DiscordObjectState::Invalid; +} +std::string UserApplicationProfileHandle::AvatarHash() const +{ + assert(state_ == DiscordObjectState::Owned); + Discord_String returnValueNative__; + Discord_UserApplicationProfileHandle_AvatarHash(&instance_, &returnValueNative__); + std::string returnValue__(reinterpret_cast(returnValueNative__.ptr), + returnValueNative__.size); + Discord_Free(returnValueNative__.ptr); + return returnValue__; +} +std::string UserApplicationProfileHandle::Metadata() const +{ + assert(state_ == DiscordObjectState::Owned); + Discord_String returnValueNative__; + Discord_UserApplicationProfileHandle_Metadata(&instance_, &returnValueNative__); + std::string returnValue__(reinterpret_cast(returnValueNative__.ptr), + returnValueNative__.size); + Discord_Free(returnValueNative__.ptr); + return returnValue__; +} +std::optional UserApplicationProfileHandle::ProviderId() const +{ + assert(state_ == DiscordObjectState::Owned); + bool returnIsNonNull__; + Discord_String returnValueNative__; + returnIsNonNull__ = + Discord_UserApplicationProfileHandle_ProviderId(&instance_, &returnValueNative__); + if (!returnIsNonNull__) { + return {}; + } + std::string returnValue__(reinterpret_cast(returnValueNative__.ptr), + returnValueNative__.size); + Discord_Free(returnValueNative__.ptr); + return returnValue__; +} +std::string UserApplicationProfileHandle::ProviderIssuedUserId() const +{ + assert(state_ == DiscordObjectState::Owned); + Discord_String returnValueNative__; + Discord_UserApplicationProfileHandle_ProviderIssuedUserId(&instance_, &returnValueNative__); + std::string returnValue__(reinterpret_cast(returnValueNative__.ptr), + returnValueNative__.size); + Discord_Free(returnValueNative__.ptr); + return returnValue__; +} +discordpp::ExternalIdentityProviderType UserApplicationProfileHandle::ProviderType() const +{ + assert(state_ == DiscordObjectState::Owned); + Discord_ExternalIdentityProviderType returnValue__; + returnValue__ = Discord_UserApplicationProfileHandle_ProviderType(&instance_); + return static_cast(returnValue__); +} +std::string UserApplicationProfileHandle::Username() const +{ + assert(state_ == DiscordObjectState::Owned); + Discord_String returnValueNative__; + Discord_UserApplicationProfileHandle_Username(&instance_, &returnValueNative__); + std::string returnValue__(reinterpret_cast(returnValueNative__.ptr), + returnValueNative__.size); + Discord_Free(returnValueNative__.ptr); + return returnValue__; +} const UserHandle UserHandle::nullobj{{}, DiscordObjectState::Invalid}; UserHandle::~UserHandle() { @@ -8799,6 +9359,19 @@ discordpp::StatusType UserHandle::Status() const returnValue__ = Discord_UserHandle_Status(&instance_); return static_cast(returnValue__); } +std::vector UserHandle::UserApplicationProfiles() const +{ + assert(state_ == DiscordObjectState::Owned); + Discord_UserApplicationProfileHandleSpan returnValueNative__; + Discord_UserHandle_UserApplicationProfiles(&instance_, &returnValueNative__); + std::vector returnValue__; + returnValue__.reserve(returnValueNative__.size); + for (size_t i__ = 0; i__ < returnValueNative__.size; ++i__) { + returnValue__.emplace_back(returnValueNative__.ptr[i__], DiscordObjectState::Owned); + } + Discord_Free(returnValueNative__.ptr); + return returnValue__; +} std::string UserHandle::Username() const { assert(state_ == DiscordObjectState::Owned); @@ -9269,6 +9842,20 @@ std::optional MessageHandle::AdditionalContent() c discordpp::AdditionalContent returnValue__(returnValueNative__, DiscordObjectState::Owned); return returnValue__; } +std::optional MessageHandle::AdditionalName() const +{ + assert(state_ == DiscordObjectState::Owned); + bool returnIsNonNull__; + Discord_String returnValueNative__; + returnIsNonNull__ = Discord_MessageHandle_AdditionalName(&instance_, &returnValueNative__); + if (!returnIsNonNull__) { + return {}; + } + std::string returnValue__(reinterpret_cast(returnValueNative__.ptr), + returnValueNative__.size); + Discord_Free(returnValueNative__.ptr); + return returnValue__; +} std::optional MessageHandle::ApplicationId() const { assert(state_ == DiscordObjectState::Owned); @@ -9376,6 +9963,16 @@ std::unordered_map MessageHandle::Metadata() const Discord_FreeProperties(returnValueNative__); return returnValue__; } +std::unordered_map MessageHandle::ModerationMetadata() const +{ + assert(state_ == DiscordObjectState::Owned); + Discord_Properties returnValueNative__; + Discord_MessageHandle_ModerationMetadata(&instance_, &returnValueNative__); + std::unordered_map returnValue__ = + ConvertReturnedProperties(returnValueNative__); + Discord_FreeProperties(returnValueNative__); + return returnValue__; +} std::string MessageHandle::RawContent() const { assert(state_ == DiscordObjectState::Owned); @@ -9534,6 +10131,195 @@ void AudioDevice::SetIsDefault(bool IsDefault) assert(state_ == DiscordObjectState::Owned); Discord_AudioDevice_SetIsDefault(&instance_, IsDefault); } +const VoiceSettings VoiceSettings::nullobj{{}, DiscordObjectState::Invalid}; +VoiceSettings::~VoiceSettings() +{ + if (state_ == DiscordObjectState::Owned) { + Drop(); + state_ = DiscordObjectState::Invalid; + } +} +VoiceSettings::VoiceSettings(VoiceSettings&& other) noexcept + : instance_(other.instance_) + , state_(other.state_) +{ + other.state_ = DiscordObjectState::Invalid; +} +VoiceSettings& VoiceSettings::operator=(VoiceSettings&& other) noexcept +{ + if (this != &other) { + if (state_ == DiscordObjectState::Owned) { + Drop(); + } + instance_ = other.instance_; + state_ = other.state_; + other.state_ = DiscordObjectState::Invalid; + } + return *this; +} +VoiceSettings::VoiceSettings(const VoiceSettings& arg0) + : instance_{} + , state_(DiscordObjectState::Invalid) +{ + if (arg0.state_ == DiscordObjectState::Owned) { + Discord_VoiceSettings_Clone(&instance_, arg0.instance()); + + state_ = DiscordObjectState::Owned; + } +} +VoiceSettings& VoiceSettings::operator=(const VoiceSettings& arg0) +{ + if (this != &arg0) { + if (state_ == DiscordObjectState::Owned) { + Drop(); + state_ = DiscordObjectState::Invalid; + } + if (arg0.state_ == DiscordObjectState::Owned) { + Discord_VoiceSettings_Clone(&instance_, arg0.instance()); + + state_ = DiscordObjectState::Owned; + } + } + return *this; +} +VoiceSettings::VoiceSettings(Discord_VoiceSettings instance, DiscordObjectState state) + : instance_(instance) + , state_(state) +{ +} +void VoiceSettings::Drop() +{ + if (state_ != DiscordObjectState::Owned) { + return; + } + Discord_VoiceSettings_Drop(&instance_); + state_ = DiscordObjectState::Invalid; +} +bool VoiceSettings::SelfMute() const +{ + assert(state_ == DiscordObjectState::Owned); + bool returnValue__; + returnValue__ = Discord_VoiceSettings_SelfMute(&instance_); + return returnValue__; +} +void VoiceSettings::SetSelfMute(bool SelfMute) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_VoiceSettings_SetSelfMute(&instance_, SelfMute); +} +bool VoiceSettings::SelfDeaf() const +{ + assert(state_ == DiscordObjectState::Owned); + bool returnValue__; + returnValue__ = Discord_VoiceSettings_SelfDeaf(&instance_); + return returnValue__; +} +void VoiceSettings::SetSelfDeaf(bool SelfDeaf) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_VoiceSettings_SetSelfDeaf(&instance_, SelfDeaf); +} +discordpp::VoiceInputModeType VoiceSettings::InputMode() const +{ + assert(state_ == DiscordObjectState::Owned); + Discord_VoiceInputModeType returnValue__; + returnValue__ = Discord_VoiceSettings_InputMode(&instance_); + return static_cast(returnValue__); +} +void VoiceSettings::SetInputMode(discordpp::VoiceInputModeType InputMode) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_VoiceSettings_SetInputMode(&instance_, + static_cast(InputMode)); +} +std::string VoiceSettings::PttKey() const +{ + assert(state_ == DiscordObjectState::Owned); + Discord_String returnValueNative__; + Discord_VoiceSettings_PttKey(&instance_, &returnValueNative__); + std::string returnValue__(reinterpret_cast(returnValueNative__.ptr), + returnValueNative__.size); + Discord_Free(returnValueNative__.ptr); + return returnValue__; +} +void VoiceSettings::SetPttKey(std::string PttKey) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_String PttKey__str{(uint8_t*)(PttKey.data()), PttKey.size()}; + Discord_VoiceSettings_SetPttKey(&instance_, PttKey__str); +} +float VoiceSettings::InputVolume() const +{ + assert(state_ == DiscordObjectState::Owned); + float returnValue__; + returnValue__ = Discord_VoiceSettings_InputVolume(&instance_); + return returnValue__; +} +void VoiceSettings::SetInputVolume(float InputVolume) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_VoiceSettings_SetInputVolume(&instance_, InputVolume); +} +float VoiceSettings::OutputVolume() const +{ + assert(state_ == DiscordObjectState::Owned); + float returnValue__; + returnValue__ = Discord_VoiceSettings_OutputVolume(&instance_); + return returnValue__; +} +void VoiceSettings::SetOutputVolume(float OutputVolume) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_VoiceSettings_SetOutputVolume(&instance_, OutputVolume); +} +bool VoiceSettings::AutomaticGainControl() const +{ + assert(state_ == DiscordObjectState::Owned); + bool returnValue__; + returnValue__ = Discord_VoiceSettings_AutomaticGainControl(&instance_); + return returnValue__; +} +void VoiceSettings::SetAutomaticGainControl(bool AutomaticGainControl) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_VoiceSettings_SetAutomaticGainControl(&instance_, AutomaticGainControl); +} +bool VoiceSettings::EchoCancellation() const +{ + assert(state_ == DiscordObjectState::Owned); + bool returnValue__; + returnValue__ = Discord_VoiceSettings_EchoCancellation(&instance_); + return returnValue__; +} +void VoiceSettings::SetEchoCancellation(bool EchoCancellation) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_VoiceSettings_SetEchoCancellation(&instance_, EchoCancellation); +} +bool VoiceSettings::NoiseSuppression() const +{ + assert(state_ == DiscordObjectState::Owned); + bool returnValue__; + returnValue__ = Discord_VoiceSettings_NoiseSuppression(&instance_); + return returnValue__; +} +void VoiceSettings::SetNoiseSuppression(bool NoiseSuppression) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_VoiceSettings_SetNoiseSuppression(&instance_, NoiseSuppression); +} +bool VoiceSettings::NoiseCancellation() const +{ + assert(state_ == DiscordObjectState::Owned); + bool returnValue__; + returnValue__ = Discord_VoiceSettings_NoiseCancellation(&instance_); + return returnValue__; +} +void VoiceSettings::SetNoiseCancellation(bool NoiseCancellation) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_VoiceSettings_SetNoiseCancellation(&instance_, NoiseCancellation); +} const UserMessageSummary UserMessageSummary::nullobj{{}, DiscordObjectState::Invalid}; UserMessageSummary::~UserMessageSummary() { @@ -9744,6 +10530,23 @@ void ClientCreateOptions::SetExperimentalAndroidPreventCommsForBluetooth( Discord_ClientCreateOptions_SetExperimentalAndroidPreventCommsForBluetooth( &instance_, ExperimentalAndroidPreventCommsForBluetooth); } +std::optional ClientCreateOptions::CpuAffinityMask() const +{ + assert(state_ == DiscordObjectState::Owned); + bool returnIsNonNull__; + uint64_t returnValue__; + returnIsNonNull__ = Discord_ClientCreateOptions_CpuAffinityMask(&instance_, &returnValue__); + if (!returnIsNonNull__) { + return std::nullopt; + } + return returnValue__; +} +void ClientCreateOptions::SetCpuAffinityMask(std::optional CpuAffinityMask) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_ClientCreateOptions_SetCpuAffinityMask( + &instance_, (CpuAffinityMask.has_value() ? &*CpuAffinityMask : nullptr)); +} const Client Client::nullobj{{}, DiscordObjectState::Invalid}; Client::~Client() { @@ -9819,6 +10622,14 @@ uint64_t Client::GetApplicationId() returnValue__ = Discord_Client_GetApplicationId(&instance_); return returnValue__; } +discordpp::UserHandle Client::GetCurrentUser() const +{ + assert(state_ == DiscordObjectState::Owned); + Discord_UserHandle returnValueNative__{}; + Discord_Client_GetCurrentUser(&instance_, &returnValueNative__); + discordpp::UserHandle returnValue__(returnValueNative__, DiscordObjectState::Owned); + return returnValue__; +} std::string Client::GetDefaultAudioDeviceId() { Discord_String returnValueNative__; @@ -10031,6 +10842,20 @@ bool Client::GetSelfMuteAll() const returnValue__ = Discord_Client_GetSelfMuteAll(&instance_); return returnValue__; } +void Client::GetVoiceSettings(discordpp::Client::GetVoiceSettingsCallback cb) +{ + assert(state_ == DiscordObjectState::Owned); + using Tcb__UserData = TDelegateUserData>; + auto cb__userData = new Tcb__UserData(cb); + Discord_Client_GetVoiceSettingsCallback cb__native = + [](auto result, auto settings, void* userData__) { + auto userData__typed = static_cast(userData__); + discordpp::ClientResult result__obj(*result, DiscordObjectState::Owned); + discordpp::VoiceSettings settings__obj(*settings, DiscordObjectState::Owned); + userData__typed->delegate(std::move(result__obj), std::move(settings__obj)); + }; + Discord_Client_GetVoiceSettings(&instance_, cb__native, Tcb__UserData::Free, cb__userData); +} void Client::SetAecDump(bool on) { assert(state_ == DiscordObjectState::Owned); @@ -10113,6 +10938,11 @@ void Client::SetNoAudioInputThreshold(float dBFSThreshold) assert(state_ == DiscordObjectState::Owned); Discord_Client_SetNoAudioInputThreshold(&instance_, dBFSThreshold); } +void Client::SetNoiseCancellation(bool on) +{ + assert(state_ == DiscordObjectState::Owned); + Discord_Client_SetNoiseCancellation(&instance_, on); +} void Client::SetNoiseSuppression(bool on) { assert(state_ == DiscordObjectState::Owned); @@ -10179,6 +11009,21 @@ void Client::SetVoiceParticipantChangedCallback( Discord_Client_SetVoiceParticipantChangedCallback( &instance_, cb__native, Tcb__UserData::Free, cb__userData); } +void Client::SetVoiceSettingsUpdatedCallback( + discordpp::Client::VoiceSettingsUpdatedCallback callback) +{ + assert(state_ == DiscordObjectState::Owned); + using Tcallback__UserData = TDelegateUserData>; + auto callback__userData = new Tcallback__UserData(callback); + Discord_Client_VoiceSettingsUpdatedCallback callback__native = [](auto settings, + void* userData__) { + auto userData__typed = static_cast(userData__); + discordpp::VoiceSettings settings__obj(*settings, DiscordObjectState::Owned); + userData__typed->delegate(std::move(settings__obj)); + }; + Discord_Client_SetVoiceSettingsUpdatedCallback( + &instance_, callback__native, Tcallback__UserData::Free, callback__userData); +} bool Client::ShowAudioRoutePicker() { assert(state_ == DiscordObjectState::Owned); @@ -10603,6 +11448,23 @@ void Client::RefreshToken(uint64_t applicationId, Tcallback__UserData::Free, callback__userData); } +void Client::RegisterAuthorizeRequestCallback(discordpp::Client::AuthorizeRequestCallback callback) +{ + assert(state_ == DiscordObjectState::Owned); + using Tcallback__UserData = TDelegateUserData>; + auto callback__userData = new Tcallback__UserData(callback); + Discord_Client_AuthorizeRequestCallback callback__native = [](void* userData__) { + auto userData__typed = static_cast(userData__); + userData__typed->delegate(); + }; + Discord_Client_RegisterAuthorizeRequestCallback( + &instance_, callback__native, Tcallback__UserData::Free, callback__userData); +} +void Client::RemoveAuthorizeRequestCallback() +{ + assert(state_ == DiscordObjectState::Owned); + Discord_Client_RemoveAuthorizeRequestCallback(&instance_); +} void Client::RevokeToken(uint64_t applicationId, std::string const& token, discordpp::Client::RevokeTokenCallback callback) @@ -11378,6 +12240,19 @@ void Client::UnlinkChannelFromLobby(uint64_t lobbyId, Discord_Client_UnlinkChannelFromLobby( &instance_, lobbyId, callback__native, Tcallback__UserData::Free, callback__userData); } +void Client::IsDiscordAppInstalled(discordpp::Client::IsDiscordAppInstalledCallback callback) +{ + assert(state_ == DiscordObjectState::Owned); + using Tcallback__UserData = TDelegateUserData>; + auto callback__userData = new Tcallback__UserData(callback); + Discord_Client_IsDiscordAppInstalledCallback callback__native = [](auto installed, + void* userData__) { + auto userData__typed = static_cast(userData__); + userData__typed->delegate(installed); + }; + Discord_Client_IsDiscordAppInstalled( + &instance_, callback__native, Tcallback__UserData::Free, callback__userData); +} void Client::AcceptActivityInvite(discordpp::ActivityInvite invite, discordpp::Client::AcceptActivityInviteCallback cb) { @@ -11816,14 +12691,6 @@ void Client::UnblockUser(uint64_t userId, discordpp::Client::UpdateRelationshipC }; Discord_Client_UnblockUser(&instance_, userId, cb__native, Tcb__UserData::Free, cb__userData); } -discordpp::UserHandle Client::GetCurrentUser() const -{ - assert(state_ == DiscordObjectState::Owned); - Discord_UserHandle returnValueNative__{}; - Discord_Client_GetCurrentUser(&instance_, &returnValueNative__); - discordpp::UserHandle returnValue__(returnValueNative__, DiscordObjectState::Owned); - return returnValue__; -} std::optional Client::GetCurrentUserV2() const { assert(state_ == DiscordObjectState::Owned); diff --git a/3rdPartyBinaries/discord_social_sdk_linux.zip b/3rdPartyBinaries/discord_social_sdk_linux.zip index e6961119da..a53f377992 100644 Binary files a/3rdPartyBinaries/discord_social_sdk_linux.zip and b/3rdPartyBinaries/discord_social_sdk_linux.zip differ diff --git a/3rdPartyBinaries/discord_social_sdk_mac.zip b/3rdPartyBinaries/discord_social_sdk_mac.zip index 8418ea9648..054f9cde58 100644 Binary files a/3rdPartyBinaries/discord_social_sdk_mac.zip and b/3rdPartyBinaries/discord_social_sdk_mac.zip differ diff --git a/3rdPartyBinaries/discord_social_sdk_win.zip b/3rdPartyBinaries/discord_social_sdk_win.zip index fd060106b7..796621e6b2 100644 Binary files a/3rdPartyBinaries/discord_social_sdk_win.zip and b/3rdPartyBinaries/discord_social_sdk_win.zip differ diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index 84e30d8486..a09a111ca1 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -148,6 +148,9 @@ link_directories(${CMAKE_CURRENT_LIST_DIR}) # add the list of all code file paths as ${CORE_LIBRARY_SOURCES}, ${LIBRARY_SOURCES} and ${EXECUTABLE_SOURCES} include(cmake/SourceFiles.cmake) +# add extract_discord_sdk(), which unpacks the per-platform Discord Social SDK zips +include(cmake/ExtractDiscordSDK.cmake) + # Organize source files in IDE project view source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../ FILES ${CORE_LIBRARY_SOURCES}) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../../ FILES ${LIBRARY_SOURCES}) @@ -581,13 +584,7 @@ else() # macOS and Linux set(DISCORD_LIB_RELEASE "${REPO_ROOT_DIR}/3rdPartyBinaries/discord_social_sdk_linux/lib/release/libdiscord_partner_sdk.so") endif() - if (NOT EXISTS "${DISCORD_DIR}") - message(STATUS "Discord SDK not found, extracting from zip...") - execute_process( - COMMAND ${CMAKE_COMMAND} -E tar xf "${DISCORD_ZIP}" - WORKING_DIRECTORY "${REPO_ROOT_DIR}/3rdPartyBinaries" - ) - endif() + extract_discord_sdk("${DISCORD_ZIP}" "${DISCORD_DIR}") target_compile_definitions(SerialProgramsLib PUBLIC PA_SOCIAL_SDK) target_include_directories(SerialProgramsLib SYSTEM PRIVATE ../3rdParty/discord_social_sdk/) @@ -761,14 +758,7 @@ if (WIN32) COMMAND cmd /c "if exist \"$\" ( \"${CMAKE_COMMAND}\" -E rename \"$\" \"${WIN_DEPLOY_DIR}/$\" ) else ( echo [Deploy] PDB file missing: $ )" ) - # Extract Discord SDK if missing - if (NOT EXISTS "${DISCORD_DIR}") - message(STATUS "Discord SDK not found, extracting from zip...") - execute_process( - COMMAND ${CMAKE_COMMAND} -E tar xf "${DISCORD_ZIP}" - WORKING_DIRECTORY "${REPO_ROOT_DIR}/3rdPartyBinaries" - ) - endif() + extract_discord_sdk("${DISCORD_ZIP}" "${DISCORD_DIR}") # Copy dpp dll add_custom_command( diff --git a/SerialPrograms/cmake/ExtractDiscordSDK.cmake b/SerialPrograms/cmake/ExtractDiscordSDK.cmake new file mode 100644 index 0000000000..6b166df418 --- /dev/null +++ b/SerialPrograms/cmake/ExtractDiscordSDK.cmake @@ -0,0 +1,73 @@ +# Extract the Discord Social SDK from `DISCORD_ZIP` into `DISCORD_DIR` when DISCORD_DIR does +# not exist or is older than DISCORD_ZIP. +# +function(extract_discord_sdk DISCORD_ZIP DISCORD_DIR) + if (NOT EXISTS "${DISCORD_ZIP}") + message(FATAL_ERROR "Discord SDK archive is missing: ${DISCORD_ZIP}") + endif() + + # Initialize the string for logging the reason for extracing the zip. + set(EXTRACT_REASON "") + + # Directories are excluded by GLOB_RECURSE, so this is the list of real files. + file(GLOB_RECURSE EXTRACTED_FILES "${DISCORD_DIR}/*") + + if (NOT EXISTS "${DISCORD_DIR}") + set(EXTRACT_REASON "not extracted yet") + elseif (NOT EXTRACTED_FILES) + set(EXTRACT_REASON "extracted directory is empty") + else() + # Compare each file's timestamp against the zip file. + file(TIMESTAMP "${DISCORD_ZIP}" ZIP_TIME "%s" UTC) + set(OLDEST_TIME "") + foreach (EXTRACTED_FILE IN LISTS EXTRACTED_FILES) + file(TIMESTAMP "${EXTRACTED_FILE}" FILE_TIME "%s" UTC) + # file(TIMESTAMP) yields "" for a file it cannot stat. Treat that as requiring + # extraction to cover the case of broken files. + if (FILE_TIME STREQUAL "") + set(OLDEST_TIME "") + break() + endif() + if (OLDEST_TIME STREQUAL "" OR FILE_TIME LESS OLDEST_TIME) + set(OLDEST_TIME "${FILE_TIME}") + endif() + endforeach() + if (OLDEST_TIME STREQUAL "") + set(EXTRACT_REASON "extracted files are unreadable") + elseif (ZIP_TIME STREQUAL "") + # Unknown zip timestamp: extract anyway + set(EXTRACT_REASON "zip timestamp is unreadable") + elseif (ZIP_TIME GREATER_EQUAL OLDEST_TIME) + # GREATER_EQUAL, not GREATER: file(TIMESTAMP) has whole-second resolution, so a + # zip replaced within the same second as the extraction is indistinguishable from + # one that predates it. + set(EXTRACT_REASON "zip is newer than the extracted files") + endif() + endif() + + if (EXTRACT_REASON STREQUAL "") + # No need to extract. + return() + endif() + + message(STATUS "Discord SDK ${EXTRACT_REASON}, extracting from ${DISCORD_ZIP}...") + + # Delete first so files dropped or renamed by the new SDK do not survive as leftovers. + file(REMOVE_RECURSE "${DISCORD_DIR}") + get_filename_component(DISCORD_PARENT_DIR "${DISCORD_DIR}" DIRECTORY) + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar xf "${DISCORD_ZIP}" + WORKING_DIRECTORY "${DISCORD_PARENT_DIR}" + RESULT_VARIABLE EXTRACT_RESULT + ) + if (NOT EXTRACT_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to extract ${DISCORD_ZIP} (error: ${EXTRACT_RESULT})") + endif() + + file(GLOB_RECURSE EXTRACTED_FILES "${DISCORD_DIR}/*") + if (NOT EXTRACTED_FILES) + message(FATAL_ERROR "Extracting ${DISCORD_ZIP} produced no files in ${DISCORD_DIR}") + endif() + # Touch the files to ensure their timestamps are newer to avoid redundant extraction. + file(TOUCH ${EXTRACTED_FILES}) +endfunction()