Skip to content

Commit

Permalink
Merge pull request #240 from Commandserver/i4
Browse files Browse the repository at this point in the history
feat: update activity and added some variables to it
  • Loading branch information
braindigitalis authored Jan 30, 2022
2 parents b5875e7 + d8e4005 commit 82701e3
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 18 deletions.
2 changes: 1 addition & 1 deletion include/dpp/cluster.h
Original file line number Diff line number Diff line change
Expand Up @@ -2506,7 +2506,7 @@ class DPP_EXPORT cluster {
/**
* @brief Edit guild widget
*
* Requires the `MANAGE_GUILD` permission.
* Requires the `MANAGE_GUILD` permission.
*
* @param guild_id Guild ID to edit widget for
* @param gw New guild widget information
Expand Down
142 changes: 132 additions & 10 deletions include/dpp/presence.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#pragma once
#include <dpp/export.h>
#include <dpp/snowflake.h>
#include <dpp/emoji.h>
#include <dpp/json_fwd.hpp>
#include <unordered_map>

Expand Down Expand Up @@ -114,17 +115,101 @@ enum activity_type : uint8_t {
*/
enum activity_flags {
/// In an instance
af_instance = 0b00000001,
af_instance = 0b000000001,
/// Joining
af_join = 0b00000010,
af_join = 0b000000010,
/// Spectating
af_spectate = 0b00000100,
af_spectate = 0b000000100,
/// Sending join request
af_join_request = 0b00001000,
af_join_request = 0b000001000,
/// Synchronising
af_sync = 0b00010000,
af_sync = 0b000010000,
/// Playing
af_play = 0b00100000
af_play = 0b000100000,
/// Party privacy friends
af_party_privacy_friends = 0b001000000,
/// Party privacy voice channel
af_party_privacy_voice_channel = 0b010000000,
/// 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:
/** The text shown on the button (1-32 characters)
*/
std::string label;
/** The url opened when clicking the button (1-512 characters). It's may 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:
/** The large asset image which usually contain snowflake ID or prefixed image ID
*/
std::string large_image;
/** Text displayed when hovering over the large image of the activity
*/
std::string large_text;
/** The small asset image which usually contain snowflake ID or prefixed image ID
*/
std::string small_image;
/** 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:
/** The secret for joining a party
*/
std::string join;
/** The secret for spectating a game
*/
std::string spectate;
/** 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:
/** The ID of the party
*/
snowflake id;
/** The party's current size. Used to show the party's current size
*/
int32_t current_size;
/** The party's maximum size. Used to show the party's maximum size
*/
int32_t maximum_size;

/** Constructor */
activity_party();
};

/**
Expand All @@ -136,15 +221,33 @@ class DPP_EXPORT activity {
* e.g. "Fortnite"
*/
std::string name;
/** State of activity.
/** State of activity or the custom user status.
* e.g. "Waiting in lobby"
*/
std::string state;
/** What the player is currently doing
*/
std::string details;
/** Images for the presence and their hover texts
*/
activity_assets assets;
/** URL.
* Only applicable for certain sites such a YouTube
* Alias: details
*/
std::string url;
/** The custom buttons shown in the Rich Presence (max 2)
*/
std::vector<activity_button> buttons;
/** The emoji used for the custom status
*/
dpp::emoji emoji;
/** Information of the current party if there is one
*/
activity_party party;
/** Secrets for rich presence joining and spectating
*/
activity_secrets secrets;
/** Activity type
*/
activity_type type;
Expand All @@ -160,11 +263,30 @@ class DPP_EXPORT activity {
/** Creating application (e.g. a linked account on the user's client)
*/
snowflake application_id;
/** Flags bitmask from activity_flags
/** Flags bitmask from dpp::activity_flags
*/
uint8_t flags;
/** 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.
*
* @param size The size of the image in pixels. It can be any power of two between 16 and 4096. if not specified, the default sized image is returned.
* @return image url or empty string
*/
std::string get_large_asset_url(uint16_t size = 0) 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.
*
* @param size The size of the image in pixels. It can be any power of two between 16 and 4096. if not specified, the default sized image is returned.
* @return image url or empty string
*/
std::string get_small_asset_url(uint16_t size = 0) const;

activity() = default;
activity();

/**
* @brief Construct a new activity
Expand All @@ -188,7 +310,7 @@ class DPP_EXPORT presence {
/** Guild ID. Apparently, Discord supports this internally but the client doesnt... */
snowflake guild_id;

/** Flags bitmask containing presence_flags */
/** Flags bitmask containing dpp::presence_flags */
uint8_t flags;

/** List of activities */
Expand Down
94 changes: 87 additions & 7 deletions src/dpp/presence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,56 @@
************************************************************************************/
#include <dpp/presence.h>
#include <dpp/discordevents.h>
#include <dpp/utility.h>
#include <dpp/emoji.h>
#include <dpp/nlohmann/json.hpp>
#include <dpp/fmt/format.h>

using json = nlohmann::json;

namespace dpp {

std::string activity::get_large_asset_url(uint16_t size) const {
// https://discord.com/developers/docs/topics/gateway#activity-object-activity-asset-image
if (!this->assets.large_image.empty() && this->application_id &&
this->assets.large_image.find(':') == std::string::npos) { // make sure it's not a prefixed proxy image
return fmt::format("{}/app-assets/{}/{}.png{}",
utility::cdn_host,
this->application_id,
this->assets.large_image,
utility::avatar_size(size)
);
} else {
return std::string();
}
}

std::string activity::get_small_asset_url(uint16_t size) const {
// https://discord.com/developers/docs/topics/gateway#activity-object-activity-asset-image
if (!this->assets.small_image.empty() && this->application_id &&
this->assets.small_image.find(':') == std::string::npos) { // make sure it's not a prefixed proxy image
return fmt::format("{}/app-assets/{}/{}.png{}",
utility::cdn_host,
this->application_id,
this->assets.small_image,
utility::avatar_size(size)
);
} else {
return std::string();
}
}

activity_party::activity_party() : id(0), current_size(0), maximum_size(0)
{
}

activity::activity(const activity_type typ, const std::string& nam, const std::string& stat, const std::string& url_) :
name(nam), state(stat), url(url_), type(typ)
{
name(nam), state(stat), url(url_), type(typ), created_at(0), start(0), end(0), application_id(0), flags(0), is_instance(false)
{
}

activity::activity(): created_at(0), start(0), end(0), application_id(0), flags(0), is_instance(false)
{
}

presence::presence() : user_id(0), guild_id(0), flags(0)
Expand Down Expand Up @@ -135,18 +176,57 @@ presence& presence::fill_from_json(nlohmann::json* j) {
for (auto & act : (*j)["activities"]) {
activity a;
a.name = string_not_null(&act, "name");
a.state = string_not_null(&act, "state"); // if user
if (a.state.empty()) a.state = string_not_null(&act, "details"); // if activity from bot, maybe?
a.details = string_not_null(&act, "details");
if (act.find("assets") != act.end()) {
a.assets.large_image = string_not_null(&act["assets"], "large_image");
a.assets.large_text = string_not_null(&act["assets"], "large_text");
a.assets.small_image = string_not_null(&act["assets"], "small_image");
a.assets.small_text = string_not_null(&act["assets"], "small_text");
}
a.state = string_not_null(&act, "state");
a.type = (activity_type)int8_not_null(&act, "type");
a.url = string_not_null(&act, "url");
if (act.find("buttons") != act.end()) {
for (auto &b : act["buttons"]) {
activity_button btn;
if (b.is_string()) { // its may be just a string (label) because normal bots cannot access the button URLs
btn.label = b;
} else {
btn.label = string_not_null(&b, "label");
btn.url = string_not_null(&b, "url");
}
a.buttons.push_back(btn);
}
}
if (act.find("emoji") != act.end()) {
a.emoji.name = string_not_null(&act["emoji"], "name");
a.emoji.id = snowflake_not_null(&act["emoji"], "id");
if (bool_not_null(&act["emoji"], "animated"))
a.emoji.flags |= e_animated;
}
if (act.find("party") != act.end()) {
a.party.id = snowflake_not_null(&act["party"], "id");
if (act["party"].find("size") != act["party"].end()) { // "size" is an array of two integers
try {
a.party.current_size = act["party"]["size"][0].get<int32_t>();
a.party.maximum_size = act["party"]["size"][1].get<int32_t>();
} catch (std::exception &exception) {}
}
}
if (act.find("secrets") != act.end()) {
a.secrets.join = string_not_null(&act["secret"], "join");
a.secrets.spectate = string_not_null(&act["secret"], "spectate");
a.secrets.match = string_not_null(&act["secret"], "match");
}
a.created_at = int64_not_null(&act, "created_at");
if (act.find("timestamps") != act.end()) {
a.start = int64_not_null(&(act["timestamps"]), "start");
a.end = int64_not_null(&(act["timestamps"]), "end");
a.start = int64_not_null(&act["timestamps"], "start");
a.end = int64_not_null(&act["timestamps"], "end");
}
a.application_id = snowflake_not_null(&act, "application_id");
a.flags = int8_not_null(&act, "flags");

a.is_instance = bool_not_null(&act, "instance");

activities.push_back(a);
}
}
Expand Down

0 comments on commit 82701e3

Please sign in to comment.