- 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

@@ -7,12 +7,12 @@ namespace NadekoBot.Db;
public static class NadekoExpressionExtensions public static class NadekoExpressionExtensions
{ {
public static int ClearFromGuild(this DbSet<CustomReaction> exprs, ulong guildId) public static int ClearFromGuild(this DbSet<NadekoExpression> exprs, ulong guildId)
=> exprs.Delete(x => x.GuildId == guildId); => exprs.Delete(x => x.GuildId == guildId);
public static IEnumerable<CustomReaction> ForId(this DbSet<CustomReaction> exprs, ulong id) public static IEnumerable<NadekoExpression> ForId(this DbSet<NadekoExpression> exprs, ulong id)
=> exprs.AsNoTracking().AsQueryable().Where(x => x.GuildId == id).ToList(); => exprs.AsNoTracking().AsQueryable().Where(x => x.GuildId == id).ToList();
public static CustomReaction GetByGuildIdAndInput(this DbSet<CustomReaction> exprs, ulong? guildId, string input) public static NadekoExpression GetByGuildIdAndInput(this DbSet<NadekoExpression> exprs, ulong? guildId, string input)
=> exprs.FirstOrDefault(x => x.GuildId == guildId && x.Trigger.ToUpper() == input); => exprs.FirstOrDefault(x => x.GuildId == guildId && x.Trigger.ToUpper() == input);
} }

View File

