Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QoL fix: Enhance the entitlement stuff with data from the actual api docs now there are some #1166

Merged
merged 1 commit into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading