Browse Source

reworkkkk

pull/2578/head
Misha133 2 years ago
parent
commit
0a84cac10a
8 changed files with 181 additions and 651 deletions
  1. +0
    -102
      src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRule.cs
  2. +0
    -508
      src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleBuilder.cs
  3. +55
    -0
      src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleProperties.cs
  4. +1
    -1
      src/Discord.Net.Core/Entities/Guilds/IGuild.cs
  5. +119
    -4
      src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
  6. +3
    -3
      src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
  7. +0
    -30
      src/Discord.Net.Rest/Extensions/EntityExtensions.cs
  8. +3
    -3
      src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs

+ 0
- 102
src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRule.cs View File

@@ -1,102 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Discord
{
/// <summary>
/// Provides properties used to create a <see cref="IAutoModRule"/>.
/// </summary>
public class AutoModRule
{
/// <summary>
/// Gets the name for the rule.
/// </summary>
public string Name { get; }

/// <summary>
/// Gets the event type for the rule.
/// </summary>
public AutoModEventType EventType { get; }

/// <summary>
/// Gets the trigger type for the rule.
/// </summary>
public AutoModTriggerType TriggerType { get; }

/// <summary>
/// Gets the keyword filter for the rule.
/// </summary>
public string[] KeywordFilter { get; }

/// <summary>
/// Gets regex patterns for the rule. Empty if the rule has no regexes.
/// </summary>
public string[] RegexPatterns { get; }

/// <summary>
/// Gets the allow list for the rule. Empty if the rule has no allowed terms.
/// </summary>
public string[] AllowList { get; }

/// <summary>
/// Gets total mention limit for the rule. <see langword="null"/> if not provided.
/// </summary>
public int? MentionLimit { get; }

/// <summary>
/// Gets the presets for the rule. Empty if the rule has no presets.
/// </summary>
public KeywordPresetTypes[] Presets { get; }

/// <summary>
/// Gets the actions for the rule.
/// </summary>
public AutoModRuleAction[] Actions { get; }

/// <summary>
/// Gets whether or not the rule is enabled.
/// </summary>
public bool Enabled { get; }

/// <summary>
/// Gets the exempt roles for the rule. Empty if the rule has no exempt roles.
/// </summary>
public ulong[] ExemptRoles { get; }

/// <summary>
/// Gets the exempt channels for the rule. Empty if the rule has no exempt channels.
/// </summary>
public ulong[] ExemptChannels { get; }
internal AutoModRule(string name,
AutoModEventType eventType,
AutoModTriggerType triggerType,
string[] keywordFilter,
string[] regexPatterns,
string[] allowList,
int? mentionLimit,
KeywordPresetTypes[] presets,
AutoModRuleAction[] actions,
bool enabled,
ulong[] exemptRoles,
ulong[] exemptChannels)
{
Name = name;
EventType = eventType;
TriggerType = triggerType;
KeywordFilter = keywordFilter;
RegexPatterns = regexPatterns;
AllowList = allowList;
MentionLimit = mentionLimit;
Presets = presets;
Actions = actions;
Enabled = enabled;
ExemptRoles = exemptRoles;
ExemptChannels = exemptChannels;
}
}

}

+ 0
- 508
src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleBuilder.cs View File

@@ -1,508 +0,0 @@
using Newtonsoft.Json.Linq;

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;

namespace Discord;

