discord-bot/libs/DPP-10.0.29/include/dpp/presence.h

599 lines
12 KiB
C++
Raw Normal View History

2024-02-22 16:09:56 -05:00
/************************************************************************************
*
* D++, A Lightweight C++ library for Discord
*
* SPDX-License-Identifier: Apache-2.0
* Copyright 2021 Craig Edwards and D++ contributors
* (https://github.com/brainboxdotcc/DPP/graphs/contributors)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
************************************************************************************/
#pragma once
#include <dpp/export.h>
#include <dpp/snowflake.h>
#include <dpp/emoji.h>
#include <dpp/json_fwd.h>
#include <unordered_map>
#include <dpp/json_interface.h>
namespace dpp {
/**
* @brief Presence flags bitmask
*/
enum presence_flags {
/**
* @brief Desktop: Online.
*/
p_desktop_online = 0b00000001,
/**
* @brief Desktop: DND.
*/
p_desktop_dnd = 0b00000010,
/**
* @brief Desktop: Idle.
*/
p_desktop_idle = 0b00000011,
/**
* @brief Web: Online.
*/
p_web_online = 0b00000100,
/**
* @brief Web: DND.
*/
p_web_dnd = 0b00001000,
/**
* @brief Web: Idle.
*/
p_web_idle = 0b00001100,
/**
* @brief Mobile: Online.
*/
p_mobile_online = 0b00010000,
/**
* @brief Mobile: DND.
*/
p_mobile_dnd = 0b00100000,
/**
* @brief Mobile: Idle.
*/
p_mobile_idle = 0b00110000,
/**
* @brief General: Online.
*/
p_status_online = 0b01000000,
/**
* @brief General: DND.
*/
p_status_dnd = 0b10000000,
/**
* @brief General: Idle.
*/
p_status_idle = 0b11000000
};
/**
* @brief Online presence status values
*/
enum presence_status : uint8_t {
/**
* @brief Offline.
*/
ps_offline = 0,
/**
* @brief Online.
*/
ps_online = 1,
/**
* @brief DND.
*/
ps_dnd = 2,
/**
* @brief Idle.
*/
ps_idle = 3,
/**
* @brief Invisible (show as offline).
*/
ps_invisible = 4,
};
/**
* @brief Bit shift for desktop status.
*/
#define PF_SHIFT_DESKTOP 0
/**
* @brief Bit shift for web status.
*/
#define PF_SHIFT_WEB 2
/**
* @brief Bit shift for mobile status.
*/
#define PF_SHIFT_MOBILE 4
/**
* @brief Bit shift for main status.
*/
#define PF_SHIFT_MAIN 6
/**
* @brief Bit mask for status.
*/
#define PF_STATUS_MASK 0b00000011
/**
* @brief Bit mask for clearing desktop status.
*/
#define PF_CLEAR_DESKTOP 0b11111100
/**
* @brief Bit mask for clearing web status.
*/
#define PF_CLEAR_WEB 0b11110011
/**
* @brief Bit mask for clearing mobile status.
*/
#define PF_CLEAR_MOBILE 0b11001111
/**
* @brief Bit mask for clearing main status.
*/
#define PF_CLEAR_STATUS 0b00111111
/**
* @brief Game types
*/
enum activity_type : uint8_t {
/**
* @brief "Playing ..."
*/
at_game = 0,
/**
* @brief "Streaming ..."
*/
at_streaming = 1,
/**
* @brief "Listening to..."
*/
at_listening = 2,
/**
* @brief "Watching..."
*/
at_watching = 3,
/**
* @brief "Emoji..."
*/
at_custom = 4,
/**
* @brief "Competing in..."
*/
at_competing = 5
};
/**
* @brief Activity types for rich presence
*/
enum activity_flags {
/**
* @brief In an instance.
*/
af_instance = 0b000000001,
/**
* @brief Joining.
*/
af_join = 0b000000010,
/**
* @brief Spectating.
*/
af_spectate = 0b000000100,
/**
* @brief Sending join request.
*/
af_join_request = 0b000001000,
/**
* @brief Synchronising.
*/
af_sync = 0b000010000,
/**
* @brief Playing.
*/
af_play = 0b000100000,
/**
* @brief Party privacy friends.
*/
af_party_privacy_friends = 0b001000000,
/**
* @brief Party privacy voice channel.
*/
af_party_privacy_voice_channel = 0b010000000,
/**
* @brief Embedded.
*/
af_embedded = 0b100000000
};
/**
* @brief An activity button is a custom button shown in the rich presence. Can be to join a game or whatever
*/
struct DPP_EXPORT activity_button {
public:
/**
* @brief The text shown on the button (1-32 characters).
*/
std::string label;
/**
* @brief The url opened when clicking the button (1-512 characters, can be empty).
*
* @note Bots cannot access the activity button URLs.
*/
std::string url;
/** Constructor */
activity_button() = default;
};
/**
* @brief An activity asset are the images and the hover text displayed in the rich presence
*/
struct DPP_EXPORT activity_assets {
public:
/**
* @brief The large asset image which usually contain snowflake ID or prefixed image ID.
*/
std::string large_image;
/**
* @brief Text displayed when hovering over the large image of the activity.
*/
std::string large_text;
/**
* @brief The small asset image which usually contain snowflake ID or prefixed image ID.
*/
std::string small_image;
/**
* @brief Text displayed when hovering over the small image of the activity.
*/
std::string small_text;
/** Constructor */
activity_assets() = default;
};
/**
* @brief Secrets for Rich Presence joining and spectating.
*/
struct DPP_EXPORT activity_secrets {
public:
/**
* @brief The secret for joining a party.
*/
std::string join;
/**
* @brief The secret for spectating a game.
*/
std::string spectate;
/**
* @brief The secret for a specific instanced match.
*/
std::string match;
/** Constructor */
activity_secrets() = default;
};
/**
* @brief Information for the current party of the player
*/
struct DPP_EXPORT activity_party {
public:
/**
* @brief The ID of the party.
*/
snowflake id;
/**
* @brief The party's current size.
* Used to show the party's current size.
*/
int32_t current_size;
/**
* @brief The party's maximum size.
* Used to show the party's maximum size.
*/
int32_t maximum_size;
/** Constructor */
activity_party();
};
/**
* @brief An activity is a representation of what a user is doing. It might be a game, or a website, or a movie. Whatever.
*/
class DPP_EXPORT activity {
public:
/**
* @brief Name of activity.
* e.g. "Fortnite", "Mr Boom's Firework Factory", etc.
*/
std::string name;
/**
* @brief State of activity or the custom user status.
* e.g. "Waiting in lobby".
*/
std::string state;
/**
* @brief What the player is currently doing.
*/
std::string details;
/**
* @brief Images for the presence and their hover texts.
*/
activity_assets assets;
/**
* @brief URL of activity (this is also named details).
*
* @note Only applicable for certain sites such a YouTube
*/
std::string url;
/**
* @brief The custom buttons shown in the Rich Presence (max 2).
*/
std::vector<activity_button> buttons;
/**
* @brief The emoji used for the custom status.
*/
dpp::emoji emoji;
/**
* @brief Information of the current party if there is one.
*/
activity_party party;
/**
* @brief Secrets for rich presence joining and spectating.
*/
activity_secrets secrets;
/**
* @brief Activity type.
*/
activity_type type;
/**
* @brief Time activity was created.
*/
time_t created_at;
/**
* @brief Start time.
* e.g. when game was started.
*/
time_t start;
/**
* @brief End time.
* e.g. for songs on spotify.
*/
time_t end;
/**
* @brief Creating application.
* e.g. a linked account on the user's client.
*/
snowflake application_id;
/**
* @brief Flags bitmask from dpp::activity_flags.
*/
uint8_t flags;
/**
* @brief Whether or not the activity is an instanced game session.
*/
bool is_instance;
/**
* @brief Get the assets large image url if they have one, otherwise returns an empty string. In case of prefixed image IDs (mp:{image_id}) it returns an empty string.
*
* @see https://discord.com/developers/docs/topics/gateway-events#activity-object-activity-asset-image
*
* @param size The size of the image in pixels. It can be any power of two between 16 and 4096,
* otherwise the default sized image is returned.
* @param format The format to use for the avatar. It can be one of `i_webp`, `i_jpg` or `i_png`.
* @return std::string image url or an empty string, if required attributes are missing or an invalid format was passed
*/
std::string get_large_asset_url(uint16_t size = 0, const image_type format = i_png) const;
/**
* @brief Get the assets small image url if they have one, otherwise returns an empty string. In case of prefixed image IDs (mp:{image_id}) it returns an empty string.
*
* @see https://discord.com/developers/docs/topics/gateway-events#activity-object-activity-asset-image
*
* @param size The size of the image in pixels. It can be any power of two between 16 and 4096,
* otherwise the default sized image is returned.
* @param format The format to use for the avatar. It can be one of `i_webp`, `i_jpg` or `i_png`.
* @return std::string image url or an empty string, if required attributes are missing or an invalid format was passed
*/
std::string get_small_asset_url(uint16_t size = 0, const image_type format = i_png) const;
activity();
/**
* @brief Construct a new activity
*
* @param typ activity type
* @param nam Name of the activity
* @param stat State of the activity
* @param url_ url of the activity, only works for certain sites, such as YouTube
*/
activity(const activity_type typ, const std::string& nam, const std::string& stat, const std::string& url_);
};
/**
* @brief Represents user presence, e.g. what game they are playing and if they are online
*/
class DPP_EXPORT presence : public json_interface<presence> {
protected:
friend struct json_interface<presence>;
/** Fill this object from json.
* @param j JSON object to fill from
* @return A reference to self
*/
presence& fill_from_json_impl(nlohmann::json* j);
/** Build JSON from this object.
*
* @note This excludes any part of the presence object that are not valid for websockets and bots,
* and includes websocket opcode 3. You will not get what you expect if you call this on a user's
* presence received from on_presence_update or on_guild_create!
*
* @param with_id Add ID to output
* @return The JSON text of the presence
*/
virtual json to_json_impl(bool with_id = false) const;
public:
/**
* @brief The user the presence applies to.
*/
snowflake user_id;
/**
* @brief Guild ID.
*
* @note Apparently, Discord supports this internally, but the client doesn't...
*/
snowflake guild_id;
/**
* @brief Flags bitmask containing dpp::presence_flags
*/
uint8_t flags;
/**
* @brief List of activities.
*/
std::vector<activity> activities;
/** Constructor */
presence();
/**
* @brief Construct a new presence object with some parameters for sending to a websocket
*
* @param status Status of the activity
* @param type Type of activity
* @param activity_description Description of the activity
*/
presence(presence_status status, activity_type type, const std::string& activity_description);
/**
* @brief Construct a new presence object with some parameters for sending to a websocket.
*
* @param status Status of the activity
* @param a Activity itself
*/
presence(presence_status status, const activity& a);
/** Destructor */
~presence();
/**
* @brief The users status on desktop
* @return The user's status on desktop
*/
presence_status desktop_status() const;
/**
* @brief The user's status on web
* @return The user's status on web
*/
presence_status web_status() const;
/**
* @brief The user's status on mobile
* @return The user's status on mobile
*/
presence_status mobile_status() const;
/**
* @brief The user's status as shown to other users
* @return The user's status as shown to other users
*/
presence_status status() const;
/**
* @brief Build JSON from this object.
*
* @note This excludes any part of the presence object that are not valid for websockets and bots,
* and includes websocket opcode 3. You will not get what you expect if you call this on a user's
* presence received from on_presence_update or on_guild_create!
*
* @param with_id Add ID to output
* @return The JSON of the presence
*/
json to_json(bool with_id = false) const; // Intentional shadow of json_interface, mostly present for documentation
};
/**
* @brief A container of presences
*/
typedef std::unordered_map<snowflake, presence> presence_map;
} // namespace dpp