Created
May 31, 2020 23:11
-
-
Save Hamsterland/a69d60aaa416e5174322b7f0280e8c37 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Threading.Tasks; | |
using Beatbox.Enums; | |
using Discord; | |
using Discord.Commands; | |
namespace Beatbox.Preconditions | |
{ | |
public class CooldownAttribute : PreconditionAttribute | |
{ | |
private readonly TimeSpan _invokeLimitPeriod; | |
private readonly uint _invokeLimit; | |
private readonly bool _skipAdmin; | |
private readonly Dictionary<ulong, CommandTimeout> _invokeTracker = new Dictionary<ulong, CommandTimeout>(); | |
public CooldownAttribute(double period, Measure measure, uint times, bool skipAdmin = false) | |
{ | |
_invokeLimit = times; | |
_skipAdmin = skipAdmin; | |
_invokeLimitPeriod = measure switch | |
{ | |
Measure.Days => TimeSpan.FromDays(period), | |
Measure.Hours => TimeSpan.FromHours(period), | |
Measure.Minutes => TimeSpan.FromMinutes(period), | |
Measure.Seconds => TimeSpan.FromSeconds(period), | |
_ => _invokeLimitPeriod | |
}; | |
} | |
public override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services) | |
{ | |
var now = DateTime.UtcNow; | |
var key = context.User.Id; | |
var timeout = _invokeTracker.TryGetValue(key, out var t) && now - t.FirstInvoke < _invokeLimitPeriod ? t : new CommandTimeout(now); | |
timeout.TimesInvoked++; | |
if (timeout.TimesInvoked <= _invokeLimit || _skipAdmin && (context.User as IGuildUser).GuildPermissions.Administrator) | |
{ | |
_invokeTracker[key] = timeout; | |
return Task.FromResult(PreconditionResult.FromSuccess()); | |
} | |
return Task.FromResult(PreconditionResult.FromError($"{context.User.Mention} Please wait `{timeout.FirstInvoke - now + _invokeLimitPeriod:hh\\:mm\\:ss}`")); | |
} | |
} | |
public sealed class CommandTimeout | |
{ | |
public uint TimesInvoked { get; set; } | |
public DateTime FirstInvoke { get; } | |
public CommandTimeout(DateTime timeStarted) | |
{ | |
FirstInvoke = timeStarted; | |
} | |
} | |
public enum Measure | |
{ | |
Days, | |
Hours, | |
Minutes, | |
Seconds | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment