diff --git a/DisCatSharp/Clients/BaseDiscordClient.cs b/DisCatSharp/Clients/BaseDiscordClient.cs
index 6c56bd801..98c9fa309 100644
--- a/DisCatSharp/Clients/BaseDiscordClient.cs
+++ b/DisCatSharp/Clients/BaseDiscordClient.cs
@@ -1,301 +1,304 @@
// This file is part of the DisCatSharp project.
//
// Copyright (c) 2021 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma warning disable CS0618
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using DisCatSharp.Entities;
using DisCatSharp.Net;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace DisCatSharp
{
///
/// Represents a common base for various Discord client implementations.
///
public abstract class BaseDiscordClient : IDisposable
{
///
/// Gets the api client.
///
internal protected DiscordApiClient ApiClient { get; }
///
/// Gets the configuration.
///
internal protected DiscordConfiguration Configuration { get; }
///
/// Gets the instance of the logger for this client.
///
public ILogger Logger { get; }
///
/// Gets the string representing the version of bot lib.
///
public string VersionString { get; }
///
/// Gets the bot library name.
///
public string BotLibrary { get; }
///
/// Gets the library team.
///
public DisCatSharpTeam LibraryDeveloperTeam
=> this.ApiClient.GetDisCatSharpTeamAsync().Result;
///
/// Gets the current user.
///
public DiscordUser CurrentUser { get; internal set; }
///
/// Gets the current application.
///
public DiscordApplication CurrentApplication { get; internal set; }
///
/// Gets the cached guilds for this client.
///
public abstract IReadOnlyDictionary Guilds { get; }
///
/// Gets the cached users for this client.
///
protected internal ConcurrentDictionary UserCache { get; }
///
/// Gets the service provider.
/// This allows passing data around without resorting to static members.
/// Defaults to null.
///
internal IServiceProvider ServiceProvider { get; set; } = new ServiceCollection().BuildServiceProvider(true);
///
/// Gets the list of available voice regions. Note that this property will not contain VIP voice regions.
///
public IReadOnlyDictionary VoiceRegions
=> this._voice_regions_lazy.Value;
///
/// Gets the list of available voice regions. This property is meant as a way to modify .
///
protected internal ConcurrentDictionary InternalVoiceRegions { get; set; }
internal Lazy> _voice_regions_lazy;
///
/// Initializes this Discord API client.
///
/// Configuration for this client.
protected BaseDiscordClient(DiscordConfiguration config)
{
this.Configuration = new DiscordConfiguration(config);
if (this.Configuration.LoggerFactory == null)
{
this.Configuration.LoggerFactory = new DefaultLoggerFactory();
this.Configuration.LoggerFactory.AddProvider(new DefaultLoggerProvider(this));
}
this.Logger = this.Configuration.LoggerFactory.CreateLogger();
this.ApiClient = new DiscordApiClient(this);
this.UserCache = new ConcurrentDictionary();
this.InternalVoiceRegions = new ConcurrentDictionary();
this._voice_regions_lazy = new Lazy>(() => new ReadOnlyDictionary(this.InternalVoiceRegions));
var a = typeof(DiscordClient).GetTypeInfo().Assembly;
var iv = a.GetCustomAttribute();
if (iv != null)
{
this.VersionString = iv.InformationalVersion;
}
else
{
var v = a.GetName().Version;
var vs = v.ToString(3);
if (v.Revision > 0)
this.VersionString = $"{vs}, CI build {v.Revision}";
}
this.BotLibrary = "DisCatSharp";
this.ServiceProvider = config.ServiceProvider;
}
///
/// Gets the current API application.
///
/// Current API application.
public async Task GetCurrentApplicationAsync()
{
var tapp = await this.ApiClient.GetCurrentApplicationInfoAsync().ConfigureAwait(false);
var app = new DiscordApplication
{
Discord = this,
Id = tapp.Id,
Name = tapp.Name,
Description = tapp.Description,
Summary = tapp.Summary,
IconHash = tapp.IconHash,
RpcOrigins = tapp.RpcOrigins != null ? new ReadOnlyCollection(tapp.RpcOrigins) : null,
Flags = tapp.Flags,
RequiresCodeGrant = tapp.BotRequiresCodeGrant,
IsPublic = tapp.IsPublicBot,
PrivacyPolicyUrl = tapp.PrivacyPolicyUrl,
- TermsOfServiceUrl = tapp.TermsOfServiceUrl
+ TermsOfServiceUrl = tapp.TermsOfServiceUrl,
+ CustomInstallUrl = tapp.CustomInstallUrl,
+ InstallParams = tapp.InstallParams,
+ Tags = (tapp.Tags ?? Enumerable.Empty()).ToArray()
};
// do team and owners
// tbh fuck doing this properly
if (tapp.Team == null)
{
// singular owner
app.Owners = new ReadOnlyCollection(new[] { new DiscordUser(tapp.Owner) });
app.Team = null;
app.TeamName = null;
}
else
{
// team owner
app.Team = new DiscordTeam(tapp.Team);
var members = tapp.Team.Members
.Select(x => new DiscordTeamMember(x) { Team = app.Team, User = new DiscordUser(x.User) })
.ToArray();
var owners = members
.Where(x => x.MembershipStatus == DiscordTeamMembershipStatus.Accepted)
.Select(x => x.User)
.ToArray();
app.Owners = new ReadOnlyCollection(owners);
app.Team.Owner = owners.FirstOrDefault(x => x.Id == tapp.Team.OwnerId);
app.Team.Members = new ReadOnlyCollection(members);
app.TeamName = app.Team.Name;
}
app.GuildId = tapp.GuildId.HasValue ? tapp.GuildId.Value : null;
app.Slug = tapp.Slug.HasValue ? tapp.Slug.Value : null;
app.PrimarySkuId = tapp.PrimarySkuId.HasValue ? tapp.PrimarySkuId.Value : null;
app.VerifyKey = tapp.VerifyKey.HasValue ? tapp.VerifyKey.Value : null;
app.CoverImageHash = tapp.CoverImageHash.HasValue ? tapp.CoverImageHash.Value : null;
return app;
}
///
/// Gets a list of regions
///
///
/// Thrown when Discord is unable to process the request.
public Task> ListVoiceRegionsAsync()
=> this.ApiClient.ListVoiceRegionsAsync();
///
/// Initializes this client. This method fetches information about current user, application, and voice regions.
///
///
public virtual async Task InitializeAsync()
{
if (this.CurrentUser == null)
{
this.CurrentUser = await this.ApiClient.GetCurrentUserAsync().ConfigureAwait(false);
this.UserCache.AddOrUpdate(this.CurrentUser.Id, this.CurrentUser, (id, xu) => this.CurrentUser);
}
if (this.Configuration.TokenType == TokenType.Bot && this.CurrentApplication == null)
this.CurrentApplication = await this.GetCurrentApplicationAsync().ConfigureAwait(false);
if (this.Configuration.TokenType != TokenType.Bearer && this.InternalVoiceRegions.Count == 0)
{
var vrs = await this.ListVoiceRegionsAsync().ConfigureAwait(false);
foreach (var xvr in vrs)
this.InternalVoiceRegions.TryAdd(xvr.Id, xvr);
}
}
///
/// Gets the current gateway info for the provided token.
/// If no value is provided, the configuration value will be used instead.
///
/// A gateway info object.
public async Task GetGatewayInfoAsync(string token = null)
{
if (this.Configuration.TokenType != TokenType.Bot)
throw new InvalidOperationException("Only bot tokens can access this info.");
if (string.IsNullOrEmpty(this.Configuration.Token))
{
if (string.IsNullOrEmpty(token))
throw new InvalidOperationException("Could not locate a valid token.");
this.Configuration.Token = token;
var res = await this.ApiClient.GetGatewayInfoAsync().ConfigureAwait(false);
this.Configuration.Token = null;
return res;
}
return await this.ApiClient.GetGatewayInfoAsync().ConfigureAwait(false);
}
///
/// Gets a cached user.
///
/// The user_id.
internal DiscordUser GetCachedOrEmptyUserInternal(ulong user_id)
{
this.TryGetCachedUserInternal(user_id, out var user);
return user;
}
///
/// Tries the get a cached user.
///
/// The user_id.
/// The user.
internal bool TryGetCachedUserInternal(ulong user_id, out DiscordUser user)
{
if (this.UserCache.TryGetValue(user_id, out user))
return true;
user = new DiscordUser { Id = user_id, Discord = this };
return false;
}
///
/// Disposes this client.
///
public abstract void Dispose();
}
}
diff --git a/DisCatSharp/Entities/Application/DiscordApplication.cs b/DisCatSharp/Entities/Application/DiscordApplication.cs
index 9bd979ca3..0d3c485a7 100644
--- a/DisCatSharp/Entities/Application/DiscordApplication.cs
+++ b/DisCatSharp/Entities/Application/DiscordApplication.cs
@@ -1,399 +1,415 @@
// This file is part of the DisCatSharp project.
//
// Copyright (c) 2021 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks;
using DisCatSharp.Enums;
using DisCatSharp.Net;
using Newtonsoft.Json;
namespace DisCatSharp.Entities
{
///
/// Represents an OAuth2 application.
///
public sealed class DiscordApplication : DiscordMessageApplication, IEquatable
{
///
/// Gets the application's summary.
///
public string Summary { get; internal set; }
///
/// Gets the application's icon.
///
public override string Icon
=> !string.IsNullOrWhiteSpace(this.IconHash) ? $"{DiscordDomain.GetDomain(CoreDomain.DiscordCdn).Url}{Endpoints.APP_ICONS}/{this.Id.ToString(CultureInfo.InvariantCulture)}/{this.IconHash}.png?size=1024" : null;
///
/// Gets the application's icon hash.
///
public string IconHash { get; internal set; }
///
/// Gets the application's allowed RPC origins.
///
public IReadOnlyList RpcOrigins { get; internal set; }
///
/// Gets the application's flags.
///
public ApplicationFlags Flags { get; internal set; }
///
/// Gets the application's owners.
///
public IEnumerable Owners { get; internal set; }
///
/// Gets whether this application's bot user requires code grant.
///
public bool? RequiresCodeGrant { get; internal set; }
///
/// Gets whether this bot application is public.
///
public bool? IsPublic { get; internal set; }
///
/// Gets the terms of service url of the application.
///
public string TermsOfServiceUrl { get; internal set; }
///
/// Gets the privacy policy url of the application.
///
public string PrivacyPolicyUrl { get; internal set; }
///
/// Gets the team name of the application.
///
public string TeamName { get; internal set; }
///
/// Gets the hash of the application's cover image.
///
public string CoverImageHash { get; internal set; }
///
/// Gets this application's cover image URL.
///
public override string CoverImageUrl
=> $"{DiscordDomain.GetDomain(CoreDomain.DiscordCdn).Url}{Endpoints.APP_ICONS}/{this.Id.ToString(CultureInfo.InvariantCulture)}/{this.CoverImageHash}.png?size=1024";
///
/// Gets the team which owns this application.
///
public DiscordTeam Team { get; internal set; }
///
/// Gets the hex encoded key for verification in interactions and the GameSDK's GetTicket
///
public string VerifyKey { get; internal set; }
///
/// If this application is a game sold on Discord, this field will be the guild to which it has been linked
///
public ulong? GuildId { get; internal set; }
///
/// If this application is a game sold on Discord, this field will be the id of the "Game SKU" that is created, if exists
///
public ulong? PrimarySkuId { get; internal set; }
///
/// If this application is a game sold on Discord, this field will be the URL slug that links to the store page
///
public string Slug { get; internal set; }
///
/// Gets or sets a list of .
///
private IReadOnlyList Assets { get; set; }
+ ///
+ /// A custom url for the Add To Server button.
+ ///
+ public string CustomInstallUrl { get; internal set; }
+
+ ///
+ /// Install parameters for adding the application to a guild.
+ ///
+ public DiscordApplicationInstallParams InstallParams { get; internal set; }
+
+ ///
+ /// The application tags.
+ /// Not used atm.
+ ///
+ public IReadOnlyList Tags { get; internal set; }
+
///
/// Initializes a new instance of the class.
///
internal DiscordApplication() { }
///
/// Gets the application's cover image URL, in requested format and size.
///
/// Format of the image to get.
/// Maximum size of the cover image. Must be a power of two, minimum 16, maximum 2048.
/// URL of the application's cover image.
public string GetAvatarUrl(ImageFormat fmt, ushort size = 1024)
{
if (fmt == ImageFormat.Unknown)
throw new ArgumentException("You must specify valid image format.", nameof(fmt));
if (size < 16 || size > 2048)
throw new ArgumentOutOfRangeException(nameof(size));
var log = Math.Log(size, 2);
if (log < 4 || log > 11 || log % 1 != 0)
throw new ArgumentOutOfRangeException(nameof(size));
var sfmt = "";
sfmt = fmt switch
{
ImageFormat.Gif => "gif",
ImageFormat.Jpeg => "jpg",
ImageFormat.Auto or ImageFormat.Png => "png",
ImageFormat.WebP => "webp",
_ => throw new ArgumentOutOfRangeException(nameof(fmt)),
};
var ssize = size.ToString(CultureInfo.InvariantCulture);
return !string.IsNullOrWhiteSpace(this.CoverImageHash)
? $"{DiscordDomain.GetDomain(CoreDomain.DiscordCdn).Url}{Endpoints.AVATARS}/{this.Id.ToString(CultureInfo.InvariantCulture)}/{this.IconHash}.{sfmt}?size={ssize}"
: null;
}
///
/// Retrieves this application's assets.
///
/// This application's assets.
public async Task> GetAssetsAsync()
{
if (this.Assets == null)
this.Assets = await this.Discord.ApiClient.GetApplicationAssetsAsync(this).ConfigureAwait(false);
return this.Assets;
}
///
/// Generates an oauth url for the application.
///
/// The permissions.
/// OAuth Url
public string GenerateBotOAuth(Permissions permissions = Permissions.None)
{
permissions &= PermissionMethods.FULL_PERMS;
// hey look, it's not all annoying and blue :P
return new QueryUriBuilder($"{DiscordDomain.GetDomain(CoreDomain.Discord).Url}{Endpoints.OAUTH2}{Endpoints.AUTHORIZE}")
.AddParameter("client_id", this.Id.ToString(CultureInfo.InvariantCulture))
.AddParameter("scope", "bot")
.AddParameter("permissions", ((long)permissions).ToString(CultureInfo.InvariantCulture))
.ToString();
}
///
/// Checks whether this is equal to another object.
///
/// Object to compare to.
/// Whether the object is equal to this .
public override bool Equals(object obj) => this.Equals(obj as DiscordApplication);
///
/// Checks whether this is equal to another .
///
/// to compare to.
/// Whether the is equal to this .
public bool Equals(DiscordApplication e) => e is not null && (ReferenceEquals(this, e) || this.Id == e.Id);
///
/// Gets the hash code for this .
///
/// The hash code for this .
public override int GetHashCode() => this.Id.GetHashCode();
///
/// Gets whether the two objects are equal.
///
/// First application to compare.
/// Second application to compare.
/// Whether the two applications are equal.
public static bool operator ==(DiscordApplication e1, DiscordApplication e2)
{
var o1 = e1 as object;
var o2 = e2 as object;
return (o1 != null || o2 == null) && (o1 == null || o2 != null) && ((o1 == null && o2 == null) || e1.Id == e2.Id);
}
///
/// Gets whether the two objects are not equal.
///
/// First application to compare.
/// Second application to compare.
/// Whether the two applications are not equal.
public static bool operator !=(DiscordApplication e1, DiscordApplication e2)
=> !(e1 == e2);
}
///
/// Represents an discord asset.
///
public abstract class DiscordAsset
{
///
/// Gets the ID of this asset.
///
public virtual string Id { get; set; }
///
/// Gets the URL of this asset.
///
public abstract Uri Url { get; }
}
///
/// Represents an asset for an OAuth2 application.
///
public sealed class DiscordApplicationAsset : DiscordAsset, IEquatable
{
///
/// Gets the Discord client instance for this asset.
///
internal BaseDiscordClient Discord { get; set; }
///
/// Gets the asset's name.
///
[JsonProperty("name")]
public string Name { get; internal set; }
///
/// Gets the asset's type.
///
[JsonProperty("type")]
public ApplicationAssetType Type { get; internal set; }
///
/// Gets the application this asset belongs to.
///
public DiscordApplication Application { get; internal set; }
///
/// Gets the Url of this asset.
///
public override Uri Url
=> new($"{DiscordDomain.GetDomain(CoreDomain.DiscordCdn).Url}{Endpoints.APP_ASSETS}/{this.Application.Id.ToString(CultureInfo.InvariantCulture)}/{this.Id}.png");
///
/// Initializes a new instance of the class.
///
internal DiscordApplicationAsset() { }
///
/// Initializes a new instance of the class.
///
/// The app.
internal DiscordApplicationAsset(DiscordApplication app)
{
this.Discord = app.Discord;
}
///
/// Checks whether this is equal to another object.
///
/// Object to compare to.
/// Whether the object is equal to this .
public override bool Equals(object obj) => this.Equals(obj as DiscordApplicationAsset);
///
/// Checks whether this is equal to another .
///
/// to compare to.
/// Whether the is equal to this .
public bool Equals(DiscordApplicationAsset e) => e is not null && (ReferenceEquals(this, e) || this.Id == e.Id);
///
/// Gets the hash code for this .
///
/// The hash code for this .
public override int GetHashCode() => this.Id.GetHashCode();
///
/// Gets whether the two objects are equal.
///
/// First application asset to compare.
/// Second application asset to compare.
/// Whether the two application assets not equal.
public static bool operator ==(DiscordApplicationAsset e1, DiscordApplicationAsset e2)
{
var o1 = e1 as object;
var o2 = e2 as object;
return (o1 != null || o2 == null) && (o1 == null || o2 != null) && ((o1 == null && o2 == null) || e1.Id == e2.Id);
}
///
/// Gets whether the two objects are not equal.
///
/// First application asset to compare.
/// Second application asset to compare.
/// Whether the two application assets are not equal.
public static bool operator !=(DiscordApplicationAsset e1, DiscordApplicationAsset e2)
=> !(e1 == e2);
}
///
/// Represents an spotify asset.
///
public sealed class DiscordSpotifyAsset : DiscordAsset
{
///
/// Gets the URL of this asset.
///
public override Uri Url
=> this._url.Value;
private readonly Lazy _url;
///
/// Initializes a new instance of the class.
///
public DiscordSpotifyAsset()
{
this._url = new Lazy(() =>
{
var ids = this.Id.Split(':');
var id = ids[1];
return new Uri($"https://i.scdn.co/image/{id}");
});
}
}
///
/// Determines the type of the asset attached to the application.
///
public enum ApplicationAssetType : int
{
///
/// Unknown type. This indicates something went terribly wrong.
///
Unknown = 0,
///
/// This asset can be used as small image for rich presences.
///
SmallImage = 1,
///
/// This asset can be used as large image for rich presences.
///
LargeImage = 2
}
}
diff --git a/DisCatSharp/Entities/Application/DiscordApplicationInstallParams.cs b/DisCatSharp/Entities/Application/DiscordApplicationInstallParams.cs
new file mode 100644
index 000000000..c3e04c1b0
--- /dev/null
+++ b/DisCatSharp/Entities/Application/DiscordApplicationInstallParams.cs
@@ -0,0 +1,50 @@
+// This file is part of the DisCatSharp project, a fork of DSharpPlus.
+//
+// Copyright (c) 2021 AITSYS
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace DisCatSharp.Entities
+{
+ ///
+ /// The application install params.
+ ///
+ public sealed class DiscordApplicationInstallParams
+ {
+ ///
+ /// Gets the scopes.
+ ///
+ [JsonProperty("scopes", NullValueHandling = NullValueHandling.Ignore)]
+ public IReadOnlyList Scopes { get; internal set; }
+
+ ///
+ /// Gets or sets the permissions.
+ ///
+ [JsonProperty("permissions", NullValueHandling = NullValueHandling.Ignore)]
+ public Permissions? Permissions { get; internal set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ internal DiscordApplicationInstallParams() { }
+ }
+}
diff --git a/DisCatSharp/Enums/User/UserFlags.cs b/DisCatSharp/Enums/User/UserFlags.cs
index 2a2e8b9c3..f8e0b3bd9 100644
--- a/DisCatSharp/Enums/User/UserFlags.cs
+++ b/DisCatSharp/Enums/User/UserFlags.cs
@@ -1,143 +1,143 @@
// This file is part of the DisCatSharp project.
//
// Copyright (c) 2021 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System;
namespace DisCatSharp
{
///
/// Represents additional details of a users account.
///
[Flags]
public enum UserFlags
{
///
/// The user has no flags.
///
None = 0,
///
/// The user is a Discord employee.
///
DiscordEmployee = 1 << 0,
///
/// The user is a Discord partner.
///
DiscordPartner = 1 << 1,
///
/// The user has the HypeSquad badge.
///
HypeSquadEvents = 1 << 2,
///
/// The user reached the first bug hunter tier.
///
BugHunterLevelOne = 1 << 3,
///
/// The user has SMS recovery for 2FA enabled.
///
MfaSms = 1 << 4,
///
/// The user is marked as dismissed Nitro promotion
///
PremiumPromoDismissed = 1 << 5,
///
/// The user is a member of house bravery.
///
HouseBravery = 1 << 6,
///
/// The user is a member of house brilliance.
///
HouseBrilliance = 1 << 7,
///
/// The user is a member of house balance.
///
HouseBalance = 1 << 8,
///
/// The user has the early supporter badge.
///
EarlySupporter = 1 << 9,
///
- /// Whether the user is apart of a Discord developer team.
+ /// User is a .
///
- TeamUser = 1 << 10,
+ TeamPseudoUser = 1 << 10,
///
/// Relates to partner/verification applications.
///
PartnerOrVerificationApplication = 1 << 11,
///
/// Whether the user is an official system user.
///
System = 1 << 12,
///
/// Whether the user has unread system messages.
///
HasUnreadUrgentMessages = 1 << 13,
///
/// The user reached the second bug hunter tier.
///
BugHunterLevelTwo = 1 << 14,
///
/// The user has a pending deletion for being underage in DOB prompt.
///
UnderageDeleted = 1 << 15,
///
/// The user is a verified bot.
///
VerifiedBot = 1 << 16,
///
/// The user is a verified bot developer.
///
VerifiedBotDeveloper = 1 << 17,
///
/// The user is a discord certified moderator.
///
DiscordCertifiedModerator = 1 << 18,
///
/// The user is a bot and has set an interactions endpoint url.
///
BotHttpInteractions = 1 << 19,
///
/// The user is disabled for being a spammer.
///
Spammer = 1 << 20
}
}
diff --git a/DisCatSharp/Net/Abstractions/Transport/TransportApplication.cs b/DisCatSharp/Net/Abstractions/Transport/TransportApplication.cs
index 5fa71d4d4..337b7ce5a 100644
--- a/DisCatSharp/Net/Abstractions/Transport/TransportApplication.cs
+++ b/DisCatSharp/Net/Abstractions/Transport/TransportApplication.cs
@@ -1,148 +1,166 @@
// This file is part of the DisCatSharp project.
//
// Copyright (c) 2021 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System.Collections.Generic;
using DisCatSharp.Entities;
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions
{
///
/// The transport application.
///
internal sealed class TransportApplication
{
///
/// Gets or sets the id.
///
[JsonProperty("id", NullValueHandling = NullValueHandling.Include)]
public ulong Id { get; set; }
///
/// Gets or sets the name.
///
[JsonProperty("name", NullValueHandling = NullValueHandling.Include)]
public string Name { get; set; }
///
/// Gets or sets the icon hash.
///
[JsonProperty("icon", NullValueHandling = NullValueHandling.Include)]
public string IconHash { get; set; }
///
/// Gets or sets the description.
///
[JsonProperty("description", NullValueHandling = NullValueHandling.Include)]
public string Description { get; set; }
///
/// Gets or sets the summary.
///
[JsonProperty("summary", NullValueHandling = NullValueHandling.Include)]
public string Summary { get; set; }
///
/// Wwhether the bot is public.
///
[JsonProperty("bot_public", NullValueHandling = NullValueHandling.Include)]
public bool IsPublicBot { get; set; }
///
/// Gets or sets the flags.
///
[JsonProperty("flags", NullValueHandling = NullValueHandling.Include)]
public ApplicationFlags Flags { get; set; }
///
/// Gets or sets the terms of service url.
///
[JsonProperty("terms_of_service_url", NullValueHandling = NullValueHandling.Include)]
public string TermsOfServiceUrl { get; set; }
///
/// Gets or sets the privacy policy url.
///
[JsonProperty("privacy_policy_url", NullValueHandling = NullValueHandling.Include)]
public string PrivacyPolicyUrl { get; set; }
///
/// Gets or sets a value indicating whether the bot requires code grant.
///
[JsonProperty("bot_require_code_grant", NullValueHandling = NullValueHandling.Include)]
public bool BotRequiresCodeGrant { get; set; }
// Json.NET can figure the type out
///
/// Gets or sets the rpc origins.
///
[JsonProperty("rpc_origins", NullValueHandling = NullValueHandling.Ignore)]
public IList RpcOrigins { get; set; }
///
/// Gets or sets the owner.
///
[JsonProperty("owner", NullValueHandling = NullValueHandling.Include)]
public TransportUser Owner { get; set; }
///
/// Gets or sets the team.
///
[JsonProperty("team", NullValueHandling = NullValueHandling.Include)]
public TransportTeam Team { get; set; }
///
/// Gets or sets the verify key.
///
[JsonProperty("verify_key", NullValueHandling = NullValueHandling.Include)]
public Optional VerifyKey { get; set; }
///
/// Gets or sets the guild id.
///
[JsonProperty("guild_id")]
public Optional GuildId { get; set; }
///
/// Gets or sets the primary sku id.
///
[JsonProperty("primary_sku_id")]
public Optional PrimarySkuId { get; set; }
///
/// Gets or sets the slug.
///
[JsonProperty("slug")]
public Optional Slug { get; set; }
///
/// Gets or sets the cover image hash.
///
[JsonProperty("cover_image")]
public Optional CoverImageHash { get; set; }
+ ///
+ /// Gets or sets the custom install url.
+ ///
+ [JsonProperty("custom_install_url")]
+ public string CustomInstallUrl { get; set; }
+
+ ///
+ /// Gets or sets the install params.
+ ///
+ [JsonProperty("install_params", NullValueHandling = NullValueHandling.Include)]
+ public DiscordApplicationInstallParams InstallParams { get; set; }
+
+ ///
+ /// Gets or sets the tags.
+ ///
+ [JsonProperty("tags", NullValueHandling = NullValueHandling.Include)]
+ public IEnumerable Tags { get; set; }
+
///
/// Initializes a new instance of the class.
///
internal TransportApplication() { }
}
}