mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-27 07:59:03 -07:00
Radicade Public Code
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RadicadeServer.DB;
|
||||
|
||||
namespace RadicadeServer.Utils
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static class GameBlockMonitor
|
||||
{
|
||||
private static readonly object Lock = new();
|
||||
private static readonly SemaphoreSlim RefreshGate = new(1, 1);
|
||||
private static Dictionary<string, DateTime?> Active = new();
|
||||
private static DateTime LastRefresh = DateTime.MinValue;
|
||||
private const double RefreshIntervalSeconds = 10;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static async Task<bool> IsBlockedAsync(IDbContextFactory<RecDBContext> factory, string ipAddress)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ipAddress)) return false;
|
||||
|
||||
DateTime lastRefresh;
|
||||
lock (Lock) lastRefresh = LastRefresh;
|
||||
if ((DateTime.UtcNow - lastRefresh).TotalSeconds > RefreshIntervalSeconds)
|
||||
await RefreshAsync(factory);
|
||||
|
||||
lock (Lock)
|
||||
{
|
||||
if (Active.TryGetValue(NormalizeIp(ipAddress), out var expiresAt))
|
||||
return !expiresAt.HasValue || expiresAt.Value > DateTime.UtcNow;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static void Invalidate()
|
||||
{
|
||||
lock (Lock) LastRefresh = DateTime.MinValue;
|
||||
}
|
||||
|
||||
public static async Task RefreshAsync(IDbContextFactory<RecDBContext> factory)
|
||||
{
|
||||
await RefreshGate.WaitAsync();
|
||||
try
|
||||
{
|
||||
|
||||
DateTime lastRefresh;
|
||||
lock (Lock) lastRefresh = LastRefresh;
|
||||
if ((DateTime.UtcNow - lastRefresh).TotalSeconds <= RefreshIntervalSeconds)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
await using var db = await factory.CreateDbContextAsync();
|
||||
var now = DateTime.UtcNow;
|
||||
var rows = await db.GameBlocks.AsNoTracking().ToListAsync();
|
||||
|
||||
|
||||
|
||||
var expired = rows.Where(b => b.ExpiresAt.HasValue && b.ExpiresAt.Value < now).ToList();
|
||||
if (expired.Count > 0)
|
||||
{
|
||||
db.GameBlocks.RemoveRange(expired);
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
|
||||
var active = new Dictionary<string, DateTime?>();
|
||||
foreach (var row in rows.Where(b => !expired.Contains(b)))
|
||||
active[NormalizeIp(row.IpAddress)] = row.ExpiresAt;
|
||||
|
||||
lock (Lock)
|
||||
{
|
||||
Active = active;
|
||||
LastRefresh = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
|
||||
lock (Lock) LastRefresh = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
RefreshGate.Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static string NormalizeIp(string ip)
|
||||
{
|
||||
ip = (ip ?? "").Trim();
|
||||
if (ip.StartsWith("::ffff:", StringComparison.OrdinalIgnoreCase))
|
||||
ip = ip.Substring("::ffff:".Length);
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user