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() { } } }