Skip to content

Commit

Permalink
Add "rule" option for infraction-issuing commands
Browse files Browse the repository at this point in the history
EF migration required
  • Loading branch information
oliverbooth committed May 3, 2022
1 parent 98d0df7 commit 4dbbe8c
Show file tree
Hide file tree
Showing 20 changed files with 542 additions and 217 deletions.
188 changes: 188 additions & 0 deletions Hammer.API/IHammerPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@ public interface IHammerPlugin : IPlugin
/// </exception>
Task<IInfraction> BanAsync(DiscordUser user, DiscordMember staffMember);

/// <summary>
/// Issues a ban against a user.
/// </summary>
/// <param name="user">The user to ban.</param>
/// <param name="staffMember">The staff member responsible for the infraction.</param>
/// <param name="ruleBroken">The rule broken.</param>
/// <returns>The newly-created infraction.</returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="user" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="staffMember" /> is <see langword="null" />.</para>
/// </exception>
Task<IInfraction> BanAsync(DiscordUser user, DiscordMember staffMember, int ruleBroken);

/// <summary>
/// Issues a ban against a user, with a specified reason.
/// </summary>
Expand All @@ -40,6 +54,23 @@ public interface IHammerPlugin : IPlugin
/// </exception>
Task<IInfraction> BanAsync(DiscordUser user, DiscordMember staffMember, string reason);

/// <summary>
/// Issues a ban against a user, with a specified reason.
/// </summary>
/// <param name="user">The user to ban.</param>
/// <param name="staffMember">The staff member responsible for the infraction.</param>
/// <param name="reason">The reason for the infraction.</param>
/// <param name="ruleBroken">The rule broken.</param>
/// <returns>The newly-created infraction.</returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="user" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="staffMember" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="reason" /> is <see langword="null" />, empty, or consists of only whitespace.</para>
/// </exception>
Task<IInfraction> BanAsync(DiscordUser user, DiscordMember staffMember, string reason, int ruleBroken);

/// <summary>
/// Issues a temporary ban against a user.
/// </summary>
Expand All @@ -55,6 +86,22 @@ public interface IHammerPlugin : IPlugin
/// <exception cref="ArgumentException"><paramref name="duration" /> refers to a negative duration.</exception>
Task<IInfraction> BanAsync(DiscordUser user, DiscordMember staffMember, TimeSpan duration);

/// <summary>
/// Issues a temporary ban against a user.
/// </summary>
/// <param name="user">The user to ban.</param>
/// <param name="staffMember">The staff member responsible for the infraction.</param>
/// <param name="duration">The duration of the ban.</param>
/// <param name="ruleBroken">The rule broken.</param>
/// <returns>The newly-created infraction.</returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="user" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="staffMember" /> is <see langword="null" />.</para>
/// </exception>
/// <exception cref="ArgumentException"><paramref name="duration" /> refers to a negative duration.</exception>
Task<IInfraction> BanAsync(DiscordUser user, DiscordMember staffMember, TimeSpan duration, int ruleBroken);

/// <summary>
/// Issues a temporary ban against a user with a specified reason.
/// </summary>
Expand All @@ -75,6 +122,27 @@ public interface IHammerPlugin : IPlugin
/// </exception>
Task<IInfraction> BanAsync(DiscordUser user, DiscordMember staffMember, string reason, TimeSpan duration);

/// <summary>
/// Issues a temporary ban against a user with a specified reason.
/// </summary>
/// <param name="user">The user to ban.</param>
/// <param name="staffMember">The staff member responsible for the infraction.</param>
/// <param name="reason">The reason for the infraction.</param>
/// <param name="duration">The duration of the ban.</param>
/// <param name="ruleBroken">The rule broken.</param>
/// <returns>The newly-created infraction.</returns>
/// <exception cref="ArgumentException">
/// <para><paramref name="duration" /> refers to a negative duration.</para>
/// </exception>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="user" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="staffMember" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="reason" /> is <see langword="null" />, empty, or consists of only whitespace.</para>
/// </exception>
Task<IInfraction> BanAsync(DiscordUser user, DiscordMember staffMember, string reason, TimeSpan duration, int ruleBroken);

