- Renamed CustomReaction model to NadekoExpression

- Used structured logging everywhere
This commit is contained in:
Kwoth
2022-01-04 07:35:55 +01:00
parent ef49030841
commit 3aa6a54b6e
30 changed files with 330 additions and 300 deletions

View File

@@ -63,7 +63,7 @@ public partial class Administration
}
catch (Exception ex)
{
Log.Warning(ex.ToString());
Log.Warning(ex, "Exception in the mute command");
await ReplyErrorLocalizedAsync(strs.mute_error);
}
}
@@ -124,7 +124,7 @@ public partial class Administration
}
catch (Exception ex)
{
Log.Warning(ex.ToString());
Log.Warning(ex, "Exception in the chatmute command");
await ReplyErrorLocalizedAsync(strs.mute_error);
}
}
@@ -148,7 +148,7 @@ public partial class Administration
}
catch (Exception ex)
{
Log.Warning(ex.ToString());
Log.Warning(ex, "Error in chatmute command");
await ReplyErrorLocalizedAsync(strs.mute_error);
}
}

View File

@@ -221,7 +221,6 @@ public class ProtectionService : INService
if (stats.Count >= spamSettings.AntiSpamSettings.MessageThreshold)
if (spamSettings.UserStats.TryRemove(msg.Author.Id, out stats))
{
stats.Dispose();
var settings = spamSettings.AntiSpamSettings;
await PunishUsers(settings.Action,
ProtectionType.Spamming,
@@ -319,10 +318,8 @@ public class ProtectionService : INService
public bool TryStopAntiSpam(ulong guildId)
{
if (_antiSpamGuilds.TryRemove(guildId, out var removed))
if (_antiSpamGuilds.TryRemove(guildId, out _))
{
foreach (var (_, val) in removed.UserStats) val.Dispose();
using var uow = _db.GetDbContext();
var gc = uow.GuildConfigsForId(guildId,
set => set.Include(x => x.AntiSpamSetting).ThenInclude(x => x.IgnoredChannels));

View File

@@ -1,52 +1,65 @@
#nullable disable
namespace NadekoBot.Modules.Administration;
public sealed class UserSpamStats : IDisposable
public sealed class UserSpamStats
{
public int Count
=> timers.Count;
{
get
{
lock (_applyLock)
{
Cleanup();
Log.Information("{Count}",_messageTracker.Count.ToString());
return _messageTracker.Count;
}
}
}
public string LastMessage { get; set; }
private string lastMessage;
private ConcurrentQueue<Timer> timers;
private readonly Queue<DateTime> _messageTracker;
private readonly object _applyLock = new();
private readonly TimeSpan _maxTime = TimeSpan.FromMinutes(30);
public UserSpamStats(IUserMessage msg)
{
LastMessage = msg.Content.ToUpperInvariant();
timers = new();
lastMessage = msg.Content.ToUpperInvariant();
_messageTracker = new();
ApplyNextMessage(msg);
}
public void ApplyNextMessage(IUserMessage message)
{
var upperMsg = message.Content.ToUpperInvariant();
lock (_applyLock)
{
var upperMsg = message.Content.ToUpperInvariant();
if (upperMsg != LastMessage || (string.IsNullOrWhiteSpace(upperMsg) && message.Attachments.Any()))
if (upperMsg != lastMessage || (string.IsNullOrWhiteSpace(upperMsg) && message.Attachments.Any()))
{
LastMessage = upperMsg;
while (timers.TryDequeue(out var old))
old.Change(Timeout.Infinite, Timeout.Infinite);
// if it's a new message, reset spam counter
lastMessage = upperMsg;
_messageTracker.Clear();
}
var t = new Timer(_ =>
{
if (timers.TryDequeue(out var old))
old.Change(Timeout.Infinite, Timeout.Infinite);
},
null,
TimeSpan.FromMinutes(30),
TimeSpan.FromMinutes(30));
timers.Enqueue(t);
_messageTracker.Enqueue(DateTime.UtcNow);
}
}
public void Dispose()
private void Cleanup()
{
while (timers.TryDequeue(out var old))
old.Change(Timeout.Infinite, Timeout.Infinite);
lock (_applyLock)
{
while (_messageTracker.TryPeek(out var dateTime))
{
if (DateTime.UtcNow - dateTime < _maxTime)
break;
_messageTracker.Dequeue();
}
}
}
}

View File

@@ -18,7 +18,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
private ImmutableDictionary<ulong, IDMChannel> ownerChannels =
new Dictionary<ulong, IDMChannel>().ToImmutableDictionary();
private ConcurrentDictionary<ulong?, ConcurrentDictionary<int, Timer>> _autoCommands = new();
private ConcurrentDictionary<ulong?, ConcurrentDictionary<int, Timer>> autoCommands = new();
private readonly IImageCache _imgs;
private readonly IHttpClientFactory _httpFactory;
@@ -75,12 +75,12 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
if (server.OwnerId != _client.CurrentUser.Id)
{
await server.LeaveAsync();
Log.Information($"Left server {server.Name} [{server.Id}]");
Log.Information("Left server {Name} [{Id}]", server.Name, server.Id);
}
else
{
await server.DeleteAsync();
Log.Information($"Deleted server {server.Name} [{server.Id}]");
Log.Information("Deleted server {Name} [{Id}]", server.Name, server.Id);
}
});
}
@@ -89,7 +89,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
{
await using var uow = _db.GetDbContext();
_autoCommands = uow.AutoCommands.AsNoTracking()
autoCommands = uow.AutoCommands.AsNoTracking()
.Where(x => x.Interval >= 5)
.AsEnumerable()
.GroupBy(x => x.GuildId)
@@ -145,7 +145,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
if (cmd.Interval >= 5)
{
var autos = _autoCommands.GetOrAdd(cmd.GuildId, new ConcurrentDictionary<int, Timer>());
var autos = autoCommands.GetOrAdd(cmd.GuildId, new ConcurrentDictionary<int, Timer>());
autos.AddOrUpdate(cmd.Id,
_ => TimerFromAutoCommand(cmd),
(_, old) =>
@@ -185,9 +185,9 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
if (!ownerChannels.Any())
Log.Warning(
"No owner channels created! Make sure you've specified the correct OwnerId in the creds.yml file and invited the bot to a Discord server.");
"No owner channels created! Make sure you've specified the correct OwnerId in the creds.yml file and invited the bot to a Discord server");
else
Log.Information($"Created {ownerChannels.Count} out of {_creds.OwnerIds.Count} owner message channels.");
Log.Information("Created {OwnerChannelCount} out of {TotalOwnerChannelCount} owner message channels", ownerChannels.Count, _creds.OwnerIds.Count);
}
public Task LeaveGuild(string guildStr)
@@ -220,7 +220,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
}
catch
{
Log.Warning("Can't contact owner with id {0}", ownerCh.Recipient.Id);
Log.Warning("Can't contact owner with id {OwnerId}", ownerCh.Recipient.Id);
}
}
else
@@ -262,7 +262,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
if (cmd is not null)
{
uow.Remove(cmd);
if (_autoCommands.TryGetValue(cmd.GuildId, out var autos))
if (autoCommands.TryGetValue(cmd.GuildId, out var autos))
if (autos.TryRemove(cmd.Id, out var timer))
timer.Change(Timeout.Infinite, Timeout.Infinite);
uow.SaveChanges();

View File

@@ -86,7 +86,7 @@ public partial class Administration
}
catch (Exception ex)
{
Log.Warning(ex.Message);
Log.Warning(ex, "Exception occured while warning a user");
var errorEmbed = _eb.Create().WithErrorColor().WithDescription(GetText(strs.cant_apply_punishment));
if (dmFailed) errorEmbed.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user));
@@ -565,7 +565,7 @@ public partial class Administration
{
var bans = await ctx.Guild.GetBansAsync();
var bun = bans.FirstOrDefault(x => x.User.ToString().ToLowerInvariant() == user.ToLowerInvariant());
var bun = bans.FirstOrDefault(x => x.User.ToString()!.ToLowerInvariant() == user.ToLowerInvariant());
if (bun is null)
{

View File

@@ -162,7 +162,9 @@ public class UserPunishService : INService
}
else
{
Log.Warning($"Can't find role {roleId.Value} on server {guild.Id} to apply punishment.");
Log.Warning("Can't find role {RoleId} on server {GuildId} to apply punishment",
roleId.Value,
guild.Id);
}
break;
@@ -217,7 +219,9 @@ WHERE GuildId in (SELECT GuildId FROM GuildConfigs WHERE WarnExpireHours > 0 AND
AND DateAdded < datetime('now', (SELECT '-' || WarnExpireHours || ' hours' FROM GuildConfigs as gc WHERE gc.GuildId = Warnings.GuildId));");
if (cleared > 0 || deleted > 0)
Log.Information($"Cleared {cleared} warnings and deleted {deleted} warnings due to expiry.");
Log.Information("Cleared {ClearedWarnings} warnings and deleted {DeletedWarnings} warnings due to expiry",
cleared,
deleted);
}
public async Task CheckWarnExpiresAsync(ulong guildId)
@@ -305,7 +309,8 @@ WHERE GuildId={guildId}
IRole role = null)
{
// these 3 don't make sense with time
if (punish is PunishmentAction.Softban or PunishmentAction.Kick or PunishmentAction.RemoveRoles && time is not null)
if (punish is PunishmentAction.Softban or PunishmentAction.Kick or PunishmentAction.RemoveRoles
&& time is not null)
return false;
if (number <= 0 || (time is not null && time.Time > TimeSpan.FromDays(49)))
return false;