Skip to content

Commit

Permalink
QoL fix: Enhance the entitlement stuff with data from the actual api …
Browse files Browse the repository at this point in the history
…docs now there are some (#1166)
  • Loading branch information
braindigitalis authored Jun 10, 2024
2 parents 412fb65 + c5ef44b commit 3553d96
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 23 deletions.
75 changes: 68 additions & 7 deletions include/dpp/entitlement.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,29 @@ enum entitlement_type : uint8_t {
/**
* @brief Entitlement flags.
*/
enum entitlement_flags : uint16_t {
enum entitlement_flags : uint8_t {
/**
* @brief Entitlement was deleted
*
* @note Only discord staff can delete an entitlement via
* their internal tooling. It should rarely happen except in cases
* of fraud or chargeback.
*/
ent_deleted = 0b000000000000001,
ent_deleted = 0b0000001,

/**
* @brief Entitlement was consumed.
*
* @note A consumed entitlement is a used-up one-off purchase.
*/
ent_consumed = 0b0000010,
};

/**
* @brief A definition of a discord entitlement.
*
* An entitlement is a user's connection to an SKU, basically a subscription
* or a one-off purchase.
*/
class DPP_EXPORT entitlement : public managed, public json_interface<entitlement> {
protected:
Expand All @@ -85,7 +99,11 @@ class DPP_EXPORT entitlement : public managed, public json_interface<entitlement

public:
/**
* @brief ID of the SKU
* @brief ID of the entitlement event
*
* Not sure if this remains constant, it does not relate to the SKU,
* user, guild or subscription. Do not use it for anything except state
* tracking.
*/
snowflake sku_id{0};

Expand All @@ -95,9 +113,40 @@ class DPP_EXPORT entitlement : public managed, public json_interface<entitlement
snowflake application_id{0};

/**
* @brief Optional: ID of the user/guild that is granted access to the entitlement's SKU
* @brief Subscription ID
*
* This is a unique identifier of the user or guilds subscription to the SKU.
* It won't ever change.
*/
snowflake owner_id{0};
snowflake subscription_id{0};

/**
* @brief Promotion id
*
* These are undocumented but given in examples in the docs.
*/
snowflake promotion_id{0};

/**
* @brief Gift Code Flags (undocumented)
*
* Undocumented, but given in examples in the docs.
*/
uint8_t gift_code_flags{0};

/**
* @brief Optional: ID of the user that is granted access to the entitlement's SKU
*/
snowflake user_id{0};

/**
* @brief Optional: ID of the user that is granted access to the entitlement's SKU
*
* If a guild is provided, according to the examples the user who triggered the
* purchase will also be passed in the user ID. The presence of a non-zero guild
* id snowflake is indication it is a guild subscription.
*/
snowflake guild_id{0};

/**
* @brief The type of entitlement.
Expand Down Expand Up @@ -144,14 +193,26 @@ class DPP_EXPORT entitlement : public managed, public json_interface<entitlement
*
* @return entitlement_type Entitlement type
*/
entitlement_type get_type() const;
[[nodiscard]] entitlement_type get_type() const;

/**
* @brief Was the entitlement consumed?
*
* A consumed entitlement is a one off purchase which
* has been claimed as used by the application. for example
* in-app purchases.
*
* @return true if the entitlement was consumed.
*/
[[nodiscard]] bool is_consumed() const;

/**
* @brief Was the entitlement deleted?
*
* @return true if the entitlement was deleted.
*/
bool is_deleted() const;
[[nodiscard]] bool is_deleted() const;

};

/**
Expand Down
12 changes: 6 additions & 6 deletions src/dpp/cluster/entitlement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ namespace dpp {
void cluster::entitlements_get(snowflake user_id, const std::vector<snowflake>& sku_ids, snowflake before_id, snowflake after_id, uint8_t limit, snowflake guild_id, bool exclude_ended, command_completion_event_t callback) {
json j;

if(user_id) {
if (!user_id.empty()) {
j["user_id"] = user_id.str();
}

if(!sku_ids.empty()) {
if (!sku_ids.empty()) {
/* Why can't Discord just be consistent and accept an array of ids????
* Why just out of nowhere introduce a "comma-delimited set of snowflakes", like what.
* Just allow an array like you normally do!!!!!!!!!!!!
Expand All @@ -46,17 +46,17 @@ void cluster::entitlements_get(snowflake user_id, const std::vector<snowflake>&
j["sku_ids"] = ids;
}

if(before_id) {
if (!before_id.empty()) {
j["before_id"] = before_id.str();
}

if(after_id) {
if (!after_id.empty()) {
j["after_id"] = after_id.str();
}

j["limit"] = limit;

if(guild_id) {
if (!guild_id.empty()) {
j["guild_id"] = guild_id.str();
}

Expand All @@ -68,7 +68,7 @@ void cluster::entitlements_get(snowflake user_id, const std::vector<snowflake>&
void cluster::entitlement_test_create(const class entitlement& new_entitlement, command_completion_event_t callback) {
json j;
j["sku_id"] = new_entitlement.sku_id.str();
j["owner_id"] = new_entitlement.owner_id.str();
j["owner_id"] = new_entitlement.guild_id.empty() ? new_entitlement.guild_id.str() : new_entitlement.user_id.str();
j["owner_type"] = new_entitlement.type;
rest_request<entitlement>(this, API_PATH "/applications", me.id.str(), "entitlements", m_post, j, callback);
}
Expand Down
26 changes: 17 additions & 9 deletions src/dpp/entitlement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,31 @@ entitlement& entitlement::fill_from_json_impl(nlohmann::json* j) {
set_snowflake_not_null(j, "id", id);
set_snowflake_not_null(j, "sku_id", sku_id);
set_snowflake_not_null(j, "application_id", application_id);
set_snowflake_not_null(j, "promotion_id", promotion_id);
set_int8_not_null(j, "gift_code_flags", gift_code_flags);

/* Discord does separate these values, but asks for them as "owner_id" in the create event, just makes sense to make them as one as only one is ever set. */
if(snowflake_not_null(j, "user_id")) {
set_snowflake_not_null(j, "user_id", owner_id);
} else if(snowflake_not_null(j, "guild_id")) {
set_snowflake_not_null(j, "guild_id", owner_id);
if (snowflake_not_null(j, "subscription_id")) {
set_snowflake_not_null(j, "subscription_id", subscription_id);
}
if (snowflake_not_null(j, "user_id")) {
set_snowflake_not_null(j, "user_id", user_id);
}
if (snowflake_not_null(j, "guild_id")) {
set_snowflake_not_null(j, "guild_id", guild_id);
}

type = static_cast<entitlement_type>(int8_not_null(j, "type"));

if (bool_not_null(j, "deleted")) {
flags |= ent_deleted;
}
if (bool_not_null(j, "consumed")) {
flags |= ent_consumed;
}

set_ts_not_null(j, "starts_at", starts_at);
set_ts_not_null(j, "ends_at", ends_at);

/*
* TODO: Look at the entitlement example on docs and see what we're missing, add it here after. Discord seems to be missing information in their structure as their example shows more data.
*/

return *this;
}

Expand All @@ -75,4 +79,8 @@ bool entitlement::is_deleted() const {
return flags & entitlement_flags::ent_deleted;
}

bool entitlement::is_consumed() const {
return flags & entitlement_flags::ent_consumed;
}

} // namespace dpp

0 comments on commit 3553d96

Please sign in to comment.