diff --git a/src/Discord.Net.Core/Entities/Users/IGuildUser.cs b/src/Discord.Net.Core/Entities/Users/IGuildUser.cs
index 3808bd435..d944104a2 100644
--- a/src/Discord.Net.Core/Entities/Users/IGuildUser.cs
+++ b/src/Discord.Net.Core/Entities/Users/IGuildUser.cs
@@ -28,5 +28,10 @@ namespace Discord
Task KickAsync(RequestOptions options = null);
/// Modifies this user's properties in this guild.
Task ModifyAsync(Action func, RequestOptions options = null);
+
+ /// The position of the user within the role hirearchy.
+ /// The returned value equal to the position of the highest role the user has,
+ /// or int.MaxValue if user is the server owner.
+ int Hirearchy { get; }
}
}
diff --git a/src/Discord.Net.Core/Extensions/GuildUserExtensions.cs b/src/Discord.Net.Core/Extensions/GuildUserExtensions.cs
index ee53fceb8..181442150 100644
--- a/src/Discord.Net.Core/Extensions/GuildUserExtensions.cs
+++ b/src/Discord.Net.Core/Extensions/GuildUserExtensions.cs
@@ -21,15 +21,20 @@ namespace Discord
return user.RoleIds.Select(r => guild.GetRole(r));
}
- public static int CompareRoles(this IGuildUser left, IGuildUser right) {
- // These should never be empty since the everyone role is always present
- var roleLeft = left.GetRoles().Max();
- var roleRight= right.GetRoles().Max();
- return roleLeft.CompareTo(roleRight);
+ internal static int GetHirearchy(this IGuildUser user) {
+ if(user == null)
+ return -1;
+ if(user.Id == user.Guild.OwnerId)
+ return int.MaxValue;
+ return user.GetRoles().Max(r => r.Position);
}
- public static int Compare(this IGuildUser user, IRole role) {
- return user.GetRoles().Max().CompareTo(role);
+ internal static int CompareRole(this IGuildUser user, IRole role) {
+ if(user == null)
+ return -1;
+ if(role == null)
+ return 1;
+ return -user.Hirearchy.CompareTo(role.Position);
}
}
}
diff --git a/src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs b/src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs
index 154307ace..227699bbd 100644
--- a/src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs
+++ b/src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs
@@ -96,8 +96,8 @@ namespace Discord.Rest
throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object.");
}
}
-
- public int CompareTo(IRole role) => this.Compare(role);
+ public int Hirearchy => this.GetHirearchy();
+ public int CompareTo(IRole role) => this.CompareRole(role);
//IVoiceState
bool IVoiceState.IsSelfDeafened => false;
diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs
index 05ca7aabc..b04a0471b 100644
--- a/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs
+++ b/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs
@@ -96,7 +96,8 @@ namespace Discord.WebSocket
IGuild IGuildUser.Guild => Guild;
ulong IGuildUser.GuildId => Guild.Id;
IReadOnlyCollection IGuildUser.RoleIds => RoleIds;
- public int CompareTo(IRole role) => this.Compare(role);
+ public int CompareTo(IRole role) => this.CompareRole(role);
+ public int Hirearchy => this.GetHirearchy();
//IUser
Task IUser.GetDMChannelAsync(CacheMode mode, RequestOptions options)