/// <summary>
/// A builder used to create a <see cref="IAutoModRule"/>.
/// </summary>
public class AutoModRuleBuilder
{
/// <summary>
/// Returns the max keyword count for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxKeywordCount = 1000;

/// <summary>
/// Returns the max keyword length for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxKeywordLength = 60;

/// <summary>
/// Returns the max regex pattern count for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxRegexPatternCount = 10;

/// <summary>
/// Returns the max regex pattern length for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxRegexPatternLength = 260;

/// <summary>
/// Returns the max allowlist keyword count for a <see cref="AutoModTriggerType.Keyword"/> AutoMod rule allowed by Discord.
/// </summary>
public const int MaxAllowListCountKeyword = 100;

/// <summary>
/// Returns the max allowlist keyword count for a <see cref="AutoModTriggerType.KeywordPreset"/> AutoMod rule allowed by Discord.
/// </summary>
public const int MaxAllowListCountKeywordPreset = 1000;

/// <summary>
/// Returns the max allowlist keyword length for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxAllowListEntryLength = 60;

/// <summary>
/// Returns the max mention limit for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxMentionLimit = 50;

/// <summary>
/// Returns the max exempt role count for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxExemptRoles = 20;

/// <summary>
/// Returns the max exempt channel count for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxExemptChannels = 50;

private List<string> _keywordFilter = new();
private List<string> _regexPatterns = new();
private List<string> _allowList = new();

private List<ulong> _exemptRoles = new();
private List<ulong> _exemptChannels = new();
private HashSet<KeywordPresetTypes> _presets = new();

private int? _mentionLimit;

/// <summary>
/// Gets or sets the list of <see cref="string"/> of an <see cref="AutoModRule"/>.
/// </summary>
public List<string> KeywordFilter
{
get { return _keywordFilter; }
set
{
if (TriggerType != AutoModTriggerType.Keyword)
throw new ArgumentException(message: $"Keyword filter can only be used with 'Keyword' trigger type.", paramName: nameof(KeywordFilter));

if (value.Count > MaxKeywordCount)
throw new ArgumentException(message: $"Keyword count must be less than or equal to {MaxKeywordCount}.", paramName: nameof(KeywordFilter));

if (value.Any(x => x.Length > MaxKeywordLength))
throw new ArgumentException(message: $"Keyword length must be less than or equal to {MaxKeywordLength}.", paramName: nameof(KeywordFilter));

_keywordFilter = value;
}
}

/// <summary>
/// Gets or sets the list of <see cref="string"/> of an <see cref="AutoModRule"/>.
/// </summary>
public List<string> RegexPatterns
{
get { return _regexPatterns; }
set
{
if (TriggerType != AutoModTriggerType.Keyword)
throw new ArgumentException(message: $"Regex patterns can only be used with 'Keyword' trigger type.", paramName: nameof(RegexPatterns));

if (value.Count > MaxRegexPatternCount)
throw new ArgumentException(message: $"Regex pattern count must be less than or equal to {MaxRegexPatternCount}.", paramName: nameof(RegexPatterns));

if (value.Any(x => x.Length > MaxRegexPatternLength))
throw new ArgumentException(message: $"Regex pattern must be less than or equal to {MaxRegexPatternLength}.", paramName: nameof(RegexPatterns));

_regexPatterns = value;
}
}

/// <summary>
/// Gets or sets the list of <see cref="string"/> of an <see cref="AutoModRule"/>.
/// </summary>
public List<string> AllowList
{
get { return _allowList; }
set
{
if (TriggerType is not AutoModTriggerType.Keyword or AutoModTriggerType.KeywordPreset)
throw new ArgumentException(message: $"Allow list can only be used with 'Keyword' or 'KeywordPreset' trigger type.", paramName: nameof(AllowList));

if (TriggerType == AutoModTriggerType.Keyword && value.Count > MaxAllowListCountKeyword)
throw new ArgumentException(message: $"Allow list entry count must be less than or equal to {MaxAllowListCountKeyword}.", paramName: nameof(AllowList));

if (TriggerType == AutoModTriggerType.KeywordPreset && value.Count > MaxAllowListCountKeywordPreset)
throw new ArgumentException(message: $"Allow list entry count must be less than or equal to {MaxAllowListCountKeywordPreset}.", paramName: nameof(AllowList));

if (value.Any(x => x.Length > MaxAllowListEntryLength))
throw new ArgumentException(message: $"Allow list entry length must be less than or equal to {MaxAllowListEntryLength}.", paramName: nameof(AllowList));

_allowList = value;
}
}

/// <summary>
/// Gets or sets the list of <see cref="ulong"/> of an <see cref="AutoModRule"/>.
/// </summary>
public List<ulong> ExemptRoles
{
get { return _exemptRoles; }
set
{
if (value.Count > MaxExemptRoles)
throw new ArgumentException(message: $"Exempt roles count must be less than or equal to {MaxExemptRoles}.", paramName: nameof(RegexPatterns));

_exemptRoles = value;
}
}

/// <summary>
/// Gets or sets the list of <see cref="ulong"/> of an <see cref="AutoModRule"/>.
/// </summary>
public List<ulong> ExemptChannels
{
get { return _exemptChannels; }
set
{
if (value.Count > MaxExemptChannels)
throw new ArgumentException(message: $"Exempt channels count must be less than or equal to {MaxExemptChannels}.", paramName: nameof(RegexPatterns));

_exemptChannels = value;
}
}

/// <summary>
/// Gets or sets the hashset of <see cref="KeywordPresetTypes"/> of an <see cref="AutoModRule"/>.
/// </summary>
public HashSet<KeywordPresetTypes> Presets
{
get => _presets;
set
{
if (TriggerType != AutoModTriggerType.KeywordPreset)
throw new ArgumentException(message: $"Keyword presets scan only be used with 'KeywordPreset' trigger type.", paramName: nameof(AllowList));

_presets = value;
}
}

/// <summary>
/// Gets or sets the name of an <see cref="AutoModRule"/>.
/// </summary>
public string Name { get; set; }

/// <summary>
/// Gets or sets the event type of an <see cref="AutoModRule"/>.
/// </summary>
public AutoModEventType EventType { get; set; } = AutoModEventType.MessageSend;

/// <summary>
/// Gets the trigger type of an <see cref="AutoModRule"/>.
/// </summary>
public AutoModTriggerType TriggerType { get; }

/// <summary>
/// Gets or sets the mention limit of an <see cref="AutoModRule"/>.
/// </summary>
public int? MentionLimit
{
get => _mentionLimit;
set
{
if (TriggerType != AutoModTriggerType.Keyword)
throw new ArgumentException(message: $"MentionLimit can only be used with 'MentionSpam' trigger type.", paramName: nameof(MentionLimit));

if (value is not null && value > MaxMentionLimit)
throw new ArgumentException(message: $"Mention limit must be less than or equal to {MaxMentionLimit}.", paramName: nameof(MentionLimit));
_mentionLimit = value;
}
}

/// <summary>
/// Gets or sets the list of <see cref="AutoModRuleActionBuilder"/> of an <see cref="AutoModRule"/>.
/// </summary>
public List<AutoModRuleActionBuilder> Actions = new();

/// <summary>
/// Gets or sets the enabled status of an <see cref="AutoModRule"/>.
/// </summary>
public bool Enabled { get; set; } = false;

/// <summary>
/// Initializes a new instance of <see cref="AutoModRuleBuilder"/> used to create a new <see cref="AutoModRule"/>.
/// </summary>
/// <param name="type">The trigger type of an <see cref="AutoModRule"/></param>
public AutoModRuleBuilder(AutoModTriggerType type)
{
TriggerType = type;
}

/// <summary>
/// Sets the name of an <see cref="AutoModRule"/>.
/// </summary>
/// <returns>The current builder.</returns>
public AutoModRuleBuilder WithName(string name)
{
Name = name;
return this;
}

/// <summary>
/// Sets the enabled status of an <see cref="AutoModRule"/>.
/// </summary>
/// <returns>The current builder.</returns>
public AutoModRuleBuilder WithEnabled(bool enabled)
{
Enabled = enabled;
return this;
}

/// <summary>
/// Sets the event type of an <see cref="AutoModRule"/>.
/// </summary>
/// <returns>The current builder.</returns>
public AutoModRuleBuilder WithEventType(AutoModEventType eventType)
{
EventType = eventType;
return this;
}

/// <summary>
/// Sets the mention limit of an <see cref="AutoModRule"/>.
/// </summary>
/// <returns>The current builder.</returns>
public AutoModRuleBuilder WithMentionLimit(int limit)
{
MentionLimit = limit;
return this;
}

/// <summary>
/// Adds a <see cref="string"/> keyword to an <see cref="AutoModRule"/>.
/// </summary>
/// <returns>The current builder.</returns>
public AutoModRuleBuilder AddKeyword(string keyword)
{
if (TriggerType != AutoModTriggerType.Keyword)
throw new ArgumentException(message: $"Keyword filter can only be used with 'Keyword' trigger type.");

if (KeywordFilter.Count >= MaxKeywordCount)
throw new ArgumentException(message: $"Keyword count must be less than or equal to {MaxKeywordCount}.");

if (keyword.Length > MaxKeywordLength)
throw new ArgumentException(message: $"Keyword length must be less than or equal to {MaxKeywordLength}.");

KeywordFilter.Add(keyword);

return this;
}

/// <summary>
/// Adds a <see cref="string"/> allow list keyword to an <see cref="AutoModRule"/>.
/// </summary>
/// <returns>The current builder.</returns>
public AutoModRuleBuilder AddAllowListKeyword(string keyword)
{
if (TriggerType is not AutoModTriggerType.Keyword or AutoModTriggerType.KeywordPreset)
throw new ArgumentException(message: $"Allow list can only be used with 'Keyword' or 'KeywordPreset' trigger type.");

if (TriggerType == AutoModTriggerType.Keyword && AllowList.Count >= MaxAllowListCountKeyword)
throw new ArgumentException(message: $"Allow list entry count must be less than or equal to {MaxAllowListCountKeyword}.");

if (TriggerType == AutoModTriggerType.KeywordPreset && AllowList.Count > MaxAllowListCountKeywordPreset)
throw new ArgumentException(message: $"Allow list entry count must be less than or equal to {MaxAllowListCountKeywordPreset}.");

if (keyword.Length > MaxAllowListEntryLength)
throw new ArgumentException(message: $"Allow list entry length must be less than or equal to {MaxAllowListEntryLength}.");

AllowList.Add(keyword);

return this;
}

/// <summary>
/// Adds a <see cref="KeyNotFoundException"/> to an <see cref="AutoModRule"/>.
/// </summary>
/// <returns>The current builder.</returns>
public AutoModRuleBuilder AddKeywordPreset(KeywordPresetTypes type)
{
if (TriggerType != AutoModTriggerType.KeywordPreset)
throw new ArgumentException(message: $"Keyword presets scan only be used with 'KeywordPreset' trigger type.", paramName: nameof(AllowList));

Presets.Add(type);
return this;
}

/// <summary>
/// Adds a <see cref="string"/> regex pattern to an <see cref="AutoModRule"/>.
/// </summary>
/// <returns>The current builder.</returns>
public AutoModRuleBuilder AddRegexPattern(string regex)
{
if (TriggerType != AutoModTriggerType.Keyword)
throw new ArgumentException(message: $"Regex patterns can only be used with 'Keyword' trigger type.");

if (RegexPatterns.Count >= MaxRegexPatternCount)
throw new ArgumentException(message: $"Regex pattern count must be less than or equal to {MaxRegexPatternCount}.");

if (regex.Length > MaxRegexPatternLength)
throw new ArgumentException(message: $"Regex pattern must be less than or equal to {MaxRegexPatternLength}.");

RegexPatterns.Add(regex);

return this;
}

/// <summary>
/// Adds an exempt <see cref="IRole"/> to an <see cref="AutoModRule"/>.
/// </summary>
/// <returns>The current builder.</returns>
public AutoModRuleBuilder AddExemptRole(IRole role)
{
AddExemptRole(role.Id);
return this;
}

/// <summary>
/// Adds a exempt role with <see cref="ulong"/> id keyword to an <see cref="AutoModRule"/>.
/// </summary>
/// <returns>The current builder.</returns>
public AutoModRuleBuilder AddExemptRole(ulong roleId)
{
ExemptRoles.Add(roleId);
return this;
}

/// <summary>
/// Adds an exempt <see cref="IMessageChannel"/> keyword to an <see cref="AutoModRule"/>.
/// </summary>
/// <returns>The current builder.</returns>
public AutoModRuleBuilder AddExemptChannel(IMessageChannel channel)
{
AddExemptChannel(channel.Id);
return this;
}

/// <summary>
/// Adds an exempt channel with <see cref="ulong"/> id keyword to an <see cref="AutoModRule"/>.
/// </summary>
/// <returns>The current builder.</returns>
public AutoModRuleBuilder AddExemptChannel(ulong channelId)
{
ExemptChannels.Add(channelId);
return this;
}

/// <summary>
/// Adds an <see cref="AutoModRuleActionBuilder"/> to an <see cref="AutoModRule"/>.
/// </summary>
/// <returns>The current builder.</returns>
public AutoModRuleBuilder AddAction(AutoModRuleActionBuilder builder)
{
Actions.Add(builder);
return this;
}

/// <summary>
/// Creates a new instance of <see cref="AutoModRuleBuilder"/> with data from a <see cref="IAutoModRule"/>.
/// </summary>
/// <returns>The new builder.</returns>
public static AutoModRuleBuilder FromAutoModRule(IAutoModRule rule)
=> new(rule.TriggerType)
{
Name = rule.Name,
AllowList = rule.AllowList.ToList(),
RegexPatterns = rule.RegexPatterns.ToList(),
KeywordFilter = rule.KeywordFilter.ToList(),
Presets = new HashSet<KeywordPresetTypes>(rule.Presets),
ExemptChannels = rule.ExemptChannels.ToList(),
ExemptRoles = rule.ExemptRoles.ToList(),
Actions = rule.Actions.Select(AutoModRuleActionBuilder.FromModel).ToList(),
MentionLimit = rule.MentionTotalLimit,
Enabled = rule.Enabled,
EventType = rule.EventType
};

/// <summary>
/// Builds the <see cref="AutoModRuleBuilder" /> into <see cref="AutoModRule"/> ready to be sent.
/// </summary>
/// <returns></returns>
public AutoModRule Build()
{
if (string.IsNullOrWhiteSpace(Name))
throw new ArgumentException("Name of the rule must not be empty", paramName: nameof(Name));

Preconditions.AtLeast(1, Actions.Count, nameof(Actions), "Auto moderation rule must have at least 1 action");

if(TriggerType is AutoModTriggerType.Keyword)
Preconditions.AtLeast(1, KeywordFilter.Count + RegexPatterns.Count, nameof(KeywordFilter), "Auto moderation rule must have at least 1 keyword or regex pattern");

if(TriggerType is AutoModTriggerType.MentionSpam && MentionLimit is null)
throw new ArgumentException("Mention limit must not be empty", paramName: nameof(MentionLimit));
return new(Name,
EventType,
TriggerType,
KeywordFilter.ToArray(),
RegexPatterns.ToArray(),
AllowList.ToArray(),
MentionLimit,
Presets.ToArray(),
Actions.Select(x => new AutoModRuleAction(x.Type, x.ChannelId, (int?)x.TimeoutDuration?.TotalSeconds)).ToArray(),
Enabled,
ExemptRoles.ToArray(),
ExemptChannels.ToArray());
}

}

