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);
}
}