/// <summary>
/// Deletes a specified message, logging the deletion in the staff log and optionally notifying the author.
/// </summary>
Expand Down Expand Up @@ -202,6 +270,23 @@ public interface IHammerPlugin : IPlugin
/// </exception>
Task<IInfraction> KickAsync(DiscordMember member, DiscordMember staffMember);

/// <summary>
/// Kicks a member from the guild.
/// </summary>
/// <param name="member">The member to kick.</param>
/// <param name="staffMember">The staff member responsible for the infraction.</param>
/// <param name="ruleBroken">The rule broken.</param>
/// <returns>The newly-created infraction.</returns>
/// <exception cref="ArgumentException">
/// <para><paramref name="member" /> and <paramref name="staffMember" /> are not in the same guild.</para>
/// </exception>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="member" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="staffMember" /> is <see langword="null" />.</para>
/// </exception>
Task<IInfraction> KickAsync(DiscordMember member, DiscordMember staffMember, int ruleBroken);

/// <summary>
/// Kicks a member from the guild.
/// </summary>
Expand All @@ -221,6 +306,26 @@ public interface IHammerPlugin : IPlugin
/// </exception>
Task<IInfraction> KickAsync(DiscordMember member, DiscordMember staffMember, string reason);

/// <summary>
/// Kicks a member from the guild.
/// </summary>
/// <param name="member">The member to kick.</param>
/// <param name="staffMember">The staff member responsible for the infraction.</param>
/// <param name="reason">The reason for the infraction.</param>
/// <param name="ruleBroken">The rule broken.</param>
/// <returns>The newly-created infraction.</returns>
/// <exception cref="ArgumentException">
/// <para><paramref name="member" /> and <paramref name="staffMember" /> are not in the same guild.</para>
/// </exception>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="member" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="staffMember" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="reason" /> is <see langword="null" />, empty, or consists of only whitespace.</para>
/// </exception>
Task<IInfraction> KickAsync(DiscordMember member, DiscordMember staffMember, string reason, int ruleBroken);

/// <summary>
/// Issues a mute against a user.
/// </summary>
Expand All @@ -234,6 +339,20 @@ public interface IHammerPlugin : IPlugin
/// </exception>
Task<IInfraction> MuteAsync(DiscordUser user, DiscordMember staffMember);

/// <summary>
/// Issues a mute against a user.
/// </summary>
/// <param name="user">The user to mute.</param>
/// <param name="staffMember">The staff member responsible for the infraction.</param>
/// <param name="ruleBroken">The rule broken.</param>
/// <returns>The newly-created infraction.</returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="user" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="staffMember" /> is <see langword="null" />.</para>
/// </exception>
Task<IInfraction> MuteAsync(DiscordUser user, DiscordMember staffMember, int ruleBroken);

/// <summary>
/// Issues a mute against a user, with a specified reason.
/// </summary>
Expand All @@ -250,6 +369,23 @@ public interface IHammerPlugin : IPlugin
/// </exception>
Task<IInfraction> MuteAsync(DiscordUser user, DiscordMember staffMember, string reason);

/// <summary>
/// Issues a mute against a user, with a specified reason.
/// </summary>
/// <param name="user">The user to mute.</param>
/// <param name="staffMember">The staff member responsible for the infraction.</param>
/// <param name="reason">The reason for the infraction.</param>
/// <param name="ruleBroken">The rule broken.</param>
/// <returns>The newly-created infraction.</returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="user" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="staffMember" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="reason" /> is <see langword="null" />, empty, or consists of only whitespace.</para>
/// </exception>
Task<IInfraction> MuteAsync(DiscordUser user, DiscordMember staffMember, string reason, int ruleBroken);

/// <summary>
/// Issues a temporary mute against a user.
/// </summary>
Expand All @@ -265,6 +401,22 @@ public interface IHammerPlugin : IPlugin
/// </exception>
Task<IInfraction> MuteAsync(DiscordUser user, DiscordMember staffMember, TimeSpan duration);

/// <summary>
/// Issues a temporary mute against a user.
/// </summary>
/// <param name="user">The user to mute.</param>
/// <param name="staffMember">The staff member responsible for the infraction.</param>
/// <param name="duration">The duration of the mute.</param>
/// <param name="ruleBroken">The rule broken.</param>
/// <returns>The newly-created infraction.</returns>
/// <exception cref="ArgumentException"><paramref name="duration" /> refers to a negative duration.</exception>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="user" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="staffMember" /> is <see langword="null" />.</para>
/// </exception>
Task<IInfraction> MuteAsync(DiscordUser user, DiscordMember staffMember, TimeSpan duration, int ruleBroken);