/// <summary>
/// Represents an action that will be preformed if a user breaks an <see cref="IAutoModRule"/>.
/// </summary>
public class AutoModRuleActionBuilder
{
private const int MaxTimeoutSeconds = 2419200;

private TimeSpan? _timeoutDuration;

/// <summary>
/// Gets or sets the type for this action.
/// </summary>
public AutoModActionType Type { get; }

/// <summary>
/// Get or sets the channel id on which to post alerts.
/// </summary>
/// <remarks>
/// This property will be <see langword="null"/> if <see cref="Type"/> is not <see cref="AutoModActionType.SendAlertMessage"/>
/// </remarks>
public ulong? ChannelId { get; set; }

/// <summary>
/// Gets or sets the duration of which a user will be timed out for breaking this rule.
/// </summary>
/// <remarks>
/// This property will be <see langword="null"/> if <see cref="Type"/> is not <see cref="AutoModActionType.Timeout"/>
/// </remarks>
public TimeSpan? TimeoutDuration
{
get => _timeoutDuration;
set
{
if (value is { TotalSeconds: > MaxTimeoutSeconds })
throw new ArgumentException(message: $"Field count must be less than or equal to {MaxTimeoutSeconds}.", paramName: nameof(TimeoutDuration));

_timeoutDuration = value;
}
}

/// <summary>
/// Creates a new instance of <see cref="AutoModRuleActionBuilder"/> used to define actions of an <see cref="AutoModRule"/>.
/// </summary>
public AutoModRuleActionBuilder(AutoModActionType type, ulong? channelId = null, TimeSpan? duration = null)
{
Type = type;
ChannelId = channelId;
TimeoutDuration = duration;
}

internal static AutoModRuleActionBuilder FromModel(AutoModRuleAction action)
=> new(action.Type, action.ChannelId, action.TimeoutDuration);
}

