diff --git a/DisCatSharp/Entities/Guild/DiscordRole.cs b/DisCatSharp/Entities/Guild/DiscordRole.cs index e1831f5d3..62b479726 100644 --- a/DisCatSharp/Entities/Guild/DiscordRole.cs +++ b/DisCatSharp/Entities/Guild/DiscordRole.cs @@ -1,256 +1,259 @@ // 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.Linq; using System.Threading.Tasks; +using DisCatSharp.Enums.Discord; +using DisCatSharp.Net; using DisCatSharp.Net.Abstractions; using DisCatSharp.Net.Models; +using DisCatSharp.Net.Serialization; using Newtonsoft.Json; namespace DisCatSharp.Entities { /// /// Represents a discord role, to which users can be assigned. /// public class DiscordRole : SnowflakeObject, IEquatable { /// /// Gets the name of this role. /// [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] public string Name { get; internal set; } /// /// Gets the color of this role. /// [JsonIgnore] public DiscordColor Color => new(this._color); [JsonProperty("color", NullValueHandling = NullValueHandling.Ignore)] internal int _color; /// /// Gets whether this role is hoisted. /// [JsonProperty("hoist", NullValueHandling = NullValueHandling.Ignore)] public bool IsHoisted { get; internal set; } /// /// Gets the position of this role in the role hierarchy. /// [JsonProperty("position", NullValueHandling = NullValueHandling.Ignore)] public int Position { get; internal set; } /// /// Gets the permissions set for this role. /// [JsonProperty("permissions", NullValueHandling = NullValueHandling.Ignore)] public Permissions Permissions { get; internal set; } /// /// Gets whether this role is managed by an integration. /// [JsonProperty("managed", NullValueHandling = NullValueHandling.Ignore)] public bool IsManaged { get; internal set; } /// /// Gets whether this role is mentionable. /// [JsonProperty("mentionable", NullValueHandling = NullValueHandling.Ignore)] public bool IsMentionable { get; internal set; } /// /// Gets the tags this role has. /// [JsonProperty("tags", NullValueHandling = NullValueHandling.Ignore)] public DiscordRoleTags Tags { get; internal set; } /// /// Gets the role icon's hash. /// [JsonProperty("icon", NullValueHandling = NullValueHandling.Ignore)] public string IconHash { get; internal set; } /// /// Gets the role icon's url. /// [JsonIgnore] public string IconUrl => !string.IsNullOrWhiteSpace(this.IconHash) ? $"{DiscordDomain.GetDomain(CoreDomain.DiscordCdn).Url}{Endpoints.ROLE_ICONS}/{this.Id.ToString(CultureInfo.InvariantCulture)}/{this.IconHash}.png?size=64" : null; [JsonIgnore] internal ulong _guild_id = 0; /// /// Gets a mention string for this role. If the role is mentionable, this string will mention all the users that belong to this role. /// public string Mention => Formatter.Mention(this); #region Methods /// /// Modifies this role's position. /// /// New position /// Reason why we moved it /// /// Thrown when the client does not have the permission. /// Thrown when the role does not exist. /// Thrown when an invalid parameter was provided. /// Thrown when Discord is unable to process the request. public Task ModifyPositionAsync(int position, string reason = null) { var roles = this.Discord.Guilds[this._guild_id].Roles.Values.OrderByDescending(xr => xr.Position).ToArray(); var pmds = new RestGuildRoleReorderPayload[roles.Length]; for (var i = 0; i < roles.Length; i++) { pmds[i] = new RestGuildRoleReorderPayload { RoleId = roles[i].Id }; pmds[i].Position = roles[i].Id == this.Id ? position : roles[i].Position <= position ? roles[i].Position - 1 : roles[i].Position; } return this.Discord.ApiClient.ModifyGuildRolePositionAsync(this._guild_id, pmds, reason); } /// /// Updates this role. /// /// New role name /// New role permissions /// New role color /// New role hoist /// Whether this role is mentionable /// Reason why we made this change /// /// Thrown when the client does not have the permission. /// Thrown when the role does not exist. /// Thrown when an invalid parameter was provided. /// Thrown when Discord is unable to process the request. public Task ModifyAsync(string name = null, Permissions? permissions = null, DiscordColor? color = null, bool? hoist = null, bool? mentionable = null, string reason = null) => this.Discord.ApiClient.ModifyGuildRoleAsync(this._guild_id, this.Id, name, permissions, color?.Value, hoist, mentionable, null, reason); /// /// Updates this role. /// /// The action. /// Thrown when the client does not have the permission. /// Thrown when the role does not exist. /// Thrown when an invalid parameter was provided. /// Thrown when Discord is unable to process the request. public Task ModifyAsync(Action action) { var mdl = new RoleEditModel(); action(mdl); var iconb64 = Optional.FromNoValue(); var can_continue = true; if (mdl.Icon.HasValue) can_continue = this.Discord.Guilds[this._guild_id].Features.CanSetRoleIcons; if (mdl.Icon.HasValue && mdl.Icon.Value != null) using (var imgtool = new ImageTool(mdl.Icon.Value)) iconb64 = imgtool.GetBase64(); else if (mdl.Icon.HasValue) iconb64 = null; return can_continue ? this.Discord.ApiClient.ModifyGuildRoleAsync(this._guild_id, this.Id, mdl.Name, mdl.Permissions, mdl.Color?.Value, mdl.Hoist, mdl.Mentionable, iconb64, mdl.AuditLogReason) : throw new NotSupportedException($"Cannot modify role icon. Guild needs boost tier two."); } /// /// Deletes this role. /// /// Reason as to why this role has been deleted. /// /// Thrown when the client does not have the permission. /// Thrown when the role does not exist. /// Thrown when an invalid parameter was provided. /// Thrown when Discord is unable to process the request. public Task DeleteAsync(string reason = null) => this.Discord.ApiClient.DeleteRoleAsync(this._guild_id, this.Id, reason); #endregion /// /// Initializes a new instance of the class. /// internal DiscordRole() { } /// /// Checks whether this role has specific permissions. /// /// Permissions to check for. /// Whether the permissions are allowed or not. public PermissionLevel CheckPermission(Permissions permission) => (this.Permissions & permission) != 0 ? PermissionLevel.Allowed : PermissionLevel.Unset; /// /// Returns a string representation of this role. /// /// String representation of this role. public override string ToString() => $"Role {this.Id}; {this.Name}"; /// /// 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 DiscordRole); /// /// Checks whether this is equal to another . /// /// to compare to. /// Whether the is equal to this . public bool Equals(DiscordRole e) => e switch { null => false, _ => 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 role to compare. /// Second role to compare. /// Whether the two roles are equal. public static bool operator ==(DiscordRole e1, DiscordRole e2) => e1 is null == e2 is null && ((e1 is null && e2 is null) || e1.Id == e2.Id); /// /// Gets whether the two objects are not equal. /// /// First role to compare. /// Second role to compare. /// Whether the two roles are not equal. public static bool operator !=(DiscordRole e1, DiscordRole e2) => !(e1 == e2); } }