diff --git a/DisCatSharp/Entities/Guild/DiscordRole.cs b/DisCatSharp/Entities/Guild/DiscordRole.cs
index d64bc2f23..7a276b0ea 100644
--- a/DisCatSharp/Entities/Guild/DiscordRole.cs
+++ b/DisCatSharp/Entities/Guild/DiscordRole.cs
@@ -1,278 +1,284 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2022 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.Globalization;
using System.Linq;
using System.Threading.Tasks;
using DisCatSharp.Enums;
using DisCatSharp.Net;
using DisCatSharp.Net.Abstractions;
using DisCatSharp.Net.Models;
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.ColorInternal);
[JsonProperty("color", NullValueHandling = NullValueHandling.Ignore)]
internal int ColorInternal;
///
/// 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;
///
/// Gets the role unicode_emoji.
///
[JsonProperty("unicode_emoji", NullValueHandling = NullValueHandling.Ignore)]
internal string UnicodeEmojiString;
///
/// Gets the unicode emoji.
///
public DiscordEmoji UnicodeEmoji
=> this.UnicodeEmojiString != null ? DiscordEmoji.FromName(this.Discord, $":{this.UnicodeEmojiString}:", false) : null;
[JsonIgnore]
internal ulong GuildId = 0;
+ ///
+ /// Gets the role flags.
+ ///
+ [JsonProperty("flags", NullValueHandling = NullValueHandling.Ignore)]
+ public RoleFlags RoleFlags { get; internal set; }
+
///
/// 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.GuildId].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.GuildId, pmds, reason);
}
///
/// Updates this role.
///
/// New role name.
/// New role permissions.
/// New role color.
/// New role hoist.
/// Whether this role is mentionable.
/// Audit log reason.
/// 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.GuildId, this.Id, name, permissions, color?.Value, hoist, mentionable, null, 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 canContinue = true;
if (mdl.Icon.HasValue || mdl.UnicodeEmoji.HasValue)
canContinue = this.Discord.Guilds[this.GuildId].Features.CanSetRoleIcons;
var iconb64 = ImageTool.Base64FromStream(mdl.Icon);
var emoji = mdl.UnicodeEmoji
.MapOrNull(e => e.Id == 0
? e.Name
: throw new ArgumentException("Emoji must be unicode"));
return canContinue ? this.Discord.ApiClient.ModifyGuildRoleAsync(this.GuildId, this.Id, mdl.Name, mdl.Permissions, mdl.Color?.Value, mdl.Hoist, mdl.Mentionable, iconb64, emoji, 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.GuildId, 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);
}
}
diff --git a/DisCatSharp/Enums/Guild/RoleFlags.cs b/DisCatSharp/Enums/Guild/RoleFlags.cs
new file mode 100644
index 000000000..2eb3cc04b
--- /dev/null
+++ b/DisCatSharp/Enums/Guild/RoleFlags.cs
@@ -0,0 +1,44 @@
+// This file is part of the DisCatSharp project, based off DSharpPlus.
+//
+// Copyright (c) 2021-2022 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.Enums
+{
+ ///
+ /// Represents additional details of a role.
+ ///
+ [Flags]
+ public enum RoleFlags
+ {
+ ///
+ /// This role has no flags.
+ ///
+ None = 0,
+
+ ///
+ /// This role is in a prompt.
+ ///
+ InPrompt = 1 << 0,
+ }
+}
+