+ 55
- 0
src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleProperties.cs View File

@@ -11,6 +11,61 @@ namespace Discord
/// </summary> /// </summary>
public class AutoModRuleProperties public class AutoModRuleProperties
{ {
/// <summary>
/// Returns the max keyword count for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxKeywordCount = 1000;

/// <summary>
/// Returns the max keyword length for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxKeywordLength = 60;

/// <summary>
/// Returns the max regex pattern count for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxRegexPatternCount = 10;

/// <summary>
/// Returns the max regex pattern length for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxRegexPatternLength = 260;

/// <summary>
/// Returns the max allowlist keyword count for a <see cref="AutoModTriggerType.Keyword"/> AutoMod rule allowed by Discord.
/// </summary>
public const int MaxAllowListCountKeyword = 100;

/// <summary>
/// Returns the max allowlist keyword count for a <see cref="AutoModTriggerType.KeywordPreset"/> AutoMod rule allowed by Discord.
/// </summary>
public const int MaxAllowListCountKeywordPreset = 1000;

/// <summary>
/// Returns the max allowlist keyword length for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxAllowListEntryLength = 60;

/// <summary>
/// Returns the max mention limit for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxMentionLimit = 50;

/// <summary>
/// Returns the max exempt role count for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxExemptRoles = 20;

/// <summary>
/// Returns the max exempt channel count for an AutoMod rule allowed by Discord.
/// </summary>
public const int MaxExemptChannels = 50;

/// <summary>
/// Returns the max timeout duration in seconds for an auto moderation rule action.
/// </summary>
public const int MaxTimeoutSeconds = 2419200;

/// <summary> /// <summary>
/// Gets or sets the name for the rule. /// Gets or sets the name for the rule.
/// </summary> /// </summary>


+ 1
- 1
src/Discord.Net.Core/Entities/Guilds/IGuild.cs View File

@@ -1290,6 +1290,6 @@ namespace Discord
/// <returns> /// <returns>
/// A task that represents the asynchronous creation operation. The task result contains the created <see cref="IAutoModRule"/>. /// A task that represents the asynchronous creation operation. The task result contains the created <see cref="IAutoModRule"/>.
/// </returns> /// </returns>
Task<IAutoModRule> CreateAutoModRuleAsync(AutoModRule props, RequestOptions options = null);
Task<IAutoModRule> CreateAutoModRuleAsync(Action<AutoModRuleProperties> props, RequestOptions options = null);
} }
} }

