2017-08-10 22:19:42 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
2017-11-12 03:12:24 +00:00
|
|
|
|
namespace Noikoio.RegexBot.Module.AutoRespond
|
2017-08-10 22:19:42 +00:00
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Stores rate limit settings and caches.
|
|
|
|
|
/// </summary>
|
|
|
|
|
class RateLimitCache
|
|
|
|
|
{
|
2017-08-12 06:45:27 +00:00
|
|
|
|
public const ushort DefaultTimeout = 20; // this is Skeeter's fault
|
2017-08-10 22:19:42 +00:00
|
|
|
|
|
|
|
|
|
private readonly ushort _timeout;
|
|
|
|
|
private Dictionary<ulong, DateTime> _cache;
|
|
|
|
|
|
|
|
|
|
public ushort Timeout => _timeout;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sets up a new instance of <see cref="RateLimitCache"/>.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public RateLimitCache(ushort timeout)
|
|
|
|
|
{
|
|
|
|
|
_timeout = timeout;
|
|
|
|
|
_cache = new Dictionary<ulong, DateTime>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2017-09-01 07:53:40 +00:00
|
|
|
|
/// Checks if a "usage" is allowed for the given value.
|
2017-08-10 22:19:42 +00:00
|
|
|
|
/// Items added to cache will be removed after the number of seconds specified in <see cref="Timeout"/>.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id">The ID to add to the cache.</param>
|
|
|
|
|
/// <returns>True on success. False if the given ID already exists.</returns>
|
2017-09-01 07:53:40 +00:00
|
|
|
|
public bool AllowUsage(ulong id)
|
2017-08-10 22:19:42 +00:00
|
|
|
|
{
|
2017-08-12 06:45:27 +00:00
|
|
|
|
if (_timeout == 0) return true;
|
|
|
|
|
|
2017-09-01 07:53:40 +00:00
|
|
|
|
lock (this)
|
|
|
|
|
{
|
|
|
|
|
Clean();
|
|
|
|
|
if (_cache.ContainsKey(id)) return false;
|
|
|
|
|
_cache.Add(id, DateTime.Now);
|
|
|
|
|
}
|
2017-08-10 22:19:42 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Clean()
|
|
|
|
|
{
|
|
|
|
|
var now = DateTime.Now;
|
|
|
|
|
var clean = new Dictionary<ulong, DateTime>();
|
|
|
|
|
foreach (var kp in _cache)
|
|
|
|
|
{
|
|
|
|
|
if (kp.Value.AddSeconds(Timeout) > now)
|
|
|
|
|
{
|
|
|
|
|
// Copy items that have not yet timed out to the new dictionary
|
|
|
|
|
clean.Add(kp.Key, kp.Value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
_cache = clean;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|