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.

RestUserMessage.cs 8.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using Discord.API.Rest;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Collections.Immutable;
  5. using System.Diagnostics;
  6. using System.Threading.Tasks;
  7. using Model = Discord.API.Message;
  8. namespace Discord.Rest
  9. {
  10. [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
  11. public class RestUserMessage : RestMessage, IUserMessage
  12. {
  13. private bool _isMentioningEveryone, _isTTS, _isPinned;
  14. private long? _editedTimestampTicks;
  15. private ulong? _webhookId;
  16. private ImmutableArray<Attachment> _attachments;
  17. private ImmutableArray<Embed> _embeds;
  18. private ImmutableArray<ITag> _tags;
  19. private ImmutableArray<RestReaction> _reactions;
  20. public override bool IsTTS => _isTTS;
  21. public override bool IsPinned => _isPinned;
  22. public override ulong? WebhookId => _webhookId;
  23. public override DateTimeOffset? EditedTimestamp => DateTimeUtils.FromTicks(_editedTimestampTicks);
  24. public override IReadOnlyCollection<Attachment> Attachments => _attachments;
  25. public override IReadOnlyCollection<Embed> Embeds => _embeds;
  26. public override IReadOnlyCollection<ulong> MentionedChannelIds => MessageHelper.FilterTagsByKey(TagType.ChannelMention, _tags);
  27. public override IReadOnlyCollection<ulong> MentionedRoleIds => MessageHelper.FilterTagsByKey(TagType.RoleMention, _tags);
  28. public override IReadOnlyCollection<RestUser> MentionedUsers => MessageHelper.FilterTagsByValue<RestUser>(TagType.UserMention, _tags);
  29. public override IReadOnlyCollection<ITag> Tags => _tags;
  30. public IReadOnlyDictionary<Emoji, int> Reactions => _reactions.ToDictionary(x => x.Emoji, x => x.Count);
  31. internal RestUserMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author)
  32. : base(discord, id, channel, author)
  33. {
  34. }
  35. internal new static RestUserMessage Create(BaseDiscordClient discord, IMessageChannel channel, IUser author, Model model)
  36. {
  37. var entity = new RestUserMessage(discord, model.Id, channel, author);
  38. entity.Update(model);
  39. return entity;
  40. }
  41. internal override void Update(Model model)
  42. {
  43. base.Update(model);
  44. if (model.IsTextToSpeech.IsSpecified)
  45. _isTTS = model.IsTextToSpeech.Value;
  46. if (model.Pinned.IsSpecified)
  47. _isPinned = model.Pinned.Value;
  48. if (model.EditedTimestamp.IsSpecified)
  49. _editedTimestampTicks = model.EditedTimestamp.Value?.UtcTicks;
  50. if (model.MentionEveryone.IsSpecified)
  51. _isMentioningEveryone = model.MentionEveryone.Value;
  52. if (model.WebhookId.IsSpecified)
  53. _webhookId = model.WebhookId.Value;
  54. if (model.Attachments.IsSpecified)
  55. {
  56. var value = model.Attachments.Value;
  57. if (value.Length > 0)
  58. {
  59. var attachments = ImmutableArray.CreateBuilder<Attachment>(value.Length);
  60. for (int i = 0; i < value.Length; i++)
  61. attachments.Add(Attachment.Create(value[i]));
  62. _attachments = attachments.ToImmutable();
  63. }
  64. else
  65. _attachments = ImmutableArray.Create<Attachment>();
  66. }
  67. if (model.Embeds.IsSpecified)
  68. {
  69. var value = model.Embeds.Value;
  70. if (value.Length > 0)
  71. {
  72. var embeds = ImmutableArray.CreateBuilder<Embed>(value.Length);
  73. for (int i = 0; i < value.Length; i++)
  74. embeds.Add(Embed.Create(value[i]));
  75. _embeds = embeds.ToImmutable();
  76. }
  77. else
  78. _embeds = ImmutableArray.Create<Embed>();
  79. }
  80. ImmutableArray<IUser> mentions = ImmutableArray.Create<IUser>();
  81. if (model.UserMentions.IsSpecified)
  82. {
  83. var value = model.UserMentions.Value;
  84. if (value.Length > 0)
  85. {
  86. var newMentions = ImmutableArray.CreateBuilder<IUser>(value.Length);
  87. for (int i = 0; i < value.Length; i++)
  88. {
  89. var val = value[i];
  90. if (val.Object != null)
  91. newMentions.Add(RestUser.Create(Discord, val.Object));
  92. }
  93. mentions = newMentions.ToImmutable();
  94. }
  95. }
  96. if (model.Reactions.IsSpecified)
  97. {
  98. var value = model.Reactions.Value;
  99. if (value.Length > 0)
  100. {
  101. var reactions = ImmutableArray.CreateBuilder<RestReaction>(value.Length);
  102. for (int i = 0; i < value.Length; i++)
  103. reactions.Add(new RestReaction(value[i]));
  104. _reactions = reactions.ToImmutable();
  105. }
  106. else
  107. _reactions = ImmutableArray.Create<RestReaction>();
  108. }
  109. if (model.Content.IsSpecified)
  110. {
  111. var text = model.Content.Value;
  112. var guildId = (Channel as IGuildChannel)?.GuildId;
  113. var guild = guildId != null ? (Discord as IDiscordClient).GetGuildAsync(guildId.Value, CacheMode.CacheOnly).Result : null;
  114. _tags = MessageHelper.ParseTags(text, null, guild, mentions);
  115. model.Content = text;
  116. }
  117. }
  118. public async Task ModifyAsync(Action<ModifyMessageParams> func, RequestOptions options)
  119. {
  120. var model = await MessageHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false);
  121. Update(model);
  122. }
  123. public Task AddReactionAsync(Emoji emoji, RequestOptions options = null)
  124. => MessageHelper.AddReactionAsync(this, emoji, Discord, options);
  125. public Task AddReactionAsync(string emoji, RequestOptions options = null)
  126. => MessageHelper.AddReactionAsync(this, emoji, Discord, options);
  127. public Task RemoveReactionAsync(Emoji emoji, IUser user, RequestOptions options = null)
  128. => MessageHelper.RemoveReactionAsync(this, user, emoji, Discord, options);
  129. public Task RemoveReactionAsync(string emoji, IUser user, RequestOptions options = null)
  130. => MessageHelper.RemoveReactionAsync(this, user, emoji, Discord, options);
  131. public Task RemoveAllReactionsAsync(RequestOptions options = null)
  132. => MessageHelper.RemoveAllReactionsAsync(this, Discord, options);
  133. public Task<IReadOnlyCollection<IUser>> GetReactionUsersAsync(string emoji, int limit = 100, ulong? afterUserId = null, RequestOptions options = null)
  134. => MessageHelper.GetReactionUsersAsync(this, emoji, x => { x.Limit = limit; x.AfterUserId = afterUserId.HasValue ? afterUserId.Value : Optional.Create<ulong>(); }, Discord, options);
  135. public Task PinAsync(RequestOptions options)
  136. => MessageHelper.PinAsync(this, Discord, options);
  137. public Task UnpinAsync(RequestOptions options)
  138. => MessageHelper.UnpinAsync(this, Discord, options);
  139. public string Resolve(int startIndex, TagHandling userHandling = TagHandling.Name, TagHandling channelHandling = TagHandling.Name,
  140. TagHandling roleHandling = TagHandling.Name, TagHandling everyoneHandling = TagHandling.Ignore, TagHandling emojiHandling = TagHandling.Name)
  141. => MentionUtils.Resolve(this, startIndex, userHandling, channelHandling, roleHandling, everyoneHandling, emojiHandling);
  142. public string Resolve(TagHandling userHandling = TagHandling.Name, TagHandling channelHandling = TagHandling.Name,
  143. TagHandling roleHandling = TagHandling.Name, TagHandling everyoneHandling = TagHandling.Ignore, TagHandling emojiHandling = TagHandling.Name)
  144. => MentionUtils.Resolve(this, 0, userHandling, channelHandling, roleHandling, everyoneHandling, emojiHandling);
  145. private string DebuggerDisplay => $"{Author}: {Content} ({Id}{(Attachments.Count > 0 ? $", {Attachments.Count} Attachments" : "")})";
  146. }
  147. }