+ 119
- 4
src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs View File

@@ -1039,7 +1039,7 @@ namespace Discord.Rest
{ {
Enabled = enabled, Enabled = enabled,
Description = description, Description = description,
WelcomeChannels = channels?.Select(ch => new API.WelcomeScreenChannel
WelcomeChannels = channels?.Select(ch => new API.WelcomeScreenChannel
{ {
ChannelId = ch.Id, ChannelId = ch.Id,
Description = ch.Description, Description = ch.Description,
@@ -1050,7 +1050,7 @@ namespace Discord.Rest


var model = await client.ApiClient.ModifyGuildWelcomeScreenAsync(args, guild.Id, options); var model = await client.ApiClient.ModifyGuildWelcomeScreenAsync(args, guild.Id, options);


if(model.WelcomeChannels.Length == 0)
if (model.WelcomeChannels.Length == 0)
return null; return null;


return new WelcomeScreen(model.Description.GetValueOrDefault(null), model.WelcomeChannels.Select( return new WelcomeScreen(model.Description.GetValueOrDefault(null), model.WelcomeChannels.Select(
@@ -1064,8 +1064,123 @@ namespace Discord.Rest


#region Auto Mod #region Auto Mod


public static async Task<AutoModerationRule> CreateAutoModRuleAsync(IGuild guild, CreateAutoModRuleParams args, BaseDiscordClient client, RequestOptions options)
=> await client.ApiClient.CreateGuildAutoModRuleAsync(guild.Id, args, options);
public static async Task<AutoModerationRule> CreateAutoModRuleAsync(IGuild guild, Action<AutoModRuleProperties> func, BaseDiscordClient client, RequestOptions options)
{
var args = new AutoModRuleProperties();
func(args);

if (!args.TriggerType.IsSpecified)
throw new ArgumentException(message: $"AutoMod rule must have a specified type.", paramName: nameof(args.TriggerType));

if (!args.Name.IsSpecified || string.IsNullOrWhiteSpace(args.Name.Value))
throw new ArgumentException("Name of the rule must not be empty", paramName: nameof(args.Name));

Preconditions.AtLeast(1, args.Actions.GetValueOrDefault(Array.Empty<AutoModRuleActionProperties>()).Length, nameof(args.Actions), "Auto moderation rule must have at least 1 action");

#region Keyword Validations

if (args.RegexPatterns.IsSpecified)
{
if (args.TriggerType.Value is not AutoModTriggerType.Keyword)
throw new ArgumentException(message: $"Regex patterns can only be used with 'Keyword' trigger type.", paramName: nameof(args.RegexPatterns));

Preconditions.AtMost(args.RegexPatterns.Value.Length, AutoModRuleProperties.MaxRegexPatternCount, nameof(args.RegexPatterns), $"Regex pattern count must be less than or equal to {AutoModRuleProperties.MaxRegexPatternCount}.");

if (args.RegexPatterns.Value.Any(x => x.Length > AutoModRuleProperties.MaxRegexPatternLength))
throw new ArgumentException(message: $"Regex pattern must be less than or equal to {AutoModRuleProperties.MaxRegexPatternLength}.", paramName: nameof(args.RegexPatterns));
}

if (args.KeywordFilter.IsSpecified)
{
if (args.TriggerType.Value != AutoModTriggerType.Keyword)
throw new ArgumentException(message: $"Keyword filter can only be used with 'Keyword' trigger type.", paramName: nameof(args.KeywordFilter));

Preconditions.AtMost(args.KeywordFilter.Value.Length, AutoModRuleProperties.MaxKeywordCount, nameof(args.KeywordFilter), $"Keyword count must be less than or equal to {AutoModRuleProperties.MaxKeywordCount}");

if (args.KeywordFilter.Value.Any(x => x.Length > AutoModRuleProperties.MaxKeywordLength))
throw new ArgumentException(message: $"Keyword length must be less than or equal to {AutoModRuleProperties.MaxKeywordLength}.", paramName: nameof(args.KeywordFilter));
}

if (args.TriggerType.Value is AutoModTriggerType.Keyword)
Preconditions.AtLeast(args.KeywordFilter.GetValueOrDefault(Array.Empty<string>()).Length + args.RegexPatterns.GetValueOrDefault(Array.Empty<string>()).Length, 1, "KeywordFilter & RegexPatterns","Auto moderation rule must have at least 1 keyword or regex pattern");

if (args.AllowList.IsSpecified)
{
if (args.TriggerType.Value is not AutoModTriggerType.Keyword or AutoModTriggerType.KeywordPreset)
throw new ArgumentException(message: $"Allow list can only be used with 'Keyword' or 'KeywordPreset' trigger type.", paramName: nameof(args.AllowList));

if (args.TriggerType.Value is AutoModTriggerType.Keyword)
Preconditions.AtMost(args.AllowList.Value.Length, AutoModRuleProperties.MaxAllowListCountKeyword, nameof(args.AllowList), $"Allow list entry count must be less than or equal to {AutoModRuleProperties.MaxAllowListCountKeyword}.");

if (args.TriggerType.Value is AutoModTriggerType.KeywordPreset)
Preconditions.AtMost(args.AllowList.Value.Length, AutoModRuleProperties.MaxAllowListCountKeywordPreset, nameof(args.AllowList), $"Allow list entry count must be less than or equal to {AutoModRuleProperties.MaxAllowListCountKeywordPreset}.");

if (args.AllowList.Value.Any(x => x.Length > AutoModRuleProperties.MaxAllowListEntryLength))
throw new ArgumentException(message: $"Allow list entry length must be less than or equal to {AutoModRuleProperties.MaxAllowListEntryLength}.", paramName: nameof(args.AllowList));

}
if (args.TriggerType.Value is not AutoModTriggerType.KeywordPreset && args.Presets.IsSpecified)
throw new ArgumentException(message: $"Keyword presets scan only be used with 'KeywordPreset' trigger type.", paramName: nameof(args.Presets));

#endregion

if (args.MentionLimit.IsSpecified)
{
if (args.TriggerType.Value is AutoModTriggerType.MentionSpam)
{
Preconditions.AtMost(args.MentionLimit.Value, AutoModRuleProperties.MaxMentionLimit, nameof(args.MentionLimit), $"Mention limit must be less or equal to {AutoModRuleProperties.MaxMentionLimit}");
Preconditions.AtLeast(args.MentionLimit.Value, 1, nameof(args.MentionLimit), $"Mention limit must be greater or equal to 1");
}
else
{
throw new ArgumentException(message: $"MentionLimit can only be used with 'MentionSpam' trigger type.", paramName: nameof(args.MentionLimit));
}
}

if (args.ExemptRoles.IsSpecified)
Preconditions.AtMost(args.ExemptRoles.Value.Length, AutoModRuleProperties.MaxExemptRoles, nameof(args.ExemptRoles), $"Exempt roles count must be less than or equal to {AutoModRuleProperties.MaxExemptRoles}.");

if (args.ExemptChannels.IsSpecified)
Preconditions.AtMost(args.ExemptChannels.Value.Length, AutoModRuleProperties.MaxExemptChannels, nameof(args.ExemptChannels), $"Exempt channels count must be less than or equal to {AutoModRuleProperties.MaxExemptChannels}.");

if (!args.Actions.IsSpecified && args.Actions.Value.Length == 0)
{
throw new ArgumentException(message: $"At least 1 action must be set for an auto moderation rule.", paramName: nameof(args.Actions));
}

if (args.Actions.Value.Any(x => x.TimeoutDuration.GetValueOrDefault().TotalSeconds > AutoModRuleProperties.MaxTimeoutSeconds))
throw new ArgumentException(message: $"Field count must be less than or equal to {AutoModRuleProperties.MaxTimeoutSeconds}.", paramName: nameof(AutoModRuleActionProperties.TimeoutDuration));

var props = new CreateAutoModRuleParams
{
EventType = args.EventType.GetValueOrDefault(AutoModEventType.MessageSend),
Enabled = args.Enabled.GetValueOrDefault(true),
ExemptRoles = args.ExemptRoles.GetValueOrDefault(),
ExemptChannels = args.ExemptChannels.GetValueOrDefault(),
Name = args.Name.Value,
TriggerType = args.TriggerType.Value,
Actions = args.Actions.Value.Select(x => new AutoModAction
{
Metadata = new ActionMetadata
{
ChannelId = x.ChannelId ?? Optional<ulong>.Unspecified,
DurationSeconds = (int?)x.TimeoutDuration?.TotalSeconds ?? Optional<int>.Unspecified
},
Type = x.Type
}).ToArray(),
TriggerMetadata = new TriggerMetadata
{
AllowList = args.AllowList,
KeywordFilter = args.KeywordFilter,
MentionLimit = args.MentionLimit,
Presets = args.Presets,
RegexPatterns = args.RegexPatterns,
},
};

return await client.ApiClient.CreateGuildAutoModRuleAsync(guild.Id, props, options);
}


public static async Task<AutoModerationRule> GetAutoModRuleAsync(ulong ruleId, IGuild guild, BaseDiscordClient client, RequestOptions options) public static async Task<AutoModerationRule> GetAutoModRuleAsync(ulong ruleId, IGuild guild, BaseDiscordClient client, RequestOptions options)
=> await client.ApiClient.GetGuildAutoModRuleAsync(guild.Id, ruleId, options); => await client.ApiClient.GetGuildAutoModRuleAsync(guild.Id, ruleId, options);


+ 3
- 3
src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs View File

@@ -1217,9 +1217,9 @@ namespace Discord.Rest
} }


/// <inheritdoc cref="IGuild.CreateAutoModRuleAsync"/> /// <inheritdoc cref="IGuild.CreateAutoModRuleAsync"/>
public async Task<RestAutoModRule> CreateAutoModRuleAsync(AutoModRule props, RequestOptions options = null)
public async Task<RestAutoModRule> CreateAutoModRuleAsync(Action<AutoModRuleProperties> props, RequestOptions options = null)
{ {
var rule = await GuildHelper.CreateAutoModRuleAsync(this, props.ToProperties(), Discord, options);
var rule = await GuildHelper.CreateAutoModRuleAsync(this, props, Discord, options);


return RestAutoModRule.Create(Discord, rule); return RestAutoModRule.Create(Discord, rule);
} }
@@ -1581,7 +1581,7 @@ namespace Discord.Rest
=> await GetAutoModRulesAsync(options).ConfigureAwait(false); => await GetAutoModRulesAsync(options).ConfigureAwait(false);


/// <inheritdoc/> /// <inheritdoc/>
async Task<IAutoModRule> IGuild.CreateAutoModRuleAsync(AutoModRule props, RequestOptions options)
async Task<IAutoModRule> IGuild.CreateAutoModRuleAsync(Action<AutoModRuleProperties> props, RequestOptions options)
=> await CreateAutoModRuleAsync(props, options).ConfigureAwait(false); => await CreateAutoModRuleAsync(props, options).ConfigureAwait(false);


#endregion #endregion


+ 0
- 30
src/Discord.Net.Rest/Extensions/EntityExtensions.cs View File

@@ -214,35 +214,5 @@ namespace Discord.Rest
Id = interaction.Id, Id = interaction.Id,
}; };
} }

public static API.Rest.CreateAutoModRuleParams ToProperties(this AutoModRule builder)
{
return new API.Rest.CreateAutoModRuleParams
{
Name = builder.Name,
TriggerMetadata = new API.TriggerMetadata
{
KeywordFilter = builder.KeywordFilter ?? Optional<string[]>.Unspecified,
AllowList = builder.AllowList ?? Optional<string[]>.Unspecified,
MentionLimit = builder.MentionLimit ?? Optional<int>.Unspecified,
Presets = builder.Presets ?? Optional<KeywordPresetTypes[]>.Unspecified,
RegexPatterns = builder.RegexPatterns ?? Optional<string[]>.Unspecified,
},
TriggerType = builder.TriggerType,
Actions = builder.Actions?.Select(x => new API.AutoModAction
{
Metadata = new API.ActionMetadata
{
ChannelId = x.ChannelId ?? Optional<ulong>.Unspecified,
DurationSeconds = (int?)x.TimeoutDuration?.TotalSeconds ?? Optional<int>.Unspecified
},
Type = x.Type,
}).ToArray(),
Enabled = builder.Enabled,
EventType = builder.EventType,
ExemptChannels = builder.ExemptChannels ?? Optional<ulong[]>.Unspecified,
ExemptRoles = builder.ExemptRoles ?? Optional<ulong[]>.Unspecified,
};
}
} }
} }

