You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

SocketGuildUser.cs 7.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. using Discord.Audio;
  2. using Discord.Rest;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Collections.Immutable;
  6. using System.Diagnostics;
  7. using System.Linq;
  8. using System.Threading.Tasks;
  9. using UserModel = Discord.API.User;
  10. using MemberModel = Discord.API.GuildMember;
  11. using PresenceModel = Discord.API.Presence;
  12. namespace Discord.WebSocket
  13. {
  14. [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
  15. public class SocketGuildUser : SocketUser, IGuildUser
  16. {
  17. private long? _joinedAtTicks;
  18. private ImmutableArray<ulong> _roleIds;
  19. internal override SocketGlobalUser GlobalUser { get; }
  20. public SocketGuild Guild { get; }
  21. public string Nickname { get; private set; }
  22. public override bool IsBot { get { return GlobalUser.IsBot; } internal set { GlobalUser.IsBot = value; } }
  23. public override string Username { get { return GlobalUser.Username; } internal set { GlobalUser.Username = value; } }
  24. public override ushort DiscriminatorValue { get { return GlobalUser.DiscriminatorValue; } internal set { GlobalUser.DiscriminatorValue = value; } }
  25. public override string AvatarId { get { return GlobalUser.AvatarId; } internal set { GlobalUser.AvatarId = value; } }
  26. public GuildPermissions GuildPermissions => new GuildPermissions(Permissions.ResolveGuild(Guild, this));
  27. internal override SocketPresence Presence { get; set; }
  28. public override bool IsWebhook => false;
  29. public bool IsSelfDeafened => VoiceState?.IsSelfDeafened ?? false;
  30. public bool IsSelfMuted => VoiceState?.IsSelfMuted ?? false;
  31. public bool IsSuppressed => VoiceState?.IsSuppressed ?? false;
  32. public bool IsDeafened => VoiceState?.IsDeafened ?? false;
  33. public bool IsMuted => VoiceState?.IsMuted ?? false;
  34. public DateTimeOffset? JoinedAt => DateTimeUtils.FromTicks(_joinedAtTicks);
  35. public IReadOnlyCollection<SocketRole> Roles
  36. => _roleIds.Select(id => Guild.GetRole(id)).Where(x => x != null).ToReadOnlyCollection(() => _roleIds.Length);
  37. public SocketVoiceChannel VoiceChannel => VoiceState?.VoiceChannel;
  38. public string VoiceSessionId => VoiceState?.VoiceSessionId ?? "";
  39. public SocketVoiceState? VoiceState => Guild.GetVoiceState(Id);
  40. public AudioInStream AudioStream => Guild.GetAudioStream(Id);
  41. /// <summary> The position of the user within the role hierarchy. </summary>
  42. /// <remarks> The returned value equal to the position of the highest role the user has,
  43. /// or int.MaxValue if user is the server owner. </remarks>
  44. public int Hierarchy
  45. {
  46. get
  47. {
  48. if (Guild.OwnerId == Id)
  49. return int.MaxValue;
  50. int maxPos = 0;
  51. for (int i = 0; i < _roleIds.Length; i++)
  52. {
  53. var role = Guild.GetRole(_roleIds[i]);
  54. if (role != null && role.Position > maxPos)
  55. maxPos = role.Position;
  56. }
  57. return maxPos;
  58. }
  59. }
  60. internal SocketGuildUser(SocketGuild guild, SocketGlobalUser globalUser)
  61. : base(guild.Discord, globalUser.Id)
  62. {
  63. Guild = guild;
  64. GlobalUser = globalUser;
  65. }
  66. internal static SocketGuildUser Create(SocketGuild guild, ClientState state, UserModel model)
  67. {
  68. var entity = new SocketGuildUser(guild, guild.Discord.GetOrCreateUser(state, model));
  69. entity.Update(state, model);
  70. entity.UpdateRoles(new ulong[0]);
  71. return entity;
  72. }
  73. internal static SocketGuildUser Create(SocketGuild guild, ClientState state, MemberModel model)
  74. {
  75. var entity = new SocketGuildUser(guild, guild.Discord.GetOrCreateUser(state, model.User));
  76. entity.Update(state, model);
  77. return entity;
  78. }
  79. internal static SocketGuildUser Create(SocketGuild guild, ClientState state, PresenceModel model)
  80. {
  81. var entity = new SocketGuildUser(guild, guild.Discord.GetOrCreateUser(state, model.User));
  82. entity.Update(state, model, false);
  83. return entity;
  84. }
  85. internal void Update(ClientState state, MemberModel model)
  86. {
  87. base.Update(state, model.User);
  88. if (model.JoinedAt.IsSpecified)
  89. _joinedAtTicks = model.JoinedAt.Value.UtcTicks;
  90. if (model.Nick.IsSpecified)
  91. Nickname = model.Nick.Value;
  92. if (model.Roles.IsSpecified)
  93. UpdateRoles(model.Roles.Value);
  94. }
  95. internal void Update(ClientState state, PresenceModel model, bool updatePresence)
  96. {
  97. if (updatePresence)
  98. {
  99. Presence = SocketPresence.Create(model);
  100. GlobalUser.Update(state, model);
  101. }
  102. if (model.Nick.IsSpecified)
  103. Nickname = model.Nick.Value;
  104. if (model.Roles.IsSpecified)
  105. UpdateRoles(model.Roles.Value);
  106. }
  107. private void UpdateRoles(ulong[] roleIds)
  108. {
  109. var roles = ImmutableArray.CreateBuilder<ulong>(roleIds.Length + 1);
  110. roles.Add(Guild.Id);
  111. for (int i = 0; i < roleIds.Length; i++)
  112. roles.Add(roleIds[i]);
  113. _roleIds = roles.ToImmutable();
  114. }
  115. public Task ModifyAsync(Action<GuildUserProperties> func, RequestOptions options = null)
  116. => UserHelper.ModifyAsync(this, Discord, func, options);
  117. public Task KickAsync(string reason = null, RequestOptions options = null)
  118. => UserHelper.KickAsync(this, Discord, reason, options);
  119. /// <inheritdoc />
  120. public Task AddRoleAsync(IRole role, RequestOptions options = null)
  121. => AddRolesAsync(new[] { role }, options);
  122. /// <inheritdoc />
  123. public Task AddRolesAsync(IEnumerable<IRole> roles, RequestOptions options = null)
  124. => UserHelper.AddRolesAsync(this, Discord, roles, options);
  125. /// <inheritdoc />
  126. public Task RemoveRoleAsync(IRole role, RequestOptions options = null)
  127. => RemoveRolesAsync(new[] { role }, options);
  128. /// <inheritdoc />
  129. public Task RemoveRolesAsync(IEnumerable<IRole> roles, RequestOptions options = null)
  130. => UserHelper.RemoveRolesAsync(this, Discord, roles, options);
  131. public ChannelPermissions GetPermissions(IGuildChannel channel)
  132. => new ChannelPermissions(Permissions.ResolveChannel(Guild, this, channel, GuildPermissions.RawValue));
  133. internal new SocketGuildUser Clone() => MemberwiseClone() as SocketGuildUser;
  134. //IGuildUser
  135. IGuild IGuildUser.Guild => Guild;
  136. ulong IGuildUser.GuildId => Guild.Id;
  137. IReadOnlyCollection<ulong> IGuildUser.RoleIds => _roleIds;
  138. //IVoiceState
  139. IVoiceChannel IVoiceState.VoiceChannel => VoiceChannel;
  140. }
  141. }