@@ -1,7 +1,7 @@
#nullable disable #nullable disable
namespace NadekoBot.Services.Database.Models; namespace NadekoBot.Services.Database.Models;
public class CustomReaction : DbEntity public class NadekoExpression : DbEntity
{ {
public ulong? GuildId { get; set; } public ulong? GuildId { get; set; }
public string Response { get; set; } public string Response { get; set; }

View File

@@ -34,7 +34,7 @@ public class NadekoContext : DbContext
public DbSet<Reminder> Reminders { get; set; } public DbSet<Reminder> Reminders { get; set; }
public DbSet<SelfAssignedRole> SelfAssignableRoles { get; set; } public DbSet<SelfAssignedRole> SelfAssignableRoles { get; set; }
public DbSet<MusicPlaylist> MusicPlaylists { get; set; } public DbSet<MusicPlaylist> MusicPlaylists { get; set; }
public DbSet<CustomReaction> Expressions { get; set; } public DbSet<NadekoExpression> Expressions { get; set; }
public DbSet<CurrencyTransaction> CurrencyTransactions { get; set; } public DbSet<CurrencyTransaction> CurrencyTransactions { get; set; }
public DbSet<WaifuUpdate> WaifuUpdates { get; set; } public DbSet<WaifuUpdate> WaifuUpdates { get; set; }
public DbSet<Warning> Warnings { get; set; } public DbSet<Warning> Warnings { get; set; }

View File

@@ -29,7 +29,7 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("ClubApplicants"); b.ToTable("ClubApplicants", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.ClubBans", b => modelBuilder.Entity("NadekoBot.Db.Models.ClubBans", b =>
@@ -44,7 +44,7 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("ClubBans"); b.ToTable("ClubBans", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.ClubInfo", b => modelBuilder.Entity("NadekoBot.Db.Models.ClubInfo", b =>
@@ -86,7 +86,7 @@ namespace NadekoBot.Migrations
b.HasIndex("OwnerId") b.HasIndex("OwnerId")
.IsUnique(); .IsUnique();
b.ToTable("Clubs"); b.ToTable("Clubs", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.DiscordUser", b => modelBuilder.Entity("NadekoBot.Db.Models.DiscordUser", b =>
@@ -151,7 +151,7 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("DiscordUser"); b.ToTable("DiscordUser", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b => modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b =>
@@ -185,7 +185,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("FollowedStream"); b.ToTable("FollowedStream", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiAltSetting", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiAltSetting", b =>
@@ -214,7 +214,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId") b.HasIndex("GuildConfigId")
.IsUnique(); .IsUnique();
b.ToTable("AntiAltSetting"); b.ToTable("AntiAltSetting", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b =>
@@ -246,7 +246,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId") b.HasIndex("GuildConfigId")
.IsUnique(); .IsUnique();
b.ToTable("AntiRaidSetting"); b.ToTable("AntiRaidSetting", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamIgnore", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamIgnore", b =>
@@ -268,7 +268,7 @@ namespace NadekoBot.Migrations
b.HasIndex("AntiSpamSettingId"); b.HasIndex("AntiSpamSettingId");
b.ToTable("AntiSpamIgnore"); b.ToTable("AntiSpamIgnore", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamSetting", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamSetting", b =>
@@ -300,7 +300,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId") b.HasIndex("GuildConfigId")
.IsUnique(); .IsUnique();
b.ToTable("AntiSpamSetting"); b.ToTable("AntiSpamSetting", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoCommand", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoCommand", b =>
@@ -338,7 +338,7 @@ namespace NadekoBot.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("AutoCommands"); b.ToTable("AutoCommands", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateChannel", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateChannel", b =>
@@ -366,7 +366,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId"); b.HasIndex("GuildId");
b.ToTable("AutoTranslateChannels"); b.ToTable("AutoTranslateChannels", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateUser", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateUser", b =>
@@ -394,7 +394,7 @@ namespace NadekoBot.Migrations
b.HasAlternateKey("ChannelId", "UserId"); b.HasAlternateKey("ChannelId", "UserId");
b.ToTable("AutoTranslateUsers"); b.ToTable("AutoTranslateUsers", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.BanTemplate", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.BanTemplate", b =>
@@ -417,7 +417,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId") b.HasIndex("GuildId")
.IsUnique(); .IsUnique();
b.ToTable("BanTemplates"); b.ToTable("BanTemplates", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistEntry", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistEntry", b =>
@@ -437,7 +437,7 @@ namespace NadekoBot.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("Blacklist"); b.ToTable("Blacklist", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandAlias", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandAlias", b =>
@@ -462,7 +462,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("CommandAlias"); b.ToTable("CommandAlias", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b =>
@@ -487,7 +487,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("CommandCooldown"); b.ToTable("CommandCooldown", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.CurrencyTransaction", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.CurrencyTransaction", b =>
@@ -512,7 +512,7 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("CurrencyTransactions"); b.ToTable("CurrencyTransactions", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.CustomReaction", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.CustomReaction", b =>
@@ -550,7 +550,7 @@ namespace NadekoBot.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("Expressions"); b.ToTable("Expressions", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.DelMsgOnCmdChannel", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.DelMsgOnCmdChannel", b =>
@@ -575,7 +575,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("DelMsgOnCmdChannel"); b.ToTable("DelMsgOnCmdChannel", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.DiscordPermOverride", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.DiscordPermOverride", b =>
@@ -601,7 +601,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId", "Command") b.HasIndex("GuildId", "Command")
.IsUnique(); .IsUnique();
b.ToTable("DiscordPermOverrides"); b.ToTable("DiscordPermOverrides", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.ExcludedItem", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.ExcludedItem", b =>
@@ -626,7 +626,7 @@ namespace NadekoBot.Migrations
b.HasIndex("XpSettingsId"); b.HasIndex("XpSettingsId");
b.ToTable("ExcludedItem"); b.ToTable("ExcludedItem", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.FeedSub", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.FeedSub", b =>
@@ -652,7 +652,7 @@ namespace NadekoBot.Migrations
b.HasAlternateKey("GuildConfigId", "Url"); b.HasAlternateKey("GuildConfigId", "Url");
b.ToTable("FeedSub"); b.ToTable("FeedSub", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b =>
@@ -679,7 +679,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId1"); b.HasIndex("GuildConfigId1");
b.ToTable("FilterChannelId"); b.ToTable("FilterChannelId", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b =>
@@ -701,7 +701,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("FilteredWord"); b.ToTable("FilteredWord", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterLinksChannelId", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterLinksChannelId", b =>
@@ -723,7 +723,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("FilterLinksChannelId"); b.ToTable("FilterLinksChannelId", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b =>
@@ -745,7 +745,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("GCChannelId"); b.ToTable("GCChannelId", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.GroupName", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.GroupName", b =>
@@ -771,7 +771,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId", "Number") b.HasIndex("GuildConfigId", "Number")
.IsUnique(); .IsUnique();
b.ToTable("GroupName"); b.ToTable("GroupName", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
@@ -901,7 +901,7 @@ namespace NadekoBot.Migrations
b.HasIndex("WarnExpireHours"); b.HasIndex("WarnExpireHours");
b.ToTable("GuildConfigs"); b.ToTable("GuildConfigs", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogItem", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogItem", b =>
@@ -927,7 +927,7 @@ namespace NadekoBot.Migrations
b.HasIndex("LogSettingId", "LogItemId", "ItemType") b.HasIndex("LogSettingId", "LogItemId", "ItemType")
.IsUnique(); .IsUnique();
b.ToTable("IgnoredLogChannels"); b.ToTable("IgnoredLogChannels", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
@@ -949,7 +949,7 @@ namespace NadekoBot.Migrations
b.HasIndex("LogSettingId"); b.HasIndex("LogSettingId");
b.ToTable("IgnoredVoicePresenceCHannels"); b.ToTable("IgnoredVoicePresenceCHannels", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.ImageOnlyChannel", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.ImageOnlyChannel", b =>
@@ -972,7 +972,7 @@ namespace NadekoBot.Migrations
b.HasIndex("ChannelId") b.HasIndex("ChannelId")
.IsUnique(); .IsUnique();
b.ToTable("ImageOnlyChannels"); b.ToTable("ImageOnlyChannels", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b =>
@@ -1037,7 +1037,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId") b.HasIndex("GuildId")
.IsUnique(); .IsUnique();
b.ToTable("LogSettings"); b.ToTable("LogSettings", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlayerSettings", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlayerSettings", b =>
@@ -1071,7 +1071,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId") b.HasIndex("GuildId")
.IsUnique(); .IsUnique();
b.ToTable("MusicPlayerSettings"); b.ToTable("MusicPlayerSettings", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlaylist", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlaylist", b =>
@@ -1094,7 +1094,7 @@ namespace NadekoBot.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("MusicPlaylists"); b.ToTable("MusicPlaylists", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b =>
@@ -1116,7 +1116,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("MutedUserId"); b.ToTable("MutedUserId", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.NsfwBlacklistedTag", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.NsfwBlacklistedTag", b =>
@@ -1138,7 +1138,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId"); b.HasIndex("GuildId");
b.ToTable("NsfwBlacklistedTags"); b.ToTable("NsfwBlacklistedTags", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.Permissionv2", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.Permissionv2", b =>
@@ -1178,7 +1178,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("Permissions"); b.ToTable("Permissions", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlantedCurrency", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.PlantedCurrency", b =>
@@ -1215,7 +1215,7 @@ namespace NadekoBot.Migrations
b.HasIndex("MessageId") b.HasIndex("MessageId")
.IsUnique(); .IsUnique();
b.ToTable("PlantedCurrency"); b.ToTable("PlantedCurrency", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b =>
@@ -1249,7 +1249,7 @@ namespace NadekoBot.Migrations
b.HasIndex("MusicPlaylistId"); b.HasIndex("MusicPlaylistId");
b.ToTable("PlaylistSong"); b.ToTable("PlaylistSong", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.Poll", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.Poll", b =>
@@ -1275,7 +1275,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId") b.HasIndex("GuildId")
.IsUnique(); .IsUnique();
b.ToTable("Poll"); b.ToTable("Poll", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.PollAnswer", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.PollAnswer", b =>
@@ -1300,7 +1300,7 @@ namespace NadekoBot.Migrations
b.HasIndex("PollId"); b.HasIndex("PollId");
b.ToTable("PollAnswer"); b.ToTable("PollAnswer", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.PollVote", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.PollVote", b =>
@@ -1325,7 +1325,7 @@ namespace NadekoBot.Migrations
b.HasIndex("PollId"); b.HasIndex("PollId");
b.ToTable("PollVote"); b.ToTable("PollVote", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b =>
@@ -1361,7 +1361,7 @@ namespace NadekoBot.Migrations
b.HasIndex("Keyword"); b.HasIndex("Keyword");
b.ToTable("Quotes"); b.ToTable("Quotes", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.ReactionRole", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.ReactionRole", b =>
@@ -1386,7 +1386,7 @@ namespace NadekoBot.Migrations
b.HasIndex("ReactionRoleMessageId"); b.HasIndex("ReactionRoleMessageId");
b.ToTable("ReactionRole"); b.ToTable("ReactionRole", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.ReactionRoleMessage", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.ReactionRoleMessage", b =>
@@ -1417,7 +1417,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("ReactionRoleMessage"); b.ToTable("ReactionRoleMessage", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b =>
@@ -1451,7 +1451,7 @@ namespace NadekoBot.Migrations
b.HasIndex("When"); b.HasIndex("When");
b.ToTable("Reminders"); b.ToTable("Reminders", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.Repeater", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.Repeater", b =>
@@ -1486,7 +1486,7 @@ namespace NadekoBot.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("Repeaters"); b.ToTable("Repeaters", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.RewardedUser", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.RewardedUser", b =>
@@ -1515,7 +1515,7 @@ namespace NadekoBot.Migrations
b.HasIndex("PatreonUserId") b.HasIndex("PatreonUserId")
.IsUnique(); .IsUnique();
b.ToTable("RewardedUsers"); b.ToTable("RewardedUsers", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.RotatingPlayingStatus", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.RotatingPlayingStatus", b =>
@@ -1535,7 +1535,7 @@ namespace NadekoBot.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.ToTable("RotatingStatus"); b.ToTable("RotatingStatus", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b =>
@@ -1566,7 +1566,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildId", "RoleId") b.HasIndex("GuildId", "RoleId")
.IsUnique(); .IsUnique();
b.ToTable("SelfAssignableRoles"); b.ToTable("SelfAssignableRoles", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntry", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntry", b =>
@@ -1606,7 +1606,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("ShopEntry"); b.ToTable("ShopEntry", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b =>
@@ -1628,7 +1628,7 @@ namespace NadekoBot.Migrations
b.HasIndex("ShopEntryId"); b.HasIndex("ShopEntryId");
b.ToTable("ShopEntryItem"); b.ToTable("ShopEntryItem", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b =>
@@ -1650,7 +1650,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("SlowmodeIgnoredRole"); b.ToTable("SlowmodeIgnoredRole", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b =>
@@ -1672,7 +1672,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("SlowmodeIgnoredUser"); b.ToTable("SlowmodeIgnoredUser", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleBlacklistedUser", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleBlacklistedUser", b =>
@@ -1697,7 +1697,7 @@ namespace NadekoBot.Migrations
b.HasIndex("StreamRoleSettingsId"); b.HasIndex("StreamRoleSettingsId");
b.ToTable("StreamRoleBlacklistedUser"); b.ToTable("StreamRoleBlacklistedUser", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b =>
@@ -1729,7 +1729,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId") b.HasIndex("GuildConfigId")
.IsUnique(); .IsUnique();
b.ToTable("StreamRoleSettings"); b.ToTable("StreamRoleSettings", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleWhitelistedUser", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleWhitelistedUser", b =>
@@ -1754,7 +1754,7 @@ namespace NadekoBot.Migrations
b.HasIndex("StreamRoleSettingsId"); b.HasIndex("StreamRoleSettingsId");
b.ToTable("StreamRoleWhitelistedUser"); b.ToTable("StreamRoleWhitelistedUser", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.UnbanTimer", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.UnbanTimer", b =>
@@ -1779,7 +1779,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("UnbanTimer"); b.ToTable("UnbanTimer", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b =>
@@ -1804,7 +1804,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("UnmuteTimer"); b.ToTable("UnmuteTimer", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.UnroleTimer", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.UnroleTimer", b =>
@@ -1832,7 +1832,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("UnroleTimer"); b.ToTable("UnroleTimer", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.UserXpStats", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.UserXpStats", b =>
@@ -1877,7 +1877,7 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId", "GuildId") b.HasIndex("UserId", "GuildId")
.IsUnique(); .IsUnique();
b.ToTable("UserXpStats"); b.ToTable("UserXpStats", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.VcRoleInfo", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.VcRoleInfo", b =>
@@ -1902,7 +1902,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("VcRoleInfo"); b.ToTable("VcRoleInfo", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b =>
@@ -1937,7 +1937,7 @@ namespace NadekoBot.Migrations
b.HasIndex("WaifuId") b.HasIndex("WaifuId")
.IsUnique(); .IsUnique();
b.ToTable("WaifuInfo"); b.ToTable("WaifuInfo", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuItem", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuItem", b =>
@@ -1962,7 +1962,7 @@ namespace NadekoBot.Migrations
b.HasIndex("WaifuInfoId"); b.HasIndex("WaifuInfoId");
b.ToTable("WaifuItem"); b.ToTable("WaifuItem", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuUpdate", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuUpdate", b =>
@@ -1994,7 +1994,7 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("WaifuUpdates"); b.ToTable("WaifuUpdates", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.Warning", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.Warning", b =>
@@ -2037,7 +2037,7 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("Warnings"); b.ToTable("Warnings", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.WarningPunishment", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.WarningPunishment", b =>
@@ -2068,7 +2068,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId"); b.HasIndex("GuildConfigId");
b.ToTable("WarningPunishment"); b.ToTable("WarningPunishment", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.XpCurrencyReward", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.XpCurrencyReward", b =>
@@ -2093,7 +2093,7 @@ namespace NadekoBot.Migrations
b.HasIndex("XpSettingsId"); b.HasIndex("XpSettingsId");
b.ToTable("XpCurrencyReward"); b.ToTable("XpCurrencyReward", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.XpRoleReward", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.XpRoleReward", b =>
@@ -2122,7 +2122,7 @@ namespace NadekoBot.Migrations
b.HasIndex("XpSettingsId", "Level") b.HasIndex("XpSettingsId", "Level")
.IsUnique(); .IsUnique();
b.ToTable("XpRoleReward"); b.ToTable("XpRoleReward", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Services.Database.Models.XpSettings", b => modelBuilder.Entity("NadekoBot.Services.Database.Models.XpSettings", b =>
@@ -2145,7 +2145,7 @@ namespace NadekoBot.Migrations
b.HasIndex("GuildConfigId") b.HasIndex("GuildConfigId")
.IsUnique(); .IsUnique();
b.ToTable("XpSettings"); b.ToTable("XpSettings", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.ClubApplicants", b => modelBuilder.Entity("NadekoBot.Db.Models.ClubApplicants", b =>

View File

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

View File

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

View File

@@ -1,52 +1,65 @@
#nullable disable #nullable disable
namespace NadekoBot.Modules.Administration; namespace NadekoBot.Modules.Administration;
public sealed class UserSpamStats : IDisposable public sealed class UserSpamStats
{ {
public int Count 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 object _applyLock = new();
private readonly TimeSpan _maxTime = TimeSpan.FromMinutes(30);
public UserSpamStats(IUserMessage msg) public UserSpamStats(IUserMessage msg)
{ {
LastMessage = msg.Content.ToUpperInvariant(); lastMessage = msg.Content.ToUpperInvariant();
timers = new(); _messageTracker = new();
ApplyNextMessage(msg); ApplyNextMessage(msg);
} }
public void ApplyNextMessage(IUserMessage message) public void ApplyNextMessage(IUserMessage message)
{ {
var upperMsg = message.Content.ToUpperInvariant();
lock (_applyLock) 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; // if it's a new message, reset spam counter
while (timers.TryDequeue(out var old)) lastMessage = upperMsg;
old.Change(Timeout.Infinite, Timeout.Infinite); _messageTracker.Clear();
} }
var t = new Timer(_ => _messageTracker.Enqueue(DateTime.UtcNow);
{
if (timers.TryDequeue(out var old))
old.Change(Timeout.Infinite, Timeout.Infinite);
},
null,
TimeSpan.FromMinutes(30),
TimeSpan.FromMinutes(30));
timers.Enqueue(t);
} }
} }
public void Dispose() private void Cleanup()
{ {
while (timers.TryDequeue(out var old)) lock (_applyLock)
old.Change(Timeout.Infinite, Timeout.Infinite); {
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 = private ImmutableDictionary<ulong, IDMChannel> ownerChannels =
new Dictionary<ulong, IDMChannel>().ToImmutableDictionary(); 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 IImageCache _imgs;
private readonly IHttpClientFactory _httpFactory; private readonly IHttpClientFactory _httpFactory;
@@ -75,12 +75,12 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
if (server.OwnerId != _client.CurrentUser.Id) if (server.OwnerId != _client.CurrentUser.Id)
{ {
await server.LeaveAsync(); await server.LeaveAsync();
Log.Information($"Left server {server.Name} [{server.Id}]"); Log.Information("Left server {Name} [{Id}]", server.Name, server.Id);
} }
else else
{ {
await server.DeleteAsync(); 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(); await using var uow = _db.GetDbContext();
_autoCommands = uow.AutoCommands.AsNoTracking() autoCommands = uow.AutoCommands.AsNoTracking()
.Where(x => x.Interval >= 5) .Where(x => x.Interval >= 5)
.AsEnumerable() .AsEnumerable()
.GroupBy(x => x.GuildId) .GroupBy(x => x.GuildId)
@@ -145,7 +145,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
if (cmd.Interval >= 5) 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, autos.AddOrUpdate(cmd.Id,
_ => TimerFromAutoCommand(cmd), _ => TimerFromAutoCommand(cmd),
(_, old) => (_, old) =>
@@ -185,9 +185,9 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
if (!ownerChannels.Any()) if (!ownerChannels.Any())
Log.Warning( 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 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) public Task LeaveGuild(string guildStr)
@@ -220,7 +220,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
} }
catch 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 else
@@ -262,7 +262,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
if (cmd is not null) if (cmd is not null)
{ {
uow.Remove(cmd); 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)) if (autos.TryRemove(cmd.Id, out var timer))
timer.Change(Timeout.Infinite, Timeout.Infinite); timer.Change(Timeout.Infinite, Timeout.Infinite);
uow.SaveChanges(); uow.SaveChanges();

View File

@@ -86,7 +86,7 @@ public partial class Administration
} }
catch (Exception ex) 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)); var errorEmbed = _eb.Create().WithErrorColor().WithDescription(GetText(strs.cant_apply_punishment));
if (dmFailed) errorEmbed.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user)); 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 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) if (bun is null)
{ {

View File

@@ -162,7 +162,9 @@ public class UserPunishService : INService
} }
else 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; 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));"); AND DateAdded < datetime('now', (SELECT '-' || WarnExpireHours || ' hours' FROM GuildConfigs as gc WHERE gc.GuildId = Warnings.GuildId));");
if (cleared > 0 || deleted > 0) 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) public async Task CheckWarnExpiresAsync(ulong guildId)
@@ -305,7 +309,8 @@ WHERE GuildId={guildId}
IRole role = null) IRole role = null)
{ {
// these 3 don't make sense with time // 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; return false;
if (number <= 0 || (time is not null && time.Time > TimeSpan.FromDays(49))) if (number <= 0 || (time is not null && time.Time > TimeSpan.FromDays(49)))
return false; return false;

View File

@@ -13,7 +13,7 @@ public class ExportedExpr
public bool Ca { get; set; } public bool Ca { get; set; }
public string[] React; public string[] React;
public static ExportedExpr FromModel(CustomReaction cr) public static ExportedExpr FromModel(NadekoExpression cr)
=> new() => new()
{ {
Res = cr.Response, Res = cr.Response,

View File

@@ -10,7 +10,7 @@ public static class NadekoExpressionExtensions
=> str.Replace("%bot.mention%", client.CurrentUser.Mention, StringComparison.Ordinal); => str.Replace("%bot.mention%", client.CurrentUser.Mention, StringComparison.Ordinal);
public static async Task<IUserMessage> Send( public static async Task<IUserMessage> Send(
this CustomReaction cr, this NadekoExpression cr,
IUserMessage ctx, IUserMessage ctx,
DiscordSocketClient client, DiscordSocketClient client,
bool sanitize) bool sanitize)

View File

@@ -46,17 +46,17 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
private readonly object _gexprWriteLock = new(); private readonly object _gexprWriteLock = new();
private readonly TypedKey<CustomReaction> _gexprAddedKey = new("gexpr.added"); private readonly TypedKey<NadekoExpression> _gexprAddedKey = new("gexpr.added");
private readonly TypedKey<int> _gexprDeletedkey = new("gexpr.deleted"); private readonly TypedKey<int> _gexprDeletedkey = new("gexpr.deleted");
private readonly TypedKey<CustomReaction> _gexprEditedKey = new("gexpr.edited"); private readonly TypedKey<NadekoExpression> _gexprEditedKey = new("gexpr.edited");
private readonly TypedKey<bool> _exprsReloadedKey = new("exprs.reloaded"); private readonly TypedKey<bool> _exprsReloadedKey = new("exprs.reloaded");
// it is perfectly fine to have global expressions as an array // it is perfectly fine to have global expressions as an array
// 1. expressions are almost never added (compared to how many times they are being looped through) // 1. expressions are almost never added (compared to how many times they are being looped through)
// 2. only need write locks for this as we'll rebuild+replace the array on every edit // 2. only need write locks for this as we'll rebuild+replace the array on every edit
// 3. there's never many of them (at most a thousand, usually < 100) // 3. there's never many of them (at most a thousand, usually < 100)
private CustomReaction[] globalReactions; private NadekoExpression[] globalReactions;
private ConcurrentDictionary<ulong, CustomReaction[]> newGuildReactions; private ConcurrentDictionary<ulong, NadekoExpression[]> newGuildReactions;
private readonly DbService _db; private readonly DbService _db;
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
@@ -140,7 +140,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
ready = true; ready = true;
} }
private CustomReaction TryGetExpression(IUserMessage umsg) private NadekoExpression TryGetExpression(IUserMessage umsg)
{ {
if (!ready) if (!ready)
return null; return null;
@@ -163,9 +163,9 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private CustomReaction MatchExpressions(in ReadOnlySpan<char> content, CustomReaction[] exprs) private NadekoExpression MatchExpressions(in ReadOnlySpan<char> content, NadekoExpression[] exprs)
{ {
var result = new List<CustomReaction>(1); var result = new List<NadekoExpression>(1);
for (var i = 0; i < exprs.Length; i++) for (var i = 0; i < exprs.Length; i++)
{ {
var expr = exprs[i]; var expr = exprs[i];
@@ -248,19 +248,19 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
{ {
if (pc.Verbose) if (pc.Verbose)
{ {
var returnMsg = _strings.GetText(strs.perm_prevent(index + 1, var permissionMessage = _strings.GetText(strs.perm_prevent(index + 1,
Format.Bold(pc.Permissions[index].GetCommand(_cmd.GetPrefix(guild), sg))), Format.Bold(pc.Permissions[index].GetCommand(_cmd.GetPrefix(guild), sg))),
sg.Id); sg.Id);
try try
{ {
await msg.Channel.SendErrorAsync(_eb, returnMsg); await msg.Channel.SendErrorAsync(_eb, permissionMessage);
} }
catch catch
{ {
} }
Log.Information(returnMsg); Log.Information("{PermissionMessage}", permissionMessage);
} }
return true; return true;
@@ -307,7 +307,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Warning(ex.Message); Log.Warning(ex, "Error in Expression RunBehavior: {ErrorMessage}", ex.Message);
} }
return false; return false;
@@ -315,7 +315,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
public async Task ResetExprReactions(ulong? maybeGuildId, int id) public async Task ResetExprReactions(ulong? maybeGuildId, int id)
{ {
CustomReaction expr; NadekoExpression expr;
await using var uow = _db.GetDbContext(); await using var uow = _db.GetDbContext();
expr = uow.Expressions.GetById(id); expr = uow.Expressions.GetById(id);
if (expr is null) if (expr is null)
@@ -326,7 +326,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
await uow.SaveChangesAsync(); await uow.SaveChangesAsync();
} }
private Task UpdateInternalAsync(ulong? maybeGuildId, CustomReaction expr) private Task UpdateInternalAsync(ulong? maybeGuildId, NadekoExpression expr)
{ {
if (maybeGuildId is { } guildId) if (maybeGuildId is { } guildId)
UpdateInternal(guildId, expr); UpdateInternal(guildId, expr);
@@ -336,7 +336,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
return Task.CompletedTask; return Task.CompletedTask;
} }
private void UpdateInternal(ulong? maybeGuildId, CustomReaction expr) private void UpdateInternal(ulong? maybeGuildId, NadekoExpression expr)
{ {
if (maybeGuildId is { } guildId) if (maybeGuildId is { } guildId)
newGuildReactions.AddOrUpdate(guildId, newGuildReactions.AddOrUpdate(guildId,
@@ -359,7 +359,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
} }
} }
private Task AddInternalAsync(ulong? maybeGuildId, CustomReaction expr) private Task AddInternalAsync(ulong? maybeGuildId, NadekoExpression expr)
{ {
// only do this for perf purposes // only do this for perf purposes
expr.Trigger = expr.Trigger.Replace(MENTION_PH, _client.CurrentUser.Mention); expr.Trigger = expr.Trigger.Replace(MENTION_PH, _client.CurrentUser.Mention);
@@ -377,7 +377,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
if (maybeGuildId is { } guildId) if (maybeGuildId is { } guildId)
{ {
newGuildReactions.AddOrUpdate(guildId, newGuildReactions.AddOrUpdate(guildId,
Array.Empty<CustomReaction>(), Array.Empty<NadekoExpression>(),
(key, old) => DeleteInternal(old, id, out _)); (key, old) => DeleteInternal(old, id, out _));
return Task.CompletedTask; return Task.CompletedTask;
@@ -392,16 +392,16 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
return Task.CompletedTask; return Task.CompletedTask;
} }
private CustomReaction[] DeleteInternal( private NadekoExpression[] DeleteInternal(
IReadOnlyList<CustomReaction> exprs, IReadOnlyList<NadekoExpression> exprs,
int id, int id,
out CustomReaction deleted) out NadekoExpression deleted)
{ {
deleted = null; deleted = null;
if (exprs is null || exprs.Count == 0) if (exprs is null || exprs.Count == 0)
return exprs as CustomReaction[] ?? exprs?.ToArray(); return exprs as NadekoExpression[] ?? exprs?.ToArray();
var newExprs = new CustomReaction[exprs.Count - 1]; var newExprs = new NadekoExpression[exprs.Count - 1];
for (int i = 0, k = 0; i < exprs.Count; i++, k++) for (int i = 0, k = 0; i < exprs.Count; i++, k++)
{ {
if (exprs[i].Id == id) if (exprs[i].Id == id)
@@ -419,7 +419,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
public async Task SetExprReactions(ulong? guildId, int id, IEnumerable<string> emojis) public async Task SetExprReactions(ulong? guildId, int id, IEnumerable<string> emojis)
{ {
CustomReaction expr; NadekoExpression expr;
await using (var uow = _db.GetDbContext()) await using (var uow = _db.GetDbContext())
{ {
expr = uow.Expressions.GetById(id); expr = uow.Expressions.GetById(id);
@@ -437,7 +437,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
public async Task<(bool Sucess, bool NewValue)> ToggleExprOptionAsync(int id, ExprField field) public async Task<(bool Sucess, bool NewValue)> ToggleExprOptionAsync(int id, ExprField field)
{ {
var newVal = false; var newVal = false;
CustomReaction expr; NadekoExpression expr;
await using (var uow = _db.GetDbContext()) await using (var uow = _db.GetDbContext())
{ {
expr = uow.Expressions.GetById(id); expr = uow.Expressions.GetById(id);
@@ -460,7 +460,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
return (true, newVal); return (true, newVal);
} }
public CustomReaction GetExpression(ulong? guildId, int id) public NadekoExpression GetExpression(ulong? guildId, int id)
{ {
using var uow = _db.GetDbContext(); using var uow = _db.GetDbContext();
var expr = uow.Expressions.GetById(id); var expr = uow.Expressions.GetById(id);
@@ -516,7 +516,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
{ {
var trigger = entry.Key; var trigger = entry.Key;
await uow.Expressions.AddRangeAsync(entry.Value.Where(expr => !string.IsNullOrWhiteSpace(expr.Res)) await uow.Expressions.AddRangeAsync(entry.Value.Where(expr => !string.IsNullOrWhiteSpace(expr.Res))
.Select(expr => new CustomReaction .Select(expr => new NadekoExpression
{ {
GuildId = guildId, GuildId = guildId,
Response = expr.Res, Response = expr.Res,
@@ -542,11 +542,11 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
private ValueTask OnExprsShouldReload(bool _) private ValueTask OnExprsShouldReload(bool _)
=> new(ReloadInternal(_bot.GetCurrentGuildIds())); => new(ReloadInternal(_bot.GetCurrentGuildIds()));
private ValueTask OnGexprAdded(CustomReaction c) private ValueTask OnGexprAdded(NadekoExpression c)
{ {
lock (_gexprWriteLock) lock (_gexprWriteLock)
{ {
var newGlobalReactions = new CustomReaction[globalReactions.Length + 1]; var newGlobalReactions = new NadekoExpression[globalReactions.Length + 1];
Array.Copy(globalReactions, newGlobalReactions, globalReactions.Length); Array.Copy(globalReactions, newGlobalReactions, globalReactions.Length);
newGlobalReactions[globalReactions.Length] = c; newGlobalReactions[globalReactions.Length] = c;
globalReactions = newGlobalReactions; globalReactions = newGlobalReactions;
@@ -555,7 +555,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
return default; return default;
} }
private ValueTask OnGexprEdited(CustomReaction c) private ValueTask OnGexprEdited(NadekoExpression c)
{ {
lock (_gexprWriteLock) lock (_gexprWriteLock)
{ {
@@ -611,10 +611,10 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
#region Basic Operations #region Basic Operations
public async Task<CustomReaction> AddAsync(ulong? guildId, string key, string message) public async Task<NadekoExpression> AddAsync(ulong? guildId, string key, string message)
{ {
key = key.ToLowerInvariant(); key = key.ToLowerInvariant();
var expr = new CustomReaction { GuildId = guildId, Trigger = key, Response = message }; var expr = new NadekoExpression { GuildId = guildId, Trigger = key, Response = message };
if (expr.Response.Contains("%target%", StringComparison.OrdinalIgnoreCase)) if (expr.Response.Contains("%target%", StringComparison.OrdinalIgnoreCase))
expr.AllowTarget = true; expr.AllowTarget = true;
@@ -630,7 +630,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
return expr; return expr;
} }
public async Task<CustomReaction> EditAsync(ulong? guildId, int id, string message) public async Task<NadekoExpression> EditAsync(ulong? guildId, int id, string message)
{ {
await using var uow = _db.GetDbContext(); await using var uow = _db.GetDbContext();
var expr = uow.Expressions.GetById(id); var expr = uow.Expressions.GetById(id);
@@ -656,7 +656,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
} }
public async Task<CustomReaction> DeleteAsync(ulong? guildId, int id) public async Task<NadekoExpression> DeleteAsync(ulong? guildId, int id)
{ {
await using var uow = _db.GetDbContext(); await using var uow = _db.GetDbContext();
var toDelete = uow.Expressions.GetById(id); var toDelete = uow.Expressions.GetById(id);
@@ -676,10 +676,10 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public CustomReaction[] GetExpressionsFor(ulong? maybeGuildId) public NadekoExpression[] GetExpressionsFor(ulong? maybeGuildId)
{ {
if (maybeGuildId is { } guildId) if (maybeGuildId is { } guildId)
return newGuildReactions.TryGetValue(guildId, out var exprs) ? exprs : Array.Empty<CustomReaction>(); return newGuildReactions.TryGetValue(guildId, out var exprs) ? exprs : Array.Empty<NadekoExpression>();
return globalReactions; return globalReactions;
} }

View File

@@ -56,8 +56,9 @@ public partial class Gambling
if (await bj.Join(ctx.User, amount)) if (await bj.Join(ctx.User, amount))
await ReplyConfirmLocalizedAsync(strs.bj_joined); await ReplyConfirmLocalizedAsync(strs.bj_joined);
else else
Log.Information( Log.Information("{User} can't join a blackjack game as it's in {BlackjackState} state already",
$"{ctx.User} can't join a blackjack game as it's in " + bj.State + " state already."); ctx.User,
bj.State);
} }
await ctx.Message.DeleteAsync(); await ctx.Message.DeleteAsync();

View File

@@ -25,7 +25,7 @@ public class Blackjack
private readonly ICurrencyService _cs; private readonly ICurrencyService _cs;
private readonly DbService _db; private readonly DbService _db;
private readonly SemaphoreSlim locker = new(1, 1); private readonly SemaphoreSlim _locker = new(1, 1);
public Blackjack(ICurrencyService cs, DbService db) public Blackjack(ICurrencyService cs, DbService db)
{ {
@@ -45,14 +45,14 @@ public class Blackjack
{ {
//wait for players to join //wait for players to join
await Task.Delay(20000); await Task.Delay(20000);
await locker.WaitAsync(); await _locker.WaitAsync();
try try
{ {
State = GameState.Playing; State = GameState.Playing;
} }
finally finally
{ {
locker.Release(); _locker.Release();
} }
await PrintState(); await PrintState();
@@ -79,7 +79,7 @@ public class Blackjack
foreach (var usr in Players.Where(x => !x.Done)) foreach (var usr in Players.Where(x => !x.Done))
while (!usr.Done) while (!usr.Done)
{ {
Log.Information($"Waiting for {usr.DiscordUser}'s move"); Log.Information("Waiting for {DiscordUser}'s move", usr.DiscordUser);
await PromptUserMove(usr); await PromptUserMove(usr);
} }
@@ -115,7 +115,7 @@ public class Blackjack
public async Task<bool> Join(IUser user, long bet) public async Task<bool> Join(IUser user, long bet)
{ {
await locker.WaitAsync(); await _locker.WaitAsync();
try try
{ {
if (State != GameState.Starting) if (State != GameState.Starting)
@@ -132,7 +132,7 @@ public class Blackjack
} }
finally finally
{ {
locker.Release(); _locker.Release();
} }
} }
@@ -148,7 +148,7 @@ public class Blackjack
public async Task<bool> Stand(User u) public async Task<bool> Stand(User u)
{ {
await locker.WaitAsync(); await _locker.WaitAsync();
try try
{ {
if (State != GameState.Playing) if (State != GameState.Playing)
@@ -163,7 +163,7 @@ public class Blackjack
} }
finally finally
{ {
locker.Release(); _locker.Release();
} }
} }
@@ -229,7 +229,7 @@ public class Blackjack
public async Task<bool> Double(User u) public async Task<bool> Double(User u)
{ {
await locker.WaitAsync(); await _locker.WaitAsync();
try try
{ {
if (State != GameState.Playing) if (State != GameState.Playing)
@@ -260,7 +260,7 @@ public class Blackjack
} }
finally finally
{ {
locker.Release(); _locker.Release();
} }
} }
@@ -276,7 +276,7 @@ public class Blackjack
public async Task<bool> Hit(User u) public async Task<bool> Hit(User u)
{ {
await locker.WaitAsync(); await _locker.WaitAsync();
try try
{ {
if (State != GameState.Playing) if (State != GameState.Playing)
@@ -300,7 +300,7 @@ public class Blackjack
} }
finally finally
{ {
locker.Release(); _locker.Release();
} }
} }

View File

@@ -51,9 +51,12 @@ public class GamblingService : INService
if (DateTime.UtcNow - lastCurrencyDecay < TimeSpan.FromHours(config.Decay.HourInterval)) if (DateTime.UtcNow - lastCurrencyDecay < TimeSpan.FromHours(config.Decay.HourInterval))
return; return;
Log.Information($"Decaying users' currency - decay: {config.Decay.Percent * 100}% " Log.Information(@"Decaying users' currency - decay: {ConfigDecayPercent}%
+ $"| max: {maxDecay} " | max: {MaxDecay}
+ $"| threshold: {config.Decay.MinThreshold}"); | threshold: {DecayMinTreshold}",
config.Decay.Percent * 100,
maxDecay,
config.Decay.MinThreshold);
if (maxDecay == 0) if (maxDecay == 0)
maxDecay = int.MaxValue; maxDecay = int.MaxValue;

View File

@@ -116,7 +116,7 @@ public class ChatterBotService : IEarlyBehavior
try { await usrMsg.Channel.SendErrorAsync(_eb, returnMsg); } try { await usrMsg.Channel.SendErrorAsync(_eb, returnMsg); }
catch { } catch { }
Log.Information(returnMsg); Log.Information("{PermissionMessage}", returnMsg);
} }
return true; return true;
@@ -125,11 +125,19 @@ public class ChatterBotService : IEarlyBehavior
var cleverbotExecuted = await TryAsk(cbs, (ITextChannel)usrMsg.Channel, message); var cleverbotExecuted = await TryAsk(cbs, (ITextChannel)usrMsg.Channel, message);
if (cleverbotExecuted) if (cleverbotExecuted)
{ {
Log.Information($@"CleverBot Executed Log.Information(@"CleverBot Executed
Server: {guild.Name} [{guild.Id}] Server: {GuildName} [{GuildId}]
Channel: {usrMsg.Channel?.Name} [{usrMsg.Channel?.Id}] Channel: {ChannelName} [{ChannelId}]
UserId: {usrMsg.Author} [{usrMsg.Author.Id}] UserId: {Author} [{AuthorId}]
Message: {usrMsg.Content}"); Message: {Content}",
guild.Name,
guild.Id,
usrMsg.Channel?.Name,
usrMsg.Channel?.Id,
usrMsg.Author,
usrMsg.Author.Id,
usrMsg.Content);
return true; return true;
} }
} }

View File

@@ -31,8 +31,7 @@ public class OfficialCleverbotSession : IChatterBotSession
} }
catch catch
{ {
Log.Warning("Unexpected cleverbot response received: "); Log.Warning("Unexpected cleverbot response received: {ResponseString}", dataString);
Log.Warning(dataString);
return null; return null;
} }
} }

View File

@@ -11,8 +11,8 @@ public class TypingGame
public ITextChannel Channel { get; } public ITextChannel Channel { get; }
public string CurrentSentence { get; private set; } public string CurrentSentence { get; private set; }
public bool IsActive { get; private set; } public bool IsActive { get; private set; }
private readonly Stopwatch sw; private readonly Stopwatch _sw;
private readonly List<ulong> finishedUserIds; private readonly List<ulong> _finishedUserIds;
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly GamesService _games; private readonly GamesService _games;
private readonly string _prefix; private readonly string _prefix;
@@ -35,25 +35,24 @@ public class TypingGame
Channel = channel; Channel = channel;
IsActive = false; IsActive = false;
sw = new(); _sw = new();
finishedUserIds = new(); _finishedUserIds = new();
} }
public async Task<bool> Stop() public async Task<bool> Stop()
{ {
if (!IsActive) return false; if (!IsActive) return false;
_client.MessageReceived -= AnswerReceived; _client.MessageReceived -= AnswerReceived;
finishedUserIds.Clear(); _finishedUserIds.Clear();
IsActive = false; IsActive = false;
sw.Stop(); _sw.Stop();
sw.Reset(); _sw.Reset();
try try
{ {
await Channel.SendConfirmAsync(_eb, "Typing contest stopped."); await Channel.SendConfirmAsync(_eb, "Typing contest stopped.");
} }
catch (Exception ex) catch
{ {
Log.Warning(ex.ToString());
} }
return true; return true;
@@ -88,7 +87,7 @@ public class TypingGame
{ {
m.Content = CurrentSentence.Replace(" ", " \x200B", StringComparison.InvariantCulture); m.Content = CurrentSentence.Replace(" ", " \x200B", StringComparison.InvariantCulture);
}); });
sw.Start(); _sw.Start();
HandleAnswers(); HandleAnswers();
while (i > 0) while (i > 0)
@@ -133,19 +132,19 @@ public class TypingGame
var distance = CurrentSentence.LevenshteinDistance(guess); var distance = CurrentSentence.LevenshteinDistance(guess);
var decision = Judge(distance, guess.Length); var decision = Judge(distance, guess.Length);
if (decision && !finishedUserIds.Contains(msg.Author.Id)) if (decision && !_finishedUserIds.Contains(msg.Author.Id))
{ {
var elapsed = sw.Elapsed; var elapsed = _sw.Elapsed;
var wpm = CurrentSentence.Length / WORD_VALUE / elapsed.TotalSeconds * 60; var wpm = CurrentSentence.Length / WORD_VALUE / elapsed.TotalSeconds * 60;
finishedUserIds.Add(msg.Author.Id); _finishedUserIds.Add(msg.Author.Id);
await Channel.EmbedAsync(_eb.Create() await Channel.EmbedAsync(_eb.Create()
.WithOkColor() .WithOkColor()
.WithTitle($"{msg.Author} finished the race!") .WithTitle($"{msg.Author} finished the race!")
.AddField("Place", $"#{finishedUserIds.Count}", true) .AddField("Place", $"#{_finishedUserIds.Count}", true)
.AddField("WPM", $"{wpm:F1} *[{elapsed.TotalSeconds:F2}sec]*", true) .AddField("WPM", $"{wpm:F1} *[{elapsed.TotalSeconds:F2}sec]*", true)
.AddField("Errors", distance.ToString(), true)); .AddField("Errors", distance.ToString(), true));
if (finishedUserIds.Count % 4 == 0) if (_finishedUserIds.Count % 4 == 0)
await Channel.SendConfirmAsync(_eb, await Channel.SendConfirmAsync(_eb,
":exclamation: A lot of people finished, here is the text for those still typing:" ":exclamation: A lot of people finished, here is the text for those still typing:"
+ $"\n\n**{Format.Sanitize(CurrentSentence.Replace(" ", " \x200B", StringComparison.InvariantCulture)).SanitizeMentions(true)}**"); + $"\n\n**{Format.Sanitize(CurrentSentence.Replace(" ", " \x200B", StringComparison.InvariantCulture)).SanitizeMentions(true)}**");
@@ -153,7 +152,7 @@ public class TypingGame
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Warning(ex.ToString()); Log.Warning(ex, "Error receiving typing game answer: {ErrorMessage}", ex.Message);
} }
}); });
return Task.CompletedTask; return Task.CompletedTask;

View File

@@ -264,7 +264,7 @@ public class TriviaGame
embed.WithImageUrl(CurrentQuestion.AnswerImageUrl); embed.WithImageUrl(CurrentQuestion.AnswerImageUrl);
await Channel.EmbedAsync(embed); await Channel.EmbedAsync(embed);
} }
catch (Exception ex) { Log.Warning(ex.ToString()); } catch (Exception ex) { Log.Warning(ex, "Exception in a potential guess"); }
}); });
return Task.CompletedTask; return Task.CompletedTask;
} }

View File

@@ -5,10 +5,10 @@ namespace NadekoBot.Modules.Music.Resolvers;
public class RadioResolver : IRadioResolver public class RadioResolver : IRadioResolver
{ {
private readonly Regex plsRegex = new("File1=(?<url>.*?)\\n", RegexOptions.Compiled); private readonly Regex _plsRegex = new("File1=(?<url>.*?)\\n", RegexOptions.Compiled);
private readonly Regex m3uRegex = new("(?<url>^[^#].*)", RegexOptions.Compiled | RegexOptions.Multiline); private readonly Regex _m3URegex = new("(?<url>^[^#].*)", RegexOptions.Compiled | RegexOptions.Multiline);
private readonly Regex asxRegex = new("<ref href=\"(?<url>.*?)\"", RegexOptions.Compiled); private readonly Regex _asxRegex = new("<ref href=\"(?<url>.*?)\"", RegexOptions.Compiled);
private readonly Regex xspfRegex = new("<location>(?<url>.*?)</location>", RegexOptions.Compiled); private readonly Regex _xspfRegex = new("<location>(?<url>.*?)</location>", RegexOptions.Compiled);
public async Task<ITrackInfo> ResolveByQueryAsync(string query) public async Task<ITrackInfo> ResolveByQueryAsync(string query)
{ {
@@ -46,13 +46,13 @@ public class RadioResolver : IRadioResolver
//Regex.Match(query) //Regex.Match(query)
try try
{ {
var m = plsRegex.Match(file); var m = _plsRegex.Match(file);
var res = m.Groups["url"]?.ToString(); var res = m.Groups["url"]?.ToString();
return res?.Trim(); return res?.Trim();
} }
catch catch
{ {
Log.Warning($"Failed reading .pls:\n{file}"); Log.Warning("Failed reading .pls:\n{PlsFile}", file);
return null; return null;
} }
@@ -64,13 +64,13 @@ public class RadioResolver : IRadioResolver
*/ */
try try
{ {
var m = m3uRegex.Match(file); var m = _m3URegex.Match(file);
var res = m.Groups["url"]?.ToString(); var res = m.Groups["url"]?.ToString();
return res?.Trim(); return res?.Trim();
} }
catch catch
{ {
Log.Warning($"Failed reading .m3u:\n{file}"); Log.Warning("Failed reading .m3u:\n{M3uFile}", file);
return null; return null;
} }
@@ -78,13 +78,13 @@ public class RadioResolver : IRadioResolver
//<ref href="http://armitunes.com:8000"/> //<ref href="http://armitunes.com:8000"/>
try try
{ {
var m = asxRegex.Match(file); var m = _asxRegex.Match(file);
var res = m.Groups["url"]?.ToString(); var res = m.Groups["url"]?.ToString();
return res?.Trim(); return res?.Trim();
} }
catch catch
{ {
Log.Warning($"Failed reading .asx:\n{file}"); Log.Warning("Failed reading .asx:\n{AsxFile}", file);
return null; return null;
} }
@@ -97,13 +97,13 @@ public class RadioResolver : IRadioResolver
*/ */
try try
{ {
var m = xspfRegex.Match(file); var m = _xspfRegex.Match(file);
var res = m.Groups["url"]?.ToString(); var res = m.Groups["url"]?.ToString();
return res?.Trim(); return res?.Trim();
} }
catch catch
{ {
Log.Warning($"Failed reading .xspf:\n{file}"); Log.Warning("Failed reading .xspf:\n{XspfFile}", file);
return null; return null;
} }

View File

@@ -92,7 +92,8 @@ public sealed class FilterService : IEarlyBehavior
WordFilteringServers.TryRemove(guildId); WordFilteringServers.TryRemove(guildId);
ServerFilteredWords.TryRemove(guildId, out _); ServerFilteredWords.TryRemove(guildId, out _);
foreach (var c in gc.FilterWordsChannelIds) WordFilteringChannels.TryRemove(c.ChannelId); foreach (var c in gc.FilterWordsChannelIds)
WordFilteringChannels.TryRemove(c.ChannelId);
gc.FilterWords = false; gc.FilterWords = false;
gc.FilteredWords.Clear(); gc.FilteredWords.Clear();
@@ -131,7 +132,9 @@ public sealed class FilterService : IEarlyBehavior
var filteredServerWords = FilteredWordsForServer(guild.Id) ?? new ConcurrentHashSet<string>(); var filteredServerWords = FilteredWordsForServer(guild.Id) ?? new ConcurrentHashSet<string>();
var wordsInMessage = usrMsg.Content.ToLowerInvariant().Split(' '); var wordsInMessage = usrMsg.Content.ToLowerInvariant().Split(' ');
if (filteredChannelWords.Count != 0 || filteredServerWords.Count != 0) if (filteredChannelWords.Count != 0 || filteredServerWords.Count != 0)
{
foreach (var word in wordsInMessage) foreach (var word in wordsInMessage)
{
if (filteredChannelWords.Contains(word) || filteredServerWords.Contains(word)) if (filteredChannelWords.Contains(word) || filteredServerWords.Contains(word))
{ {
Log.Information("User {UserName} [{UserId}] used a filtered word in {ChannelId} channel", Log.Information("User {UserName} [{UserId}] used a filtered word in {ChannelId} channel",
@@ -145,12 +148,15 @@ public sealed class FilterService : IEarlyBehavior
} }
catch (HttpException ex) catch (HttpException ex)
{ {
Log.Warning("I do not have permission to filter words in channel with id " + usrMsg.Channel.Id, Log.Warning(ex,
ex); "I do not have permission to filter words in channel with id {Id}",
usrMsg.Channel.Id);
} }
return true; return true;
} }
}
}
return false; return false;
} }
@@ -177,7 +183,9 @@ public sealed class FilterService : IEarlyBehavior
} }
catch (HttpException ex) catch (HttpException ex)
{ {
Log.Warning("I do not have permission to filter invites in channel with id " + usrMsg.Channel.Id, ex); Log.Warning(ex,
"I do not have permission to filter invites in channel with id {Id}",
usrMsg.Channel.Id);
return true; return true;
} }
} }
@@ -207,7 +215,7 @@ public sealed class FilterService : IEarlyBehavior
} }
catch (HttpException ex) catch (HttpException ex)
{ {
Log.Warning("I do not have permission to filter links in channel with id " + usrMsg.Channel.Id, ex); Log.Warning(ex, "I do not have permission to filter links in channel with id {Id}", usrMsg.Channel.Id);
return true; return true;
} }
} }

View File

@@ -19,7 +19,7 @@ namespace NadekoBot.Modules.Searches;
public partial class Searches : NadekoModule<SearchesService> public partial class Searches : NadekoModule<SearchesService>
{ {
private static readonly ConcurrentDictionary<string, string> cachedShortenedLinks = new(); private static readonly ConcurrentDictionary<string, string> _cachedShortenedLinks = new();
private readonly IBotCredentials _creds; private readonly IBotCredentials _creds;
private readonly IGoogleApiService _google; private readonly IGoogleApiService _google;
private readonly IHttpClientFactory _httpFactory; private readonly IHttpClientFactory _httpFactory;
@@ -141,7 +141,7 @@ public partial class Searches : NadekoModule<SearchesService>
var eb = _eb.Create() var eb = _eb.Create()
.WithOkColor() .WithOkColor()
.WithTitle(GetText(strs.time_new)) .WithTitle(GetText(strs.time_new))
.WithDescription(Format.Code(data.Time.ToString())) .WithDescription(Format.Code(data.Time.ToString(Culture)))
.AddField(GetText(strs.location), string.Join('\n', data.Address.Split(", ")), true) .AddField(GetText(strs.location), string.Join('\n', data.Address.Split(", ")), true)
.AddField(GetText(strs.timezone), data.TimeZoneName, true); .AddField(GetText(strs.timezone), data.TimeZoneName, true);
@@ -282,20 +282,20 @@ public partial class Searches : NadekoModule<SearchesService>
return; return;
query = query.Trim(); query = query.Trim();
if (!cachedShortenedLinks.TryGetValue(query, out var shortLink)) if (!_cachedShortenedLinks.TryGetValue(query, out var shortLink))
try try
{ {
using var _http = _httpFactory.CreateClient(); using var http = _httpFactory.CreateClient();
using var req = new HttpRequestMessage(HttpMethod.Post, "https://goolnk.com/api/v1/shorten"); using var req = new HttpRequestMessage(HttpMethod.Post, "https://goolnk.com/api/v1/shorten");
var formData = new MultipartFormDataContent { { new StringContent(query), "url" } }; var formData = new MultipartFormDataContent { { new StringContent(query), "url" } };
req.Content = formData; req.Content = formData;
using var res = await _http.SendAsync(req); using var res = await http.SendAsync(req);
var content = await res.Content.ReadAsStringAsync(); var content = await res.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<ShortenData>(content); var data = JsonConvert.DeserializeObject<ShortenData>(content);
if (!string.IsNullOrWhiteSpace(data?.ResultUrl)) if (!string.IsNullOrWhiteSpace(data?.ResultUrl))
cachedShortenedLinks.TryAdd(query, data.ResultUrl); _cachedShortenedLinks.TryAdd(query, data.ResultUrl);
else else
return; return;
@@ -406,7 +406,6 @@ public partial class Searches : NadekoModule<SearchesService>
[Cmd] [Cmd]
public async partial Task Hearthstone([Leftover] string name) public async partial Task Hearthstone([Leftover] string name)
{ {
var arg = name;
if (!await ValidateQuery(name)) if (!await ValidateQuery(name))
return; return;
@@ -496,7 +495,8 @@ public partial class Searches : NadekoModule<SearchesService>
.Where(x => x.Senses is not null .Where(x => x.Senses is not null
&& x.Senses.Count > 0 && x.Senses.Count > 0
&& x.Senses[0].Definition is not null) && x.Senses[0].Definition is not null)
.Select(x => (Sense: x.Senses[0], x.PartOfSpeech)); .Select(x => (Sense: x.Senses[0], x.PartOfSpeech))
.ToList();
if (!datas.Any()) if (!datas.Any())
{ {
@@ -505,17 +505,17 @@ public partial class Searches : NadekoModule<SearchesService>
} }
var col = datas.Select(data => ( var col = datas.Select(x => (
Definition: data.Sense.Definition is string Definition: x.Sense.Definition is string
? data.Sense.Definition.ToString() ? x.Sense.Definition.ToString()
: ((JArray)JToken.Parse(data.Sense.Definition.ToString())).First.ToString(), : ((JArray)JToken.Parse(x.Sense.Definition.ToString())).First.ToString(),
Example: data.Sense.Examples is null || data.Sense.Examples.Count == 0 Example: x.Sense.Examples is null || x.Sense.Examples.Count == 0
? string.Empty ? string.Empty
: data.Sense.Examples[0].Text, Word: word, : x.Sense.Examples[0].Text, Word: word,
WordType: string.IsNullOrWhiteSpace(data.PartOfSpeech) ? "-" : data.PartOfSpeech)) WordType: string.IsNullOrWhiteSpace(x.PartOfSpeech) ? "-" : x.PartOfSpeech))
.ToList(); .ToList();
Log.Information($"Sending {col.Count} definition for: {word}"); Log.Information("Sending {Count} definition for: {Word}", col.Count, word);
await ctx.SendPaginatedConfirmAsync(0, await ctx.SendPaginatedConfirmAsync(0,
page => page =>
@@ -547,8 +547,6 @@ public partial class Searches : NadekoModule<SearchesService>
{ {
using var http = _httpFactory.CreateClient(); using var http = _httpFactory.CreateClient();
var response = await http.GetStringAsync("https://catfact.ninja/fact"); var response = await http.GetStringAsync("https://catfact.ninja/fact");
if (response is null)
return;
var fact = JObject.Parse(response)["fact"].ToString(); var fact = JObject.Parse(response)["fact"].ToString();
await SendConfirmAsync("🐈" + GetText(strs.catfact), fact); await SendConfirmAsync("🐈" + GetText(strs.catfact), fact);
@@ -563,9 +561,6 @@ public partial class Searches : NadekoModule<SearchesService>
usr = (IGuildUser)ctx.User; usr = (IGuildUser)ctx.User;
var av = usr.RealAvatarUrl(); var av = usr.RealAvatarUrl();
if (av is null)
return;
await SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={av}"); await SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={av}");
} }
@@ -690,7 +685,7 @@ public partial class Searches : NadekoModule<SearchesService>
try try
{ {
using var http = _httpFactory.CreateClient(); using var http = _httpFactory.CreateClient();
var res = await http.GetStringAsync("https://bible-api.com/" + book + " " + chapterAndVerse); var res = await http.GetStringAsync($"https://bible-api.com/{book} {chapterAndVerse}");
obj = JsonConvert.DeserializeObject<BibleVerses>(res); obj = JsonConvert.DeserializeObject<BibleVerses>(res);
} }

View File

@@ -68,12 +68,12 @@ public class SearchesService : INService
if (File.Exists("data/wowjokes.json")) if (File.Exists("data/wowjokes.json"))
WowJokes = JsonConvert.DeserializeObject<List<WoWJoke>>(File.ReadAllText("data/wowjokes.json")); WowJokes = JsonConvert.DeserializeObject<List<WoWJoke>>(File.ReadAllText("data/wowjokes.json"));
else else
Log.Warning("data/wowjokes.json is missing. WOW Jokes are not loaded."); Log.Warning("data/wowjokes.json is missing. WOW Jokes are not loaded");
if (File.Exists("data/magicitems.json")) if (File.Exists("data/magicitems.json"))
MagicItems = JsonConvert.DeserializeObject<List<MagicItem>>(File.ReadAllText("data/magicitems.json")); MagicItems = JsonConvert.DeserializeObject<List<MagicItem>>(File.ReadAllText("data/magicitems.json"));
else else
Log.Warning("data/magicitems.json is missing. Magic items are not loaded."); Log.Warning("data/magicitems.json is missing. Magic items are not loaded");
if (File.Exists("data/yomama.txt")) if (File.Exists("data/yomama.txt"))
{ {
@@ -165,14 +165,14 @@ public class SearchesService : INService
+ "appid=42cd627dd60debf25a5739e50a217d74&" + "appid=42cd627dd60debf25a5739e50a217d74&"
+ "units=metric"); + "units=metric");
if (data is null) if (string.IsNullOrWhiteSpace(data))
return null; return null;
return JsonConvert.DeserializeObject<WeatherData>(data); return JsonConvert.DeserializeObject<WeatherData>(data);
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Warning(ex.Message); Log.Warning(ex, "Error getting weather data");
return null; return null;
} }
} }
@@ -196,7 +196,7 @@ public class SearchesService : INService
try try
{ {
using var _http = _httpFactory.CreateClient(); using var http = _httpFactory.CreateClient();
var res = await _cache.GetOrAddCachedDataAsync($"geo_{query}", var res = await _cache.GetOrAddCachedDataAsync($"geo_{query}",
_ => _ =>
{ {
@@ -207,7 +207,7 @@ public class SearchesService : INService
+ $"q={Uri.EscapeDataString(query)}&" + $"q={Uri.EscapeDataString(query)}&"
+ "format=json"; + "format=json";
var res = _http.GetStringAsync(url); var res = http.GetStringAsync(url);
return res; return res;
}, },
"", "",
@@ -227,7 +227,7 @@ public class SearchesService : INService
+ $"key={_creds.TimezoneDbApiKey}&format=json&" + $"key={_creds.TimezoneDbApiKey}&format=json&"
+ "by=position&" + "by=position&"
+ $"lat={geoData.Lat}&lng={geoData.Lon}"); + $"lat={geoData.Lat}&lng={geoData.Lon}");
using var geoRes = await _http.SendAsync(req); using var geoRes = await http.SendAsync(req);
var resString = await geoRes.Content.ReadAsStringAsync(); var resString = await geoRes.Content.ReadAsStringAsync();
var timeObj = JsonConvert.DeserializeObject<TimeZoneResult>(resString); var timeObj = JsonConvert.DeserializeObject<TimeZoneResult>(resString);
@@ -403,7 +403,7 @@ public class SearchesService : INService
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Error(ex.Message); Log.Error(ex, "Error getting Hearthstone Card: {ErrorMessage}", ex.Message);
return null; return null;
} }
} }

View File

@@ -24,7 +24,6 @@ public sealed class StreamNotificationService : INService
private readonly Dictionary<StreamDataKey, Dictionary<ulong, HashSet<FollowedStream>>> _shardTrackedStreams; private readonly Dictionary<StreamDataKey, Dictionary<ulong, HashSet<FollowedStream>>> _shardTrackedStreams;
private readonly ConcurrentHashSet<ulong> _offlineNotificationServers; private readonly ConcurrentHashSet<ulong> _offlineNotificationServers;
private readonly IBotCredentials _creds;
private readonly IPubSub _pubSub; private readonly IPubSub _pubSub;
private readonly IEmbedBuilderService _eb; private readonly IEmbedBuilderService _eb;
private readonly Timer _notifCleanupTimer; private readonly Timer _notifCleanupTimer;
@@ -49,7 +48,6 @@ public sealed class StreamNotificationService : INService
_db = db; _db = db;
_client = client; _client = client;
_strings = strings; _strings = strings;
_creds = creds;
_pubSub = pubSub; _pubSub = pubSub;
_eb = eb; _eb = eb;
_streamTracker = new(httpFactory, redis, creds.RedisKey(), client.ShardId == 0); _streamTracker = new(httpFactory, redis, creds.RedisKey(), client.ShardId == 0);
@@ -123,8 +121,12 @@ public sealed class StreamNotificationService : INService
using var uow = _db.GetDbContext(); using var uow = _db.GetDbContext();
foreach (var kvp in deleteGroups) foreach (var kvp in deleteGroups)
{ {
Log.Information($"Deleting {kvp.Value.Count} {kvp.Key} streams because " Log.Information(
+ $"they've been erroring for more than {errorLimit}: {string.Join(", ", kvp.Value)}"); "Deleting {StreamCount} {Platform} streams because they've been erroring for more than {ErrorLimit}: {RemovedList}",
kvp.Value.Count,
kvp.Key,
errorLimit,
string.Join(", ", kvp.Value));
var toDelete = uow.Set<FollowedStream>() var toDelete = uow.Set<FollowedStream>()
.AsQueryable() .AsQueryable()
@@ -140,8 +142,7 @@ public sealed class StreamNotificationService : INService
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Error("Error cleaning up FollowedStreams"); Log.Error(ex, "Error cleaning up FollowedStreams");
Log.Error(ex.ToString());
} }
}, },
null, null,

View File

@@ -0,0 +1,22 @@
#nullable disable
using System.Text.Json.Serialization;
namespace NadekoBot.Modules.Utility;
public sealed class PatreonRefreshData
{
[JsonPropertyName("access_token")]
public string AccessToken { get; set; }
[JsonPropertyName("refresh_token")]
public string RefreshToken { get; set; }
[JsonPropertyName("expires_in")]
public long ExpiresIn { get; set; }
[JsonPropertyName("scope")]
public string Scope { get; set; }
[JsonPropertyName("token_type")]
public string TokenType { get; set; }
}

View File

@@ -6,19 +6,18 @@ using NadekoBot.Services.Database.Models;
using StackExchange.Redis; using StackExchange.Redis;
using System.Net.Http.Json; using System.Net.Http.Json;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization;
namespace NadekoBot.Modules.Utility.Services; namespace NadekoBot.Modules.Utility;
public class PatreonRewardsService : INService public class PatreonRewardsService : INService
{ {
public TimeSpan Interval { get; } = TimeSpan.FromMinutes(3); public TimeSpan Interval { get; } = TimeSpan.FromMinutes(3);
public DateTime LastUpdate { get; private set; } = DateTime.UtcNow; public DateTime LastUpdate { get; private set; } = DateTime.UtcNow;
private readonly SemaphoreSlim getPledgesLocker = new(1, 1); private readonly SemaphoreSlim _getPledgesLocker = new(1, 1);
private readonly Timer _updater; private readonly Timer _updater;
private readonly SemaphoreSlim claimLockJustInCase = new(1, 1); private readonly SemaphoreSlim _claimLockJustInCase = new(1, 1);
private readonly DbService _db; private readonly DbService _db;
private readonly ICurrencyService _currency; private readonly ICurrencyService _currency;
private readonly GamblingConfigService _gamblingConfigService; private readonly GamblingConfigService _gamblingConfigService;
@@ -128,7 +127,7 @@ public class PatreonRewardsService : INService
} }
LastUpdate = DateTime.UtcNow; LastUpdate = DateTime.UtcNow;
await getPledgesLocker.WaitAsync(); await _getPledgesLocker.WaitAsync();
try try
{ {
var members = new List<PatreonMember>(); var members = new List<PatreonMember>();
@@ -154,7 +153,7 @@ public class PatreonRewardsService : INService
members.AddRange(data.Data); members.AddRange(data.Data);
users.AddRange(data.Included); users.AddRange(data.Included);
} while (!string.IsNullOrWhiteSpace(page = data?.Links?.Next)); } while (!string.IsNullOrWhiteSpace(page = data.Links?.Next));
} }
var userData = members.Join(users, var userData = members.Join(users,
@@ -185,13 +184,13 @@ public class PatreonRewardsService : INService
} }
finally finally
{ {
getPledgesLocker.Release(); _getPledgesLocker.Release();
} }
} }
public async Task<int> ClaimReward(ulong userId, string patreonUserId, int cents) public async Task<int> ClaimReward(ulong userId, string patreonUserId, int cents)
{ {
await claimLockJustInCase.WaitAsync(); await _claimLockJustInCase.WaitAsync();
var settings = _gamblingConfigService.Data; var settings = _gamblingConfigService.Data;
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
try try
@@ -213,7 +212,7 @@ public class PatreonRewardsService : INService
await _currency.AddAsync(userId, "Patreon reward - new", eligibleFor, true); await _currency.AddAsync(userId, "Patreon reward - new", eligibleFor, true);
Log.Information($"Sending new currency reward to {userId}"); Log.Information("Sending new currency reward to {UserId}", userId);
await SendMessageToUser(userId, await SendMessageToUser(userId,
"Thank you for your pledge! " + $"You've been awarded **{eligibleFor}**{settings.Currency.Sign} !"); "Thank you for your pledge! " + $"You've been awarded **{eligibleFor}**{settings.Currency.Sign} !");
return eligibleFor; return eligibleFor;
@@ -228,7 +227,7 @@ public class PatreonRewardsService : INService
await _currency.AddAsync(userId, "Patreon reward - recurring", eligibleFor, true); await _currency.AddAsync(userId, "Patreon reward - recurring", eligibleFor, true);
Log.Information($"Sending recurring currency reward to {userId}"); Log.Information("Sending recurring currency reward to {UserId}", userId);
await SendMessageToUser(userId, await SendMessageToUser(userId,
"Thank you for your continued support! " "Thank you for your continued support! "
+ $"You've been awarded **{eligibleFor}**{settings.Currency.Sign} for this month's support!"); + $"You've been awarded **{eligibleFor}**{settings.Currency.Sign} for this month's support!");
@@ -246,7 +245,7 @@ public class PatreonRewardsService : INService
await _currency.AddAsync(userId, "Patreon reward - update", toAward, true); await _currency.AddAsync(userId, "Patreon reward - update", toAward, true);
Log.Information($"Sending updated currency reward to {userId}"); Log.Information("Sending updated currency reward to {UserId}", userId);
await SendMessageToUser(userId, await SendMessageToUser(userId,
"Thank you for increasing your pledge! " "Thank you for increasing your pledge! "
+ $"You've been awarded an additional **{toAward}**{settings.Currency.Sign} !"); + $"You've been awarded an additional **{toAward}**{settings.Currency.Sign} !");
@@ -257,7 +256,7 @@ public class PatreonRewardsService : INService
} }
finally finally
{ {
claimLockJustInCase.Release(); _claimLockJustInCase.Release();
} }
} }
@@ -276,23 +275,4 @@ public class PatreonRewardsService : INService
// ignored // ignored
} }
} }
private sealed class PatreonRefreshData
{
[JsonPropertyName("access_token")]
public string AccessToken { get; set; }
[JsonPropertyName("refresh_token")]
public string RefreshToken { get; set; }
[JsonPropertyName("expires_in")]
public long ExpiresIn { get; set; }
[JsonPropertyName("scope")]
public string Scope { get; set; }
[JsonPropertyName("token_type")]
public string TokenType { get; set; }
}
} }

View File

@@ -15,7 +15,6 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AngleSharp" Version="0.16.1" /> <PackageReference Include="AngleSharp" Version="0.16.1" />
<PackageReference Include="AWSSDK.S3" Version="3.7.7.5" /> <PackageReference Include="AWSSDK.S3" Version="3.7.7.5" />
<!-- <PackageReference Include="Cloneable" Version="1.3.0" />-->
<PackageReference Include="CodeHollow.FeedReader" Version="1.2.2" /> <PackageReference Include="CodeHollow.FeedReader" Version="1.2.2" />
<PackageReference Include="CommandLineParser" Version="2.8.0" /> <PackageReference Include="CommandLineParser" Version="2.8.0" />
<PackageReference Include="Discord.Net" Version="3.0.0" /> <PackageReference Include="Discord.Net" Version="3.0.0" />

View File

@@ -15,14 +15,14 @@ public interface IBotCredsProvider
public sealed class BotCredsProvider : IBotCredsProvider public sealed class BotCredsProvider : IBotCredsProvider
{ {
private const string _credsFileName = "creds.yml"; private const string CREDS_FILE_NAME = "creds.yml";
private const string _credsExampleFileName = "creds_example.yml"; private const string CREDS_EXAMPLE_FILE_NAME = "creds_example.yml";
private string CredsPath private string CredsPath
=> Path.Combine(Directory.GetCurrentDirectory(), _credsFileName); => Path.Combine(Directory.GetCurrentDirectory(), CREDS_FILE_NAME);
private string CredsExamplePath private string CredsExamplePath
=> Path.Combine(Directory.GetCurrentDirectory(), _credsExampleFileName); => Path.Combine(Directory.GetCurrentDirectory(), CREDS_EXAMPLE_FILE_NAME);
private string OldCredsJsonPath private string OldCredsJsonPath
=> Path.Combine(Directory.GetCurrentDirectory(), "credentials.json"); => Path.Combine(Directory.GetCurrentDirectory(), "credentials.json");
@@ -37,7 +37,7 @@ public sealed class BotCredsProvider : IBotCredsProvider
private readonly IConfigurationRoot _config; private readonly IConfigurationRoot _config;
private readonly object reloadLock = new(); private readonly object _reloadLock = new();
public BotCredsProvider(int? totalShards = null) public BotCredsProvider(int? totalShards = null)
{ {
@@ -47,9 +47,10 @@ public sealed class BotCredsProvider : IBotCredsProvider
MigrateCredentials(); MigrateCredentials();
if (!File.Exists(CredsPath)) if (!File.Exists(CredsPath))
Log.Warning($"{CredsPath} is missing. " Log.Warning(
+ "Attempting to load creds from environment variables prefixed with 'NadekoBot_'. " "{CredsPath} is missing. Attempting to load creds from environment variables prefixed with 'NadekoBot_'. Example is in {CredsExamplePath}",
+ $"Example is in {CredsExamplePath}"); CredsPath,
CredsExamplePath);
_config = new ConfigurationBuilder().AddYamlFile(CredsPath, false, true) _config = new ConfigurationBuilder().AddYamlFile(CredsPath, false, true)
.AddEnvironmentVariables("NadekoBot_") .AddEnvironmentVariables("NadekoBot_")
@@ -62,15 +63,14 @@ public sealed class BotCredsProvider : IBotCredsProvider
public void Reload() public void Reload()
{ {
lock (reloadLock) lock (_reloadLock)
{ {
_creds.OwnerIds.Clear(); _creds.OwnerIds.Clear();
_config.Bind(_creds); _config.Bind(_creds);
if (string.IsNullOrWhiteSpace(_creds.Token)) if (string.IsNullOrWhiteSpace(_creds.Token))
{ {
Log.Error("Token is missing from creds.yml or Environment variables.\n" Log.Error("Token is missing from creds.yml or Environment variables.\nAdd it and restart the program");
+ "Add it and restart the program.");
Helpers.ReadErrorAndExit(5); Helpers.ReadErrorAndExit(5);
return; return;
} }
@@ -96,13 +96,13 @@ public sealed class BotCredsProvider : IBotCredsProvider
public void ModifyCredsFile(Action<Creds> func) public void ModifyCredsFile(Action<Creds> func)
{ {
var ymlData = File.ReadAllText(_credsFileName); var ymlData = File.ReadAllText(CREDS_FILE_NAME);
var creds = Yaml.Deserializer.Deserialize<Creds>(ymlData); var creds = Yaml.Deserializer.Deserialize<Creds>(ymlData);
func(creds); func(creds);
ymlData = Yaml.Serializer.Serialize(creds); ymlData = Yaml.Serializer.Serialize(creds);
File.WriteAllText(_credsFileName, ymlData); File.WriteAllText(CREDS_FILE_NAME, ymlData);
Reload(); Reload();
} }
@@ -145,13 +145,13 @@ public sealed class BotCredsProvider : IBotCredsProvider
"Data from credentials.json has been moved to creds.yml\nPlease inspect your creds.yml for correctness"); "Data from credentials.json has been moved to creds.yml\nPlease inspect your creds.yml for correctness");
} }
if (File.Exists(_credsFileName)) if (File.Exists(CREDS_FILE_NAME))
{ {
var creds = Yaml.Deserializer.Deserialize<Creds>(File.ReadAllText(_credsFileName)); var creds = Yaml.Deserializer.Deserialize<Creds>(File.ReadAllText(CREDS_FILE_NAME));
if (creds.Version <= 1) if (creds.Version <= 1)
{ {
creds.Version = 2; creds.Version = 2;
File.WriteAllText(_credsFileName, Yaml.Serializer.Serialize(creds)); File.WriteAllText(CREDS_FILE_NAME, Yaml.Serializer.Serialize(creds));
} }
} }
} }

View File

@@ -37,7 +37,7 @@ public class YtdlOperation
{ {
using var process = CreateProcess(args); using var process = CreateProcess(args);
Log.Debug($"Executing {process.StartInfo.FileName} {process.StartInfo.Arguments}"); Log.Debug("Executing {FileName} {Arguments}", process.StartInfo.FileName, process.StartInfo.Arguments);
process.Start(); process.Start();
var str = await process.StandardOutput.ReadToEndAsync(); var str = await process.StandardOutput.ReadToEndAsync();
@@ -63,7 +63,7 @@ public class YtdlOperation
{ {
using var process = CreateProcess(args); using var process = CreateProcess(args);
Log.Debug($"Executing {process.StartInfo.FileName} {process.StartInfo.Arguments}"); Log.Debug("Executing {FileName} {Arguments}", process.StartInfo.FileName, process.StartInfo.Arguments);
process.Start(); process.Start();
string line; string line;