more monetizatios stuffz (#3002)
* uhhhhhhhhhhhhhhhhhhh yes * uhhhhhhhhhhhhhhhhhhh yes * ~~i love git~~
This commit is contained in:
@@ -265,6 +265,11 @@ namespace Discord
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const int MaxEntitlementsPerBatch = 100;
|
public const int MaxEntitlementsPerBatch = 100;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the maximum number of subscriptions that can be gotten per-batch.
|
||||||
|
/// </summary>
|
||||||
|
public const int MaxSubscriptionsPerBatch = 100;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the maximum number of poll answer voters that can be gotten per-batch.
|
/// Returns the maximum number of poll answer voters that can be gotten per-batch.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Discord;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a subscription object.
|
||||||
|
/// </summary>
|
||||||
|
public interface ISubscription : ISnowflakeEntity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ID of the user who is subscribed.
|
||||||
|
/// </summary>
|
||||||
|
ulong UserId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the SKUs subscribed to.
|
||||||
|
/// </summary>
|
||||||
|
IReadOnlyCollection<ulong> SKUIds { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the entitlements granted for this subscription.
|
||||||
|
/// </summary>
|
||||||
|
IReadOnlyCollection<ulong> EntitlementIds { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the start of the current subscription period.
|
||||||
|
/// </summary>
|
||||||
|
DateTimeOffset CurrentPeriodStart { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets end of the current subscription period.
|
||||||
|
/// </summary>
|
||||||
|
DateTimeOffset CurrentPeriodEnd { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current status of the subscription.
|
||||||
|
/// </summary>
|
||||||
|
SubscriptionStatus Status { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets when the subscription was canceled.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <see langword="null"/> if the subscription has not been canceled.
|
||||||
|
/// </remarks>
|
||||||
|
DateTimeOffset? CanceledAt { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets country code of the payment source used to purchase the subscription.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Requires an oauth scope.
|
||||||
|
/// </remarks>
|
||||||
|
string Country { get; }
|
||||||
|
}
|
||||||
@@ -30,12 +30,18 @@ public struct SKU : ISnowflakeEntity
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Slug { get; }
|
public string Slug { get; }
|
||||||
|
|
||||||
internal SKU(ulong id, SKUType type, ulong applicationId, string name, string slug)
|
/// <summary>
|
||||||
|
/// Gets the flags for this SKU.
|
||||||
|
/// </summary>
|
||||||
|
public SKUFlags Flags { get; }
|
||||||
|
|
||||||
|
internal SKU(ulong id, SKUType type, ulong applicationId, string name, string slug, SKUFlags flags)
|
||||||
{
|
{
|
||||||
Id = id;
|
Id = id;
|
||||||
Type = type;
|
Type = type;
|
||||||
ApplicationId = applicationId;
|
ApplicationId = applicationId;
|
||||||
Name = name;
|
Name = name;
|
||||||
Slug = slug;
|
Slug = slug;
|
||||||
|
Flags = flags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ namespace Discord;
|
|||||||
[Flags]
|
[Flags]
|
||||||
public enum SKUFlags
|
public enum SKUFlags
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The SKU is available for purchase.
|
||||||
|
/// </summary>
|
||||||
|
IsAvailable = 1 << 2,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The SKU is a guild subscription.
|
/// The SKU is a guild subscription.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
namespace Discord;
|
||||||
|
|
||||||
|
public enum SubscriptionStatus
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Subscription is active and scheduled to renew.
|
||||||
|
/// </summary>
|
||||||
|
Active = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Subscription is active but will not renew.
|
||||||
|
/// </summary>
|
||||||
|
Ending = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Subscription is inactive and not being charged.
|
||||||
|
/// </summary>
|
||||||
|
Inactive = 2
|
||||||
|
}
|
||||||
@@ -341,7 +341,7 @@ namespace Discord
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns all entitlements for a given app, active and expired.
|
/// Returns all entitlements for a given app, active and expired.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IAsyncEnumerable<IReadOnlyCollection<IEntitlement>> GetEntitlementsAsync(int? limit = 100,
|
IAsyncEnumerable<IReadOnlyCollection<IEntitlement>> GetEntitlementsAsync(int limit = 100,
|
||||||
ulong? afterId = null, ulong? beforeId = null, bool excludeEnded = false, ulong? guildId = null, ulong? userId = null,
|
ulong? afterId = null, ulong? beforeId = null, bool excludeEnded = false, ulong? guildId = null, ulong? userId = null,
|
||||||
ulong[] skuIds = null, RequestOptions options = null);
|
ulong[] skuIds = null, RequestOptions options = null);
|
||||||
|
|
||||||
@@ -357,6 +357,17 @@ namespace Discord
|
|||||||
/// <param name="options">The options to be used when sending the request.</param>
|
/// <param name="options">The options to be used when sending the request.</param>
|
||||||
Task ConsumeEntitlementAsync(ulong entitlementId, RequestOptions options = null);
|
Task ConsumeEntitlementAsync(ulong entitlementId, RequestOptions options = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns all subscriptions for a given SKU.
|
||||||
|
/// </summary>
|
||||||
|
IAsyncEnumerable<IReadOnlyCollection<ISubscription>> GetSKUSubscriptionsAsync(ulong skuId, int limit = 100, ulong? afterId = null,
|
||||||
|
ulong? beforeId = null, ulong? userId = null, RequestOptions options = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a subscription by its id.
|
||||||
|
/// </summary>
|
||||||
|
Task<ISubscription> GetSKUSubscriptionAsync(ulong skuId, ulong subscriptionId, RequestOptions options = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets an emote for the current application.
|
/// Gets an emote for the current application.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -30,5 +30,5 @@ internal class Entitlement
|
|||||||
public Optional<DateTimeOffset> StartsAt { get; set; }
|
public Optional<DateTimeOffset> StartsAt { get; set; }
|
||||||
|
|
||||||
[JsonProperty("ends_at")]
|
[JsonProperty("ends_at")]
|
||||||
public Optional<DateTimeOffset> EndsAt { get; set; }
|
public Optional<DateTimeOffset?> EndsAt { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,4 +18,7 @@ internal class SKU
|
|||||||
|
|
||||||
[JsonProperty("slug")]
|
[JsonProperty("slug")]
|
||||||
public string Slug { get; set; }
|
public string Slug { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("flags")]
|
||||||
|
public SKUFlags Flags { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
34
src/Discord.Net.Rest/API/Common/Subscription.cs
Normal file
34
src/Discord.Net.Rest/API/Common/Subscription.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Discord.API;
|
||||||
|
|
||||||
|
internal class Subscription
|
||||||
|
{
|
||||||
|
[JsonProperty("id")]
|
||||||
|
public ulong Id { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("user_id")]
|
||||||
|
public ulong UserId { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("sku_ids")]
|
||||||
|
public ulong[] SKUIds { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("entitlement_ids")]
|
||||||
|
public ulong[] EntitlementIds { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("current_period_start")]
|
||||||
|
public DateTimeOffset CurrentPeriodStart { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("current_period_end")]
|
||||||
|
public DateTimeOffset CurrentPeriodEnd { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("status")]
|
||||||
|
public SubscriptionStatus Status { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("canceled_at")]
|
||||||
|
public DateTimeOffset? CanceledAt { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("country")]
|
||||||
|
public string Country { get; set; }
|
||||||
|
}
|
||||||
@@ -286,7 +286,7 @@ namespace Discord.Rest
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns all entitlements for a given app.
|
/// Returns all entitlements for a given app.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IAsyncEnumerable<IReadOnlyCollection<IEntitlement>> IDiscordClient.GetEntitlementsAsync(int? limit, ulong? afterId, ulong? beforeId,
|
IAsyncEnumerable<IReadOnlyCollection<IEntitlement>> IDiscordClient.GetEntitlementsAsync(int limit, ulong? afterId, ulong? beforeId,
|
||||||
bool excludeEnded, ulong? guildId, ulong? userId, ulong[] skuIds, RequestOptions options) => AsyncEnumerable.Empty<IReadOnlyCollection<IEntitlement>>();
|
bool excludeEnded, ulong? guildId, ulong? userId, ulong[] skuIds, RequestOptions options) => AsyncEnumerable.Empty<IReadOnlyCollection<IEntitlement>>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -299,6 +299,17 @@ namespace Discord.Rest
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Task IDiscordClient.ConsumeEntitlementAsync(ulong entitlementId, RequestOptions options) => Task.CompletedTask;
|
Task IDiscordClient.ConsumeEntitlementAsync(ulong entitlementId, RequestOptions options) => Task.CompletedTask;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns all subscriptions for a given SKU.
|
||||||
|
/// </summary>
|
||||||
|
IAsyncEnumerable<IReadOnlyCollection<ISubscription>> IDiscordClient.GetSKUSubscriptionsAsync(ulong skuId, int limit, ulong? afterId,
|
||||||
|
ulong? beforeId, ulong? userId, RequestOptions options) => AsyncEnumerable.Empty<IReadOnlyCollection<ISubscription>>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a subscription by its id.
|
||||||
|
/// </summary>
|
||||||
|
Task<ISubscription> IDiscordClient.GetSKUSubscriptionAsync(ulong skuId, ulong subscriptionId, RequestOptions options) => Task.FromResult<ISubscription>(null);
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
Task<Emote> IDiscordClient.GetApplicationEmoteAsync(ulong emoteId, RequestOptions options) => Task.FromResult<Emote>(null);
|
Task<Emote> IDiscordClient.GetApplicationEmoteAsync(ulong emoteId, RequestOptions options) => Task.FromResult<Emote>(null);
|
||||||
|
|||||||
@@ -443,12 +443,46 @@ namespace Discord.Rest
|
|||||||
{
|
{
|
||||||
var models = await client.ApiClient.ListSKUsAsync(options).ConfigureAwait(false);
|
var models = await client.ApiClient.ListSKUsAsync(options).ConfigureAwait(false);
|
||||||
|
|
||||||
return models.Select(x => new SKU(x.Id, x.Type, x.ApplicationId, x.Name, x.Slug)).ToImmutableArray();
|
return models.Select(x => new SKU(x.Id, x.Type, x.ApplicationId, x.Name, x.Slug, x.Flags)).ToImmutableArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task ConsumeEntitlementAsync(BaseDiscordClient client, ulong entitlementId, RequestOptions options = null)
|
public static Task ConsumeEntitlementAsync(BaseDiscordClient client, ulong entitlementId, RequestOptions options = null)
|
||||||
=> client.ApiClient.ConsumeEntitlementAsync(entitlementId, options);
|
=> client.ApiClient.ConsumeEntitlementAsync(entitlementId, options);
|
||||||
|
|
||||||
|
public static async Task<RestSubscription> GetSKUSubscriptionAsync(BaseDiscordClient client, ulong skuId, ulong subscriptionId, RequestOptions options = null)
|
||||||
|
{
|
||||||
|
var model = await client.ApiClient.GetSKUSubscriptionAsync(skuId, subscriptionId, options);
|
||||||
|
|
||||||
|
return RestSubscription.Create(client, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IAsyncEnumerable<IReadOnlyCollection<RestSubscription>> ListSubscriptionsAsync(BaseDiscordClient client, ulong skuId, int limit = 100,
|
||||||
|
ulong? afterId = null, ulong? beforeId = null, ulong? userId = null, RequestOptions options = null)
|
||||||
|
{
|
||||||
|
return new PagedAsyncEnumerable<RestSubscription>(
|
||||||
|
DiscordConfig.MaxSubscriptionsPerBatch,
|
||||||
|
async (info, ct) =>
|
||||||
|
{
|
||||||
|
var _afterId = afterId;
|
||||||
|
if (info.Position != null)
|
||||||
|
_afterId = info.Position.Value;
|
||||||
|
var models = await client.ApiClient.ListSKUSubscriptionsAsync(skuId, beforeId, _afterId, limit, userId, options).ConfigureAwait(false);
|
||||||
|
return models
|
||||||
|
.Select(x => RestSubscription.Create(client, x))
|
||||||
|
.ToImmutableArray();
|
||||||
|
},
|
||||||
|
nextPage: (info, lastPage) =>
|
||||||
|
{
|
||||||
|
if (lastPage.Count != DiscordConfig.MaxSubscriptionsPerBatch)
|
||||||
|
return false;
|
||||||
|
info.Position = lastPage.Max(x => x.Id);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
start: afterId,
|
||||||
|
count: limit
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Application Emojis
|
#region Application Emojis
|
||||||
|
|||||||
@@ -2852,6 +2852,24 @@ namespace Discord.API
|
|||||||
public Task ConsumeEntitlementAsync(ulong entitlementId, RequestOptions options = null)
|
public Task ConsumeEntitlementAsync(ulong entitlementId, RequestOptions options = null)
|
||||||
=> SendAsync("POST", () => $"applications/{CurrentApplicationId}/entitlements/{entitlementId}/consume", new BucketIds(), options: options);
|
=> SendAsync("POST", () => $"applications/{CurrentApplicationId}/entitlements/{entitlementId}/consume", new BucketIds(), options: options);
|
||||||
|
|
||||||
|
public Task<Subscription> GetSKUSubscriptionAsync(ulong skuId, ulong subscriptionId, RequestOptions options = null)
|
||||||
|
=> SendAsync<Subscription>("GET", () => $"skus/{skuId}/subscriptions/{subscriptionId}", new BucketIds(), options: options);
|
||||||
|
|
||||||
|
public Task<Subscription[]> ListSKUSubscriptionsAsync(ulong skuId, ulong? before = null, ulong? after = null, int limit = 100, ulong? userId = null, RequestOptions options = null)
|
||||||
|
{
|
||||||
|
Preconditions.AtMost(100, limit, "Limit must be less or equal to 100.");
|
||||||
|
Preconditions.AtLeast(1, limit, "Limit must be greater or equal to 1.");
|
||||||
|
|
||||||
|
var args = $"?limit={limit}";
|
||||||
|
if (before is not null)
|
||||||
|
args += $"&before={before}";
|
||||||
|
if (after is not null)
|
||||||
|
args += $"&after={after}";
|
||||||
|
if (userId is not null)
|
||||||
|
args += $"&user_id={userId}";
|
||||||
|
|
||||||
|
return SendAsync<Subscription[]>("GET", () => $"skus/{skuId}/subscriptions{args}", new BucketIds(), options: options);
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Polls
|
#region Polls
|
||||||
|
|||||||
@@ -300,6 +300,15 @@ namespace Discord.Rest
|
|||||||
public Task ConsumeEntitlementAsync(ulong entitlementId, RequestOptions options = null)
|
public Task ConsumeEntitlementAsync(ulong entitlementId, RequestOptions options = null)
|
||||||
=> ClientHelper.ConsumeEntitlementAsync(this, entitlementId, options);
|
=> ClientHelper.ConsumeEntitlementAsync(this, entitlementId, options);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IDiscordClient.GetSKUSubscriptionAsync" />
|
||||||
|
public Task<RestSubscription> GetSKUSubscriptionAsync(ulong skuId, ulong subscriptionId, RequestOptions options = null)
|
||||||
|
=> ClientHelper.GetSKUSubscriptionAsync(this, skuId, subscriptionId, options);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IDiscordClient.GetSKUSubscriptionsAsync" />
|
||||||
|
public IAsyncEnumerable<IReadOnlyCollection<RestSubscription>> GetSKUSubscriptionsAsync(ulong skuId, int limit = 100, ulong? afterId = null,
|
||||||
|
ulong? beforeId = null, ulong? userId = null, RequestOptions options = null)
|
||||||
|
=> ClientHelper.ListSubscriptionsAsync(this, skuId, limit, afterId, beforeId, userId, options);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<Emote> GetApplicationEmoteAsync(ulong emoteId, RequestOptions options = null)
|
public Task<Emote> GetApplicationEmoteAsync(ulong emoteId, RequestOptions options = null)
|
||||||
=> ClientHelper.GetApplicationEmojiAsync(this, emoteId, options);
|
=> ClientHelper.GetApplicationEmojiAsync(this, emoteId, options);
|
||||||
@@ -330,6 +339,14 @@ namespace Discord.Rest
|
|||||||
async Task<IApplication> IDiscordClient.GetApplicationInfoAsync(RequestOptions options)
|
async Task<IApplication> IDiscordClient.GetApplicationInfoAsync(RequestOptions options)
|
||||||
=> await GetApplicationInfoAsync(options).ConfigureAwait(false);
|
=> await GetApplicationInfoAsync(options).ConfigureAwait(false);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
async Task<ISubscription> IDiscordClient.GetSKUSubscriptionAsync(ulong skuId, ulong subscriptionId, RequestOptions options)
|
||||||
|
=> await GetSKUSubscriptionAsync(skuId, subscriptionId, options);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
IAsyncEnumerable<IReadOnlyCollection<ISubscription>> IDiscordClient.GetSKUSubscriptionsAsync(ulong skuId, int limit, ulong? afterId,
|
||||||
|
ulong? beforeId, ulong? userId, RequestOptions options) => GetSKUSubscriptionsAsync(skuId, limit, afterId, beforeId, userId, options);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
async Task<IChannel> IDiscordClient.GetChannelAsync(ulong id, CacheMode mode, RequestOptions options)
|
async Task<IChannel> IDiscordClient.GetChannelAsync(ulong id, CacheMode mode, RequestOptions options)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Discord.Rest;
|
|||||||
public class RestEntitlement : RestEntity<ulong>, IEntitlement
|
public class RestEntitlement : RestEntity<ulong>, IEntitlement
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public DateTimeOffset CreatedAt { get; private set; }
|
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ulong SkuId { get; private set; }
|
public ulong SkuId { get; private set; }
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
|
namespace Discord.Rest;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an application subscription.
|
||||||
|
/// </summary>
|
||||||
|
public class RestSubscription : RestEntity<ulong>, ISubscription
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ulong UserId { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IReadOnlyCollection<ulong> SKUIds { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IReadOnlyCollection<ulong> EntitlementIds { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public DateTimeOffset CurrentPeriodStart { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public DateTimeOffset CurrentPeriodEnd { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public SubscriptionStatus Status { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public DateTimeOffset? CanceledAt { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Country { get; private set; }
|
||||||
|
|
||||||
|
internal RestSubscription(BaseDiscordClient discord, ulong id) : base(discord, id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static RestSubscription Create(BaseDiscordClient discord, API.Subscription model)
|
||||||
|
{
|
||||||
|
var s = new RestSubscription(discord, model.Id);
|
||||||
|
s.Update(model);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Update(API.Subscription model)
|
||||||
|
{
|
||||||
|
UserId = model.UserId;
|
||||||
|
SKUIds = model.SKUIds.ToImmutableArray();
|
||||||
|
EntitlementIds = model.EntitlementIds.ToImmutableArray();
|
||||||
|
CurrentPeriodStart = model.CurrentPeriodStart;
|
||||||
|
CurrentPeriodEnd = model.CurrentPeriodEnd;
|
||||||
|
Status = model.Status;
|
||||||
|
CanceledAt = model.CanceledAt;
|
||||||
|
Country = model.Country;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1032,6 +1032,42 @@ namespace Discord.WebSocket
|
|||||||
internal readonly AsyncEvent<Func<Cacheable<SocketEntitlement, ulong>, Task>> _entitlementDeleted = new();
|
internal readonly AsyncEvent<Func<Cacheable<SocketEntitlement, ulong>, Task>> _entitlementDeleted = new();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fired when a user subscribes to a SKU.
|
||||||
|
/// </summary>
|
||||||
|
public event Func<SocketSubscription, Task> SubscriptionCreated
|
||||||
|
{
|
||||||
|
add { _subscriptionCreated.Add(value); }
|
||||||
|
remove { _subscriptionCreated.Remove(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal readonly AsyncEvent<Func<SocketSubscription, Task>> _subscriptionCreated = new();
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fired when a subscription to a SKU is updated.
|
||||||
|
/// </summary>
|
||||||
|
public event Func<Cacheable<SocketSubscription, ulong>, SocketSubscription, Task> SubscriptionUpdated
|
||||||
|
{
|
||||||
|
add { _subscriptionUpdated.Add(value); }
|
||||||
|
remove { _subscriptionUpdated.Remove(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal readonly AsyncEvent<Func<Cacheable<SocketSubscription, ulong>, SocketSubscription, Task>> _subscriptionUpdated = new();
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fired when a user's subscription is deleted.
|
||||||
|
/// </summary>
|
||||||
|
public event Func<Cacheable<SocketSubscription, ulong>, Task> SubscriptionDeleted
|
||||||
|
{
|
||||||
|
add { _subscriptionDeleted.Add(value); }
|
||||||
|
remove { _subscriptionDeleted.Remove(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal readonly AsyncEvent<Func<Cacheable<SocketSubscription, ulong>, Task>> _subscriptionDeleted = new();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ namespace Discord.WebSocket
|
|||||||
private readonly ConcurrentHashSet<ulong> _groupChannels;
|
private readonly ConcurrentHashSet<ulong> _groupChannels;
|
||||||
private readonly ConcurrentDictionary<ulong, SocketApplicationCommand> _commands;
|
private readonly ConcurrentDictionary<ulong, SocketApplicationCommand> _commands;
|
||||||
private readonly ConcurrentDictionary<ulong, SocketEntitlement> _entitlements;
|
private readonly ConcurrentDictionary<ulong, SocketEntitlement> _entitlements;
|
||||||
|
private readonly ConcurrentDictionary<ulong, SocketSubscription> _subscriptions;
|
||||||
|
|
||||||
internal IReadOnlyCollection<SocketChannel> Channels => _channels.ToReadOnlyCollection();
|
internal IReadOnlyCollection<SocketChannel> Channels => _channels.ToReadOnlyCollection();
|
||||||
internal IReadOnlyCollection<SocketDMChannel> DMChannels => _dmChannels.ToReadOnlyCollection();
|
internal IReadOnlyCollection<SocketDMChannel> DMChannels => _dmChannels.ToReadOnlyCollection();
|
||||||
@@ -26,6 +27,7 @@ namespace Discord.WebSocket
|
|||||||
internal IReadOnlyCollection<SocketGlobalUser> Users => _users.ToReadOnlyCollection();
|
internal IReadOnlyCollection<SocketGlobalUser> Users => _users.ToReadOnlyCollection();
|
||||||
internal IReadOnlyCollection<SocketApplicationCommand> Commands => _commands.ToReadOnlyCollection();
|
internal IReadOnlyCollection<SocketApplicationCommand> Commands => _commands.ToReadOnlyCollection();
|
||||||
internal IReadOnlyCollection<SocketEntitlement> Entitlements => _entitlements.ToReadOnlyCollection();
|
internal IReadOnlyCollection<SocketEntitlement> Entitlements => _entitlements.ToReadOnlyCollection();
|
||||||
|
internal IReadOnlyCollection<SocketSubscription> Subscriptions => _subscriptions.ToReadOnlyCollection();
|
||||||
|
|
||||||
internal IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels =>
|
internal IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels =>
|
||||||
_dmChannels.Select(x => x.Value as ISocketPrivateChannel).Concat(
|
_dmChannels.Select(x => x.Value as ISocketPrivateChannel).Concat(
|
||||||
@@ -43,6 +45,7 @@ namespace Discord.WebSocket
|
|||||||
_groupChannels = new ConcurrentHashSet<ulong>(ConcurrentHashSet.DefaultConcurrencyLevel, (int)(10 * CollectionMultiplier));
|
_groupChannels = new ConcurrentHashSet<ulong>(ConcurrentHashSet.DefaultConcurrencyLevel, (int)(10 * CollectionMultiplier));
|
||||||
_commands = new ConcurrentDictionary<ulong, SocketApplicationCommand>();
|
_commands = new ConcurrentDictionary<ulong, SocketApplicationCommand>();
|
||||||
_entitlements = new();
|
_entitlements = new();
|
||||||
|
_subscriptions = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal SocketChannel GetChannel(ulong id)
|
internal SocketChannel GetChannel(ulong id)
|
||||||
@@ -197,5 +200,29 @@ namespace Discord.WebSocket
|
|||||||
return entitlement;
|
return entitlement;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void AddSubscription(ulong id, SocketSubscription subscription)
|
||||||
|
{
|
||||||
|
_subscriptions.TryAdd(id, subscription);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal SocketSubscription GetSubscription(ulong id)
|
||||||
|
{
|
||||||
|
if (_subscriptions.TryGetValue(id, out var subscription))
|
||||||
|
return subscription;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal SocketSubscription GetOrAddSubscription(ulong id, Func<ulong, SocketSubscription> subscriptionFactory)
|
||||||
|
{
|
||||||
|
return _subscriptions.GetOrAdd(id, subscriptionFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal SocketSubscription RemoveSubscription(ulong id)
|
||||||
|
{
|
||||||
|
if (_subscriptions.TryRemove(id, out var subscription))
|
||||||
|
return subscription;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2531
src/Discord.Net.WebSocket/DiscordSocketClient.EventHandling.cs
Normal file
2531
src/Discord.Net.WebSocket/DiscordSocketClient.EventHandling.cs
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,64 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
|
namespace Discord.WebSocket;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an application subscription.
|
||||||
|
/// </summary>
|
||||||
|
public class SocketSubscription : SocketEntity<ulong>, ISubscription
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ulong UserId { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IReadOnlyCollection<ulong> SKUIds { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IReadOnlyCollection<ulong> EntitlementIds { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public DateTimeOffset CurrentPeriodStart { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public DateTimeOffset CurrentPeriodEnd { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public SubscriptionStatus Status { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public DateTimeOffset? CanceledAt { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Country { get; private set; }
|
||||||
|
|
||||||
|
internal SocketSubscription(DiscordSocketClient discord, ulong id) : base(discord, id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static SocketSubscription Create(DiscordSocketClient discord, API.Subscription model)
|
||||||
|
{
|
||||||
|
var s = new SocketSubscription(discord, model.Id);
|
||||||
|
s.Update(model);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Update(API.Subscription model)
|
||||||
|
{
|
||||||
|
UserId = model.UserId;
|
||||||
|
SKUIds = model.SKUIds.ToImmutableArray();
|
||||||
|
EntitlementIds = model.EntitlementIds.ToImmutableArray();
|
||||||
|
CurrentPeriodStart = model.CurrentPeriodStart;
|
||||||
|
CurrentPeriodEnd = model.CurrentPeriodEnd;
|
||||||
|
Status = model.Status;
|
||||||
|
CanceledAt = model.CanceledAt;
|
||||||
|
Country = model.Country;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal SocketSubscription Clone()
|
||||||
|
=> MemberwiseClone() as SocketSubscription;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user