/// <summary>
/// Issues a temporary mute against a user with a specified reason.
/// </summary>
Expand All @@ -283,6 +435,25 @@ public interface IHammerPlugin : IPlugin
/// </exception>
Task<IInfraction> MuteAsync(DiscordUser user, DiscordMember staffMember, string reason, TimeSpan duration);

/// <summary>
/// Issues a temporary mute against a user with a specified reason.
/// </summary>
/// <param name="user">The user to mute.</param>
/// <param name="staffMember">The staff member responsible for the infraction.</param>
/// <param name="reason">The reason for the infraction.</param>
/// <param name="duration">The duration of the mute.</param>
/// <param name="ruleBroken">The rule broken.</param>
/// <returns>The newly-created infraction.</returns>
/// <exception cref="ArgumentException"><paramref name="duration" /> refers to a negative duration.</exception>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="user" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="staffMember" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="reason" /> is <see langword="null" />, empty, or consists of only whitespace.</para>
/// </exception>
Task<IInfraction> MuteAsync(DiscordUser user, DiscordMember staffMember, string reason, TimeSpan duration, int ruleBroken);

/// <summary>
/// Issues a warning against a user, with a specified reason.
/// </summary>
Expand All @@ -298,4 +469,21 @@ public interface IHammerPlugin : IPlugin
/// <para><paramref name="reason" /> is <see langword="null" />, empty, or consists of only whitespace.</para>
/// </exception>
Task<IInfraction> WarnAsync(DiscordUser user, DiscordMember staffMember, string reason);

/// <summary>
/// Issues a warning against a user, with a specified reason.
/// </summary>
/// <param name="user">The user to warn.</param>
/// <param name="staffMember">The staff member responsible for the infraction.</param>
/// <param name="reason">The reason for the infraction.</param>
/// <param name="ruleBroken">The rule broken.</param>
/// <returns>The newly-created infraction.</returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="user" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="staffMember" /> is <see langword="null" />.</para>
/// or
/// <para><paramref name="reason" /> is <see langword="null" />, empty, or consists of only whitespace.</para>
/// </exception>
Task<IInfraction> WarnAsync(DiscordUser user, DiscordMember staffMember, string reason, int ruleBroken);
}
8 changes: 7 additions & 1 deletion Hammer.API/IInfraction.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;

namespace Hammer.API;

Expand Down Expand Up @@ -38,6 +38,12 @@ public interface IInfraction : IEquatable<IInfraction>, IComparable<IInfraction>
/// <value>The reason, or <see langword="null" /> if no reason is specified.</value>
string? Reason { get; }

/// <summary>
/// Gets the rule which was broken.
/// </summary>
/// <value>The rule which was broken, or <see langword="null" /> if no rule is specified.</value>
int? RuleId { get; }

/// <summary>
/// Gets the ID of the staff member who issued this infraction.
/// </summary>
Expand Down
29 changes: 29 additions & 0 deletions Hammer/AutocompleteProviders/RuleAutocompleteProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DSharpPlus.Entities;
using DSharpPlus.SlashCommands;
using Hammer.Data;
using Hammer.Services;
using Microsoft.Extensions.DependencyInjection;

namespace Hammer.AutocompleteProviders;

/// <summary>
/// Provides autocomplete suggestions for rules.
/// </summary>
internal sealed class RuleAutocompleteProvider : IAutocompleteProvider
{
/// <inheritdoc />
public Task<IEnumerable<DiscordAutoCompleteChoice>> Provider(AutocompleteContext context)
{
var ruleService = context.Services.GetRequiredService<RuleService>();
IReadOnlyList<Rule> rules = ruleService.GetGuildRules(context.Guild);
return Task.FromResult(rules.Select(rule => new DiscordAutoCompleteChoice(GetRuleDescription(rule), rule.Id)));
}

private static string GetRuleDescription(Rule rule)
{
return $"{rule.Id}: {rule.Brief ?? rule.Content}";
}
}
Loading

0 comments on commit 4dbbe8c

Please sign in to comment.