+ 3
- 3
src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs View File

@@ -1867,9 +1867,9 @@ namespace Discord.WebSocket
} }


/// <inheritdoc cref="IGuild.CreateAutoModRuleAsync"/> /// <inheritdoc cref="IGuild.CreateAutoModRuleAsync"/>
public async Task<SocketAutoModRule> CreateAutoModRuleAsync(AutoModRule props, RequestOptions options = null)
public async Task<SocketAutoModRule> CreateAutoModRuleAsync(Action<AutoModRuleProperties> props, RequestOptions options = null)
{ {
var rule = await GuildHelper.CreateAutoModRuleAsync(this, props.ToProperties(), Discord, options);
var rule = await GuildHelper.CreateAutoModRuleAsync(this, props, Discord, options);


return AddOrUpdateAutoModRule(rule); return AddOrUpdateAutoModRule(rule);
} }
@@ -2138,7 +2138,7 @@ namespace Discord.WebSocket
=> await GetAutoModRulesAsync(options).ConfigureAwait(false); => await GetAutoModRulesAsync(options).ConfigureAwait(false);


/// <inheritdoc/> /// <inheritdoc/>
async Task<IAutoModRule> IGuild.CreateAutoModRuleAsync(AutoModRule props, RequestOptions options)
async Task<IAutoModRule> IGuild.CreateAutoModRuleAsync(Action<AutoModRuleProperties> props, RequestOptions options)
=> await CreateAutoModRuleAsync(props, options).ConfigureAwait(false); => await CreateAutoModRuleAsync(props, options).ConfigureAwait(false);


#endregion #endregion


Loading…
Cancel
Save