From 63c9316b07d8c9695ca22283cacf4050fa7c32d5 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Tue, 13 Dec 2016 00:44:52 +0100 Subject: [PATCH 01/14] initial commit --- .../20161212184456_logging.Designer.cs | 798 ++++++++++++++++++ .../Migrations/20161212184456_logging.cs | 113 +++ .../NadekoSqliteContextModelSnapshot.cs | 34 +- .../Administration/Commands/LogCommand.cs | 451 +++++----- .../Administration/Commands/Migration.cs | 5 +- .../Resources/CommandStrings.Designer.cs | 58 +- src/NadekoBot/Resources/CommandStrings.resx | 22 +- .../Database/Models/IgnoredLogChannel.cs | 4 +- .../Services/Database/Models/LogSetting.cs | 37 +- .../Services/Database/NadekoContext.cs | 21 +- .../Impl/GuildConfigRepository.cs | 6 +- src/NadekoBot/project.json | 1 + 12 files changed, 1263 insertions(+), 287 deletions(-) create mode 100644 src/NadekoBot/Migrations/20161212184456_logging.Designer.cs create mode 100644 src/NadekoBot/Migrations/20161212184456_logging.cs diff --git a/src/NadekoBot/Migrations/20161212184456_logging.Designer.cs b/src/NadekoBot/Migrations/20161212184456_logging.Designer.cs new file mode 100644 index 00000000..da2bf901 --- /dev/null +++ b/src/NadekoBot/Migrations/20161212184456_logging.Designer.cs @@ -0,0 +1,798 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using NadekoBot.Services.Database; +using NadekoBot.Services.Database.Models; +using NadekoBot.Modules.Music.Classes; + +namespace NadekoBot.Migrations +{ + [DbContext(typeof(NadekoContext))] + [Migration("20161212184456_logging")] + partial class logging + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { + modelBuilder + .HasAnnotation("ProductVersion", "1.1.0-rtm-22752"); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("ItemId"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("BlacklistItem"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.BotConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BufferSize"); + + b.Property("CurrencyGenerationChance"); + + b.Property("CurrencyGenerationCooldown"); + + b.Property("CurrencyName"); + + b.Property("CurrencyPluralName"); + + b.Property("CurrencySign"); + + b.Property("DMHelpString"); + + b.Property("ForwardMessages"); + + b.Property("ForwardToAllOwners"); + + b.Property("HelpString"); + + b.Property("MigrationVersion"); + + b.Property("RemindMessageFormat"); + + b.Property("RotatingStatuses"); + + b.HasKey("Id"); + + b.ToTable("BotConfig"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BaseDestroyed"); + + b.Property("CallUser"); + + b.Property("ClashWarId"); + + b.Property("SequenceNumber"); + + b.Property("Stars"); + + b.Property("TimeAdded"); + + b.HasKey("Id"); + + b.HasIndex("ClashWarId"); + + b.ToTable("ClashCallers"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashWar", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("EnemyClan"); + + b.Property("GuildId"); + + b.Property("Size"); + + b.Property("StartedAt"); + + b.Property("WarState"); + + b.HasKey("Id"); + + b.ToTable("ClashOfClans"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("CommandName"); + + b.Property("GuildConfigId"); + + b.Property("Seconds"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("CommandCooldown"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ConvertUnit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("InternalTrigger"); + + b.Property("Modifier"); + + b.Property("UnitType"); + + b.HasKey("Id"); + + b.ToTable("ConversionUnits"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Currency", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Amount"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("Currency"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CurrencyTransaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Amount"); + + b.Property("Reason"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.ToTable("CurrencyTransactions"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CustomReaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("GuildId"); + + b.Property("IsRegex"); + + b.Property("OwnerOnly"); + + b.Property("Response"); + + b.Property("Trigger"); + + b.HasKey("Id"); + + b.ToTable("CustomReactions"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Donator", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Amount"); + + b.Property("Name"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("Donators"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("Text"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("EightBallResponses"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("GuildConfigId"); + + b.Property("GuildConfigId1"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.HasIndex("GuildConfigId1"); + + b.ToTable("FilterChannelId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("GuildConfigId"); + + b.Property("Word"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("FilteredWord"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("GuildConfigId"); + + b.Property("GuildId"); + + b.Property("Type"); + + b.Property("Username"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("FollowedStream"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("GuildConfigId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("GCChannelId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AutoAssignRoleId"); + + b.Property("AutoDeleteByeMessages"); + + b.Property("AutoDeleteByeMessagesTimer"); + + b.Property("AutoDeleteGreetMessages"); + + b.Property("AutoDeleteGreetMessagesTimer"); + + b.Property("AutoDeleteSelfAssignedRoleMessages"); + + b.Property("ByeMessageChannelId"); + + b.Property("ChannelByeMessageText"); + + b.Property("ChannelGreetMessageText"); + + b.Property("CleverbotEnabled"); + + b.Property("DefaultMusicVolume"); + + b.Property("DeleteMessageOnCommand"); + + b.Property("DmGreetMessageText"); + + b.Property("ExclusiveSelfAssignedRoles"); + + b.Property("FilterInvites"); + + b.Property("FilterWords"); + + b.Property("GreetMessageChannelId"); + + b.Property("GuildId"); + + b.Property("LogSettingId"); + + b.Property("MuteRoleName"); + + b.Property("PermissionRole"); + + b.Property("RootPermissionId"); + + b.Property("SendChannelByeMessage"); + + b.Property("SendChannelGreetMessage"); + + b.Property("SendDmGreetMessage"); + + b.Property("VerbosePermissions"); + + b.Property("VoicePlusTextEnabled"); + + b.HasKey("Id"); + + b.HasIndex("GuildId") + .IsUnique(); + + b.HasIndex("LogSettingId"); + + b.HasIndex("RootPermissionId"); + + b.ToTable("GuildConfigs"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("LogSettingId"); + + b.HasKey("Id"); + + b.HasIndex("LogSettingId"); + + b.ToTable("IgnoredLogChannels"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("LogSettingId"); + + b.HasKey("Id"); + + b.HasIndex("LogSettingId"); + + b.ToTable("IgnoredVoicePresenceCHannels"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelCreatedId"); + + b.Property("ChannelDestroyedId"); + + b.Property("ChannelUpdatedId"); + + b.Property("LogOtherId"); + + b.Property("LogUserPresenceId"); + + b.Property("LogVoicePresenceId"); + + b.Property("LogVoicePresenceTTSId"); + + b.Property("MessageDeletedId"); + + b.Property("MessageUpdatedId"); + + b.Property("UserBannedId"); + + b.Property("UserJoinedId"); + + b.Property("UserLeftId"); + + b.Property("UserUnbannedId"); + + b.Property("UserUpdatedId"); + + b.HasKey("Id"); + + b.ToTable("LogSettings"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("ModuleName"); + + b.Property("Prefix"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("ModulePrefixes"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlaylist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Author"); + + b.Property("AuthorId"); + + b.Property("Name"); + + b.HasKey("Id"); + + b.ToTable("MusicPlaylists"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("NextId"); + + b.Property("PrimaryTarget"); + + b.Property("PrimaryTargetId"); + + b.Property("SecondaryTarget"); + + b.Property("SecondaryTargetName"); + + b.Property("State"); + + b.HasKey("Id"); + + b.HasIndex("NextId") + .IsUnique(); + + b.ToTable("Permission"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("Status"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("PlayingStatus"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("MusicPlaylistId"); + + b.Property("Provider"); + + b.Property("ProviderType"); + + b.Property("Query"); + + b.Property("Title"); + + b.Property("Uri"); + + b.HasKey("Id"); + + b.HasIndex("MusicPlaylistId"); + + b.ToTable("PlaylistSong"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AuthorId"); + + b.Property("AuthorName") + .IsRequired(); + + b.Property("GuildId"); + + b.Property("Keyword") + .IsRequired(); + + b.Property("Text") + .IsRequired(); + + b.HasKey("Id"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("Icon"); + + b.Property("Name"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("RaceAnimals"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("IsPrivate"); + + b.Property("Message"); + + b.Property("ServerId"); + + b.Property("UserId"); + + b.Property("When"); + + b.HasKey("Id"); + + b.ToTable("Reminders"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Repeater", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("GuildId"); + + b.Property("Interval"); + + b.Property("Message"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId") + .IsUnique(); + + b.ToTable("Repeaters"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("GuildId"); + + b.Property("RoleId"); + + b.HasKey("Id"); + + b.HasIndex("GuildId", "RoleId") + .IsUnique(); + + b.ToTable("SelfAssignableRoles"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.UserPokeTypes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("UserId"); + + b.Property("type"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("PokeGame"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("Blacklist") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ClashWar", "ClashWar") + .WithMany("Bases") + .HasForeignKey("ClashWarId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("CommandCooldowns") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("EightBallResponses") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("FilterInvitesChannelIds") + .HasForeignKey("GuildConfigId"); + + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("FilterWordsChannelIds") + .HasForeignKey("GuildConfigId1"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("FilteredWords") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("FollowedStreams") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("GenerateCurrencyChannelIds") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b => + { + b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting") + .WithMany() + .HasForeignKey("LogSettingId"); + + b.HasOne("NadekoBot.Services.Database.Models.Permission", "RootPermission") + .WithMany() + .HasForeignKey("RootPermissionId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b => + { + b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting") + .WithMany("IgnoredChannels") + .HasForeignKey("LogSettingId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b => + { + b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting") + .WithMany("IgnoredVoicePresenceChannelIds") + .HasForeignKey("LogSettingId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("ModulePrefixes") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b => + { + b.HasOne("NadekoBot.Services.Database.Models.Permission", "Next") + .WithOne("Previous") + .HasForeignKey("NadekoBot.Services.Database.Models.Permission", "NextId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("RotatingStatusMessages") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b => + { + b.HasOne("NadekoBot.Services.Database.Models.MusicPlaylist") + .WithMany("Songs") + .HasForeignKey("MusicPlaylistId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("RaceAnimals") + .HasForeignKey("BotConfigId"); + }); + } + } +} diff --git a/src/NadekoBot/Migrations/20161212184456_logging.cs b/src/NadekoBot/Migrations/20161212184456_logging.cs new file mode 100644 index 00000000..8f53ea0a --- /dev/null +++ b/src/NadekoBot/Migrations/20161212184456_logging.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace NadekoBot.Migrations +{ + public partial class logging : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + //migrationBuilder.DropIndex( + // name: "IX_GuildConfigs_LogSettingId", + // table: "GuildConfigs"); + + //migrationBuilder.DropIndex( + // name: "IX_IgnoredLogChannels_LogSettingId", + // table: "IgnoredLogChannels"); + + //migrationBuilder.DropIndex( + // name: "IX_IgnoredVoicePresenceChannels_LogSettingId", + // table: "IgnoredVoicePresenceChannels"); + + //migrationBuilder.DropTable("LogSettings"); + //migrationBuilder.DropTable("IgnoredLogChannels"); + //migrationBuilder.DropTable("IgnoredVoicePresenceChannels"); + + //migrationBuilder.CreateTable( + // name: "LogSettings", + // columns: table => new + // { + // Id = table.Column(nullable: false) + // .Annotation("Autoincrement", true), + // LogOtherId = table.Column(nullable: true), + // MessageUpdatedId = table.Column(nullable: true), + // MessageDeletedId = table.Column(nullable: true), + // UserJoinedId = table.Column(nullable: true), + // UserLeftId = table.Column(nullable: true), + // UserBannedId = table.Column(nullable: true), + // UserUnbannedId = table.Column(nullable: true), + // UserUpdatedId = table.Column(nullable: true), + // ChannelCreatedId = table.Column(nullable: true), + // ChannelDestroyedId = table.Column(nullable: true), + // ChannelUpdatedId = table.Column(nullable: true), + // LogUserPresenceId = table.Column(nullable: true), + // LogVoicePresenceId = table.Column(nullable: true), + // LogVoicePresenceTTSId = table.Column(nullable: true) + // }, + // constraints: table => + // { + // table.PrimaryKey("PK_LogSettings", x => x.Id); + // }); + + //migrationBuilder.CreateTable( + // name: "IgnoredLogChannels", + // columns: table => new + // { + // Id = table.Column(nullable: false) + // .Annotation("Autoincrement", true), + // ChannelId = table.Column(nullable: false), + // LogSettingId = table.Column(nullable: true) + // }, + // constraints: table => + // { + // table.PrimaryKey("PK_IgnoredLogChannels", x => x.Id); + // table.ForeignKey( + // name: "FK_IgnoredLogChannels_LogSettings_LogSettingId", + // column: x => x.LogSettingId, + // principalTable: "LogSettings", + // principalColumn: "Id", + // onDelete: ReferentialAction.Restrict); + // }); + + //migrationBuilder.CreateTable( + // name: "IgnoredVoicePresenceChannels", + // columns: table => new + // { + // Id = table.Column(nullable: false) + // .Annotation("Autoincrement", true), + // ChannelId = table.Column(nullable: false), + // LogSettingId = table.Column(nullable: true) + // }, + // constraints: table => + // { + // table.PrimaryKey("PK_IgnoredVoicePresenceChannels", x => x.Id); + // table.ForeignKey( + // name: "FK_IgnoredVoicePresenceChannels_LogSettings_LogSettingId", + // column: x => x.LogSettingId, + // principalTable: "LogSettings", + // principalColumn: "Id", + // onDelete: ReferentialAction.Restrict); + // }); + + //migrationBuilder.CreateIndex( + // name: "IX_GuildConfigs_LogSettingId", + // table: "GuildConfigs", + // column: "LogSettingId"); + + //migrationBuilder.CreateIndex( + // name: "IX_IgnoredLogChannels_LogSettingId", + // table: "IgnoredLogChannels", + // column: "LogSettingId"); + + //migrationBuilder.CreateIndex( + // name: "IX_IgnoredVoicePresenceChannels_LogSettingId", + // table: "IgnoredVoicePresenceChannels", + // column: "LogSettingId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + } + } +} diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index d209fb74..7ffbe3e8 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -421,37 +421,33 @@ namespace NadekoBot.Migrations b.Property("Id") .ValueGeneratedOnAdd(); - b.Property("ChannelCreated"); + b.Property("ChannelCreatedId"); - b.Property("ChannelDestroyed"); + b.Property("ChannelDestroyedId"); - b.Property("ChannelId"); + b.Property("ChannelUpdatedId"); - b.Property("ChannelUpdated"); + b.Property("LogOtherId"); - b.Property("IsLogging"); + b.Property("LogUserPresenceId"); - b.Property("LogUserPresence"); + b.Property("LogVoicePresenceId"); - b.Property("LogVoicePresence"); + b.Property("LogVoicePresenceTTSId"); - b.Property("MessageDeleted"); + b.Property("MessageDeletedId"); - b.Property("MessageUpdated"); + b.Property("MessageUpdatedId"); - b.Property("UserBanned"); + b.Property("UserBannedId"); - b.Property("UserJoined"); + b.Property("UserJoinedId"); - b.Property("UserLeft"); + b.Property("UserLeftId"); - b.Property("UserPresenceChannelId"); + b.Property("UserUnbannedId"); - b.Property("UserUnbanned"); - - b.Property("UserUpdated"); - - b.Property("VoicePresenceChannelId"); + b.Property("UserUpdatedId"); b.HasKey("Id"); @@ -663,7 +659,7 @@ namespace NadekoBot.Migrations b.Property("Id") .ValueGeneratedOnAdd(); - b.Property("UserId"); + b.Property("UserId"); b.Property("type"); diff --git a/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs index 9913c53b..cab61cea 100644 --- a/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs @@ -4,6 +4,7 @@ using Discord.WebSocket; using Microsoft.EntityFrameworkCore; using NadekoBot.Attributes; using NadekoBot.Extensions; +using NadekoBot.Modules.Permissions; using NadekoBot.Services; using NadekoBot.Services.Database.Models; using NLog; @@ -88,10 +89,10 @@ namespace NadekoBot.Modules.Administration LogSetting logSetting; if (!GuildLogSettings.TryGetValue(users.First().Guild.Id, out logSetting) - || !logSetting.IsLogging) + || (logSetting.LogOtherId == null)) return; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(users.First().Guild, logSetting)) == null) + if ((logChannel = TryGetLogChannel(users.First().Guild, logSetting, LogType.Other)) == null) return; var punishment = ""; @@ -119,12 +120,11 @@ namespace NadekoBot.Modules.Administration { LogSetting logSetting; if (!GuildLogSettings.TryGetValue(before.Guild.Id, out logSetting) - || !logSetting.IsLogging - || !logSetting.UserUpdated) + || (logSetting.UserUpdatedId == null)) return Task.CompletedTask; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(before.Guild, logSetting)) == null) + if ((logChannel = TryGetLogChannel(before.Guild, logSetting, LogType.UserUpdated)) == null) return Task.CompletedTask; var task = Task.Run(async () => @@ -175,13 +175,12 @@ namespace NadekoBot.Modules.Administration LogSetting logSetting; if (!GuildLogSettings.TryGetValue(before.Guild.Id, out logSetting) - || !logSetting.IsLogging - || !logSetting.ChannelUpdated + || (logSetting.ChannelUpdatedId == null) || logSetting.IgnoredChannels.Any(ilc => ilc.ChannelId == after.Id)) return Task.CompletedTask; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(before.Guild, logSetting)) == null) + if ((logChannel = TryGetLogChannel(before.Guild, logSetting, LogType.ChannelUpdated)) == null) return Task.CompletedTask; var task = Task.Run(async () => @@ -213,13 +212,12 @@ namespace NadekoBot.Modules.Administration LogSetting logSetting; if (!GuildLogSettings.TryGetValue(ch.Guild.Id, out logSetting) - || !logSetting.IsLogging - || !logSetting.ChannelDestroyed + || (logSetting.ChannelDestroyedId == null) || logSetting.IgnoredChannels.Any(ilc=>ilc.ChannelId == ch.Id)) return Task.CompletedTask; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(ch.Guild, logSetting)) == null) + if ((logChannel = TryGetLogChannel(ch.Guild, logSetting, LogType.ChannelDestroyed)) == null) return Task.CompletedTask; var task = Task.Run(async () => @@ -238,12 +236,11 @@ namespace NadekoBot.Modules.Administration LogSetting logSetting; if (!GuildLogSettings.TryGetValue(ch.Guild.Id, out logSetting) - || !logSetting.IsLogging - || !logSetting.ChannelCreated) + || (logSetting.ChannelCreatedId == null)) return Task.CompletedTask; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(ch.Guild, logSetting)) == null) + if ((logChannel = TryGetLogChannel(ch.Guild, logSetting, LogType.ChannelCreated)) == null) return Task.CompletedTask; var task = Task.Run(async () => @@ -268,11 +265,11 @@ namespace NadekoBot.Modules.Administration LogSetting logSetting; if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out logSetting) - || !logSetting.LogVoicePresence) + || (logSetting.LogVoicePresenceId == null)) return Task.CompletedTask; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(usr.Guild, logSetting, LogChannelType.Voice)) == null) + if ((logChannel = TryGetLogChannel(usr.Guild, logSetting, LogType.VoicePresence)) == null) return Task.CompletedTask; string str = null; @@ -298,12 +295,12 @@ namespace NadekoBot.Modules.Administration { LogSetting logSetting; if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out logSetting) - || !logSetting.LogUserPresence + || (logSetting.LogUserPresenceId == null) || before.Status == after.Status) return Task.CompletedTask; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(usr.Guild, logSetting, LogChannelType.UserPresence)) == null) + if ((logChannel = TryGetLogChannel(usr.Guild, logSetting, LogType.UserPresence)) == null) return Task.CompletedTask; string str; if (before.Status != after.Status) @@ -320,12 +317,11 @@ namespace NadekoBot.Modules.Administration { LogSetting logSetting; if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out logSetting) - || !logSetting.IsLogging - || !logSetting.UserLeft) + || (logSetting.UserLeftId == null)) return Task.CompletedTask; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(usr.Guild, logSetting)) == null) + if ((logChannel = TryGetLogChannel(usr.Guild, logSetting, LogType.UserLeft)) == null) return Task.CompletedTask; var task = Task.Run(async () => @@ -340,12 +336,11 @@ namespace NadekoBot.Modules.Administration { LogSetting logSetting; if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out logSetting) - || !logSetting.IsLogging - || !logSetting.UserJoined) + || (logSetting.UserJoinedId == null)) return Task.CompletedTask; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(usr.Guild, logSetting)) == null) + if ((logChannel = TryGetLogChannel(usr.Guild, logSetting, LogType.UserJoined)) == null) return Task.CompletedTask; var task = Task.Run(async () => @@ -360,12 +355,11 @@ namespace NadekoBot.Modules.Administration { LogSetting logSetting; if (!GuildLogSettings.TryGetValue(guild.Id, out logSetting) - || !logSetting.IsLogging - || !logSetting.UserUnbanned) + || (logSetting.UserUnbannedId == null)) return Task.CompletedTask; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(guild, logSetting)) == null) + if ((logChannel = TryGetLogChannel(guild, logSetting, LogType.UserUnbanned)) == null) return Task.CompletedTask; var task = Task.Run(async () => @@ -380,12 +374,11 @@ namespace NadekoBot.Modules.Administration { LogSetting logSetting; if (!GuildLogSettings.TryGetValue(guild.Id, out logSetting) - || !logSetting.IsLogging - || !logSetting.UserBanned) + || (logSetting.UserBannedId == null)) return Task.CompletedTask; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(guild, logSetting)) == null) + if ((logChannel = TryGetLogChannel(guild, logSetting, LogType.UserBanned)) == null) return Task.CompletedTask; var task = Task.Run(async () => @@ -408,13 +401,12 @@ namespace NadekoBot.Modules.Administration LogSetting logSetting; if (!GuildLogSettings.TryGetValue(channel.Guild.Id, out logSetting) - || !logSetting.IsLogging - || !logSetting.MessageDeleted + || (logSetting.MessageDeletedId == null) || logSetting.IgnoredChannels.Any(ilc => ilc.ChannelId == channel.Id)) return Task.CompletedTask; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(channel.Guild, logSetting)) == null || logChannel.Id == msg.Id) + if ((logChannel = TryGetLogChannel(channel.Guild, logSetting, LogType.MessageDeleted)) == null || logChannel.Id == msg.Id) return Task.CompletedTask; var task = Task.Run(async () => @@ -449,13 +441,12 @@ namespace NadekoBot.Modules.Administration LogSetting logSetting; if (!GuildLogSettings.TryGetValue(channel.Guild.Id, out logSetting) - || !logSetting.IsLogging - || !logSetting.MessageUpdated + || (logSetting.MessageUpdatedId == null) || logSetting.IgnoredChannels.Any(ilc => ilc.ChannelId == channel.Id)) return Task.CompletedTask; ITextChannel logChannel; - if ((logChannel = TryGetLogChannel(channel.Guild, logSetting)) == null || logChannel.Id == after.Channel.Id) + if ((logChannel = TryGetLogChannel(channel.Guild, logSetting, LogType.MessageUpdated)) == null || logChannel.Id == after.Channel.Id) return Task.CompletedTask; var task = Task.Run(async () => @@ -470,85 +461,143 @@ namespace NadekoBot.Modules.Administration return Task.CompletedTask; } -// private Task _client_MessageReceived(IMessage imsg) -// { -// var msg = imsg as IUserMessage; -// if (msg == null || msg.IsAuthor()) -// return Task.CompletedTask; + public enum LogType { + Other, + MessageUpdated, + MessageDeleted, + UserJoined, + UserLeft, + UserBanned, + UserUnbanned, + UserUpdated, + ChannelCreated, + ChannelDestroyed, + ChannelUpdated, + UserPresence, + VoicePresence, + VoicePresenceTTS + }; -// var channel = msg.Channel as ITextChannel; -// if (channel == null) -// return Task.CompletedTask; - -// LogSetting logSetting; -// if (!GuildLogSettings.TryGetValue(channel.Guild.Id, out logSetting) -// || !logSetting.IsLogging -// || !logSetting.MessageReceived) -// return Task.CompletedTask; - -// ITextChannel logChannel; -// if ((logChannel = TryGetLogChannel(channel.Guild, logSetting)) == null || logChannel.Id == imsg.Channel.Id) -// return Task.CompletedTask; - -// var task = Task.Run(async () => -// { -// var str = $@"🕔`{prettyCurrentTime}` **New Message** `#{channel.Name}` -//👤`{msg.Author.Username}`: {msg.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator)}"; -// if (msg.Attachments.Any()) -// str += $"{Environment.NewLine}`Attachements`: {string.Join(", ", msg.Attachments.Select(a => a.ProxyUrl))}"; -// await logChannel.SendMessageAsync(str).ConfigureAwait(false); -// }); - -// return Task.CompletedTask; -// } - - private enum LogChannelType { Text, Voice, UserPresence }; - private static ITextChannel TryGetLogChannel(IGuild guild, LogSetting logSetting, LogChannelType logChannelType = LogChannelType.Text) + private static ITextChannel TryGetLogChannel(IGuild guild, LogSetting logSetting, LogType logChannelType) { - ulong id = 0; + ulong? id = null; switch (logChannelType) { - case LogChannelType.Text: - id = logSetting.ChannelId; + case LogType.Other: + id = logSetting.LogOtherId; break; - case LogChannelType.Voice: - id = logSetting.VoicePresenceChannelId; + case LogType.MessageUpdated: + id = logSetting.MessageUpdatedId; break; - case LogChannelType.UserPresence: - id = logSetting.UserPresenceChannelId; + case LogType.MessageDeleted: + id = logSetting.MessageDeletedId; + break; + case LogType.UserJoined: + id = logSetting.UserJoinedId; + break; + case LogType.UserLeft: + id = logSetting.UserLeftId; + break; + case LogType.UserBanned: + id = logSetting.UserBannedId; + break; + case LogType.UserUnbanned: + id = logSetting.UserUnbannedId; + break; + case LogType.UserUpdated: + id = logSetting.UserUpdatedId; + break; + case LogType.ChannelCreated: + id = logSetting.ChannelCreatedId; + break; + case LogType.ChannelDestroyed: + id = logSetting.ChannelDestroyedId; + break; + case LogType.ChannelUpdated: + id = logSetting.ChannelUpdatedId; + break; + case LogType.UserPresence: + id = logSetting.LogUserPresenceId; + break; + case LogType.VoicePresence: + id = logSetting.LogVoicePresenceId; + break; + case LogType.VoicePresenceTTS: + id = logSetting.LogVoicePresenceTTSId; + break; + default: break; } - var channel = guild.GetTextChannel(id); + + if (!id.HasValue) + { + UnsetLogSetting(guild.Id, logChannelType); + return null; + } + var channel = guild.GetTextChannel(id.Value); if (channel == null) - using (var uow = DbHandler.UnitOfWork()) - { - var newLogSetting = uow.GuildConfigs.For(guild.Id).LogSetting; - switch (logChannelType) - { - case LogChannelType.Text: - logSetting.IsLogging = false; - break; - case LogChannelType.Voice: - logSetting.LogVoicePresence = false; - break; - case LogChannelType.UserPresence: - logSetting.LogUserPresence = false; - break; - } - GuildLogSettings.AddOrUpdate(guild.Id, newLogSetting, (gid, old) => newLogSetting); - uow.Complete(); - return null; - } + { + UnsetLogSetting(guild.Id, logChannelType); + return null; + } else return channel; } + private static void UnsetLogSetting(ulong guildId, LogType logChannelType) + { + using (var uow = DbHandler.UnitOfWork()) + { + var newLogSetting = uow.GuildConfigs.For(guildId).LogSetting; + switch (logChannelType) + { + case LogType.Other: + break; + case LogType.MessageUpdated: + break; + case LogType.MessageDeleted: + break; + case LogType.UserJoined: + break; + case LogType.UserLeft: + break; + case LogType.UserBanned: + break; + case LogType.UserUnbanned: + break; + case LogType.UserUpdated: + break; + case LogType.ChannelCreated: + break; + case LogType.ChannelDestroyed: + break; + case LogType.ChannelUpdated: + break; + case LogType.UserPresence: + break; + case LogType.VoicePresence: + break; + case LogType.VoicePresenceTTS: + break; + default: + break; + } + GuildLogSettings.AddOrUpdate(guildId, newLogSetting, (gid, old) => newLogSetting); + uow.Complete(); + } + } + + public enum EnableDisable { + Enable, + Disable + } + [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.Administrator)] [OwnerOnly] - public async Task LogServer(IUserMessage msg) + public async Task LogServer(IUserMessage msg, PermissionAction action) { var channel = (ITextChannel)msg.Channel; LogSetting logSetting; @@ -556,16 +605,25 @@ namespace NadekoBot.Modules.Administration { logSetting = uow.GuildConfigs.For(channel.Guild.Id).LogSetting; GuildLogSettings.AddOrUpdate(channel.Guild.Id, (id) => logSetting, (id, old) => logSetting); - logSetting.IsLogging = !logSetting.IsLogging; - if (logSetting.IsLogging) - logSetting.ChannelId = channel.Id; - await uow.CompleteAsync(); + logSetting.LogOtherId = + logSetting.MessageUpdatedId = + logSetting.MessageDeletedId = + logSetting.UserJoinedId = + logSetting.UserLeftId = + logSetting.UserBannedId = + logSetting.UserUnbannedId = + logSetting.UserUpdatedId = + logSetting.ChannelCreatedId = + logSetting.ChannelDestroyedId = + logSetting.ChannelUpdatedId = + logSetting.LogUserPresenceId = + logSetting.LogVoicePresenceId = + logSetting.LogVoicePresenceTTSId = (action.Value ? channel.Id : (ulong?)null); } - - if (logSetting.IsLogging) - await channel.SendMessageAsync("✅ **Logging enabled.**").ConfigureAwait(false); + if (action.Value) + await channel.SendMessageAsync("✅ Logging all events on this channel.").ConfigureAwait(false); else - await channel.SendMessageAsync("ℹ️ **Logging disabled.**").ConfigureAwait(false); + await channel.SendMessageAsync("ℹ️ Logging disabled.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -597,146 +655,79 @@ namespace NadekoBot.Modules.Administration await channel.SendMessageAsync($"ℹ️ Logging will **no longer ignore** #⃣ `{channel.Name} ({channel.Id})`").ConfigureAwait(false); } - //[LocalizedCommand, LocalizedRemarks, LocalizedSummary, LocalizedAlias] - //[RequireContext(ContextType.Guild)] - //[OwnerOnly] - //public async Task LogAdd(IUserMessage msg, [Remainder] string eventName) - //{ - // var channel = (ITextChannel)msg.Channel; - // //eventName = eventName?.Replace(" ","").ToLowerInvariant(); - - // switch (eventName.ToLowerInvariant()) - // { - // case "messageupdated": - // case "messagedeleted": - // case "userjoined": - // case "userleft": - // case "userbanned": - // case "userunbanned": - // case "channelcreated": - // case "channeldestroyed": - // case "channelupdated": - // using (var uow = DbHandler.UnitOfWork()) - // { - // var logSetting = uow.GuildConfigs.For(channel.Guild.Id).LogSetting; - // GuildLogSettings.AddOrUpdate(channel.Guild.Id, (id) => logSetting, (id, old) => logSetting); - // var prop = logSetting.GetType().GetProperty(eventName); - // prop.SetValue(logSetting, true); - // await uow.CompleteAsync().ConfigureAwait(false); - // } - // await channel.SendMessageAsync($"`Now logging {eventName} event.`").ConfigureAwait(false); - // break; - // default: - // await channel.SendMessageAsync($"`Event \"{eventName}\" not found.`").ConfigureAwait(false); - // break; - // } - //} - - //[LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias] - //[RequireContext(ContextType.Guild)] - //public async Task LogRemove(IUserMessage msg, string eventName) - //{ - // var channel = (ITextChannel)msg.Channel; - // eventName = eventName.ToLowerInvariant(); - - // switch (eventName) - // { - // case "messagereceived": - // case "messageupdated": - // case "messagedeleted": - // case "userjoined": - // case "userleft": - // case "userbanned": - // case "userunbanned": - // case "channelcreated": - // case "channeldestroyed": - // case "channelupdated": - // using (var uow = DbHandler.UnitOfWork()) - // { - // var config = uow.GuildConfigs.For(channel.Guild.Id); - // LogSetting logSetting = GuildLogSettings.GetOrAdd(channel.Guild.Id, (id) => config.LogSetting); - // logSetting.GetType().GetProperty(eventName).SetValue(logSetting, false); - // config.LogSetting = logSetting; - // await uow.CompleteAsync().ConfigureAwait(false); - // } - // await channel.SendMessageAsync($"`No longer logging {eventName} event.`").ConfigureAwait(false); - // break; - // default: - // await channel.SendMessageAsync($"`Event \"{eventName}\" not found.`").ConfigureAwait(false); - // break; - // } - //} + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.Administrator)] + public async Task LogEvents(IUserMessage imsg) + { + await imsg.Channel.SendConfirmAsync("Log events you can subscribe to:", String.Join(", ", Enum.GetValues(typeof(LogType)).Cast())); + } [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.Administrator)] - public async Task UserPresence(IUserMessage imsg) + public async Task Log(IUserMessage imsg, LogType type) { var channel = (ITextChannel)imsg.Channel; - bool enabled; + ulong? channelId = null; using (var uow = DbHandler.UnitOfWork()) { var logSetting = uow.GuildConfigs.For(channel.Guild.Id).LogSetting; GuildLogSettings.AddOrUpdate(channel.Guild.Id, (id) => logSetting, (id, old) => logSetting); - enabled = logSetting.LogUserPresence = !logSetting.LogUserPresence; - if(enabled) - logSetting.UserPresenceChannelId = channel.Id; + switch (type) + { + case LogType.Other: + channelId = logSetting.LogOtherId = (logSetting.LogOtherId == null ? channel.Id : default(ulong?)); + break; + case LogType.MessageUpdated: + channelId = logSetting.MessageUpdatedId = (logSetting.MessageUpdatedId == null ? channel.Id : default(ulong?)); + break; + case LogType.MessageDeleted: + channelId = logSetting.MessageDeletedId = (logSetting.MessageDeletedId == null ? channel.Id : default(ulong?)); + break; + case LogType.UserJoined: + channelId = logSetting.UserJoinedId = (logSetting.UserJoinedId == null ? channel.Id : default(ulong?)); + break; + case LogType.UserLeft: + channelId = logSetting.UserLeftId = (logSetting.UserLeftId == null ? channel.Id : default(ulong?)); + break; + case LogType.UserBanned: + channelId = logSetting.UserBannedId = (logSetting.UserBannedId == null ? channel.Id : default(ulong?)); + break; + case LogType.UserUnbanned: + channelId = logSetting.UserUnbannedId = (logSetting.UserUnbannedId == null ? channel.Id : default(ulong?)); + break; + case LogType.UserUpdated: + channelId = logSetting.UserUpdatedId = (logSetting.UserUpdatedId == null ? channel.Id : default(ulong?)); + break; + case LogType.ChannelCreated: + channelId = logSetting.ChannelCreatedId = (logSetting.ChannelCreatedId == null ? channel.Id : default(ulong?)); + break; + case LogType.ChannelDestroyed: + channelId = logSetting.ChannelDestroyedId = (logSetting.ChannelDestroyedId == null ? channel.Id : default(ulong?)); + break; + case LogType.ChannelUpdated: + channelId = logSetting.ChannelUpdatedId = (logSetting.ChannelUpdatedId == null ? channel.Id : default(ulong?)); + break; + case LogType.UserPresence: + channelId = logSetting.LogUserPresenceId = (logSetting.LogUserPresenceId == null ? channel.Id : default(ulong?)); + break; + case LogType.VoicePresence: + channelId = logSetting.LogVoicePresenceId = (logSetting.LogVoicePresenceId == null ? channel.Id : default(ulong?)); + break; + case LogType.VoicePresenceTTS: + channelId = logSetting.LogVoicePresenceTTSId = (logSetting.LogVoicePresenceTTSId == null ? channel.Id : default(ulong?)); + break; + } + await uow.CompleteAsync().ConfigureAwait(false); } - if (enabled) - await channel.SendMessageAsync($"✅ Logging **user presence** updates in #⃣ `{channel.Name} ({channel.Id})`").ConfigureAwait(false); + if (channelId != null) + await channel.SendMessageAsync($"✅ Logging `{type}` event in #⃣ `{channel.Name} ({channel.Id})`").ConfigureAwait(false); else - await channel.SendMessageAsync($"ℹ️ Stopped logging **user presence** updates.").ConfigureAwait(false); + await channel.SendMessageAsync($"ℹ️ Stopped logging `{type}` event.").ConfigureAwait(false); } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.Administrator)] - public async Task VoicePresence(IUserMessage imsg) - { - var channel = (ITextChannel)imsg.Channel; - bool enabled; - using (var uow = DbHandler.UnitOfWork()) - { - var logSetting = uow.GuildConfigs.For(channel.Guild.Id, set => set.Include(gc => gc.LogSetting) - .ThenInclude(ls => ls.IgnoredVoicePresenceChannelIds)) - .LogSetting; - GuildLogSettings.AddOrUpdate(channel.Guild.Id, (id) => logSetting, (id, old) => logSetting); - enabled = logSetting.LogVoicePresence = !logSetting.LogVoicePresence; - if (enabled) - logSetting.VoicePresenceChannelId = channel.Id; - await uow.CompleteAsync().ConfigureAwait(false); - } - - if (enabled) - await channel.SendMessageAsync($"✅ Logging **voice presence** updates in #⃣ `{channel.Name} ({channel.Id})`").ConfigureAwait(false); - else - await channel.SendMessageAsync($"ℹ️ Stopped logging **voice presence** updates.").ConfigureAwait(false); - } - - //[LocalizedCommand, LocalizedDescription, LocalizedSummary, LocalizedAlias] - //[RequireContext(ContextType.Guild)] - //public async Task VoiPresIgnore(IUserMessage imsg, IVoiceChannel voiceChannel) - //{ - // var channel = (ITextChannel)imsg.Channel; - // int removed; - // using (var uow = DbHandler.UnitOfWork()) - // { - // var config = uow.GuildConfigs.For(channel.Guild.Id); - // LogSetting logSetting = GuildLogSettings.GetOrAdd(channel.Guild.Id, (id) => config.LogSetting); - // removed = logSetting.IgnoredVoicePresenceChannelIds.RemoveWhere(ivpc => ivpc.ChannelId == voiceChannel.Id); - // if (removed == 0) - // logSetting.IgnoredVoicePresenceChannelIds.Add(new IgnoredVoicePresenceChannel { ChannelId = voiceChannel.Id }); - // config.LogSetting = logSetting; - // await uow.CompleteAsync().ConfigureAwait(false); - // } - - // if (removed == 0) - // await channel.SendMessageAsync($"`Enabled logging voice presence updates for {voiceChannel.Name} ({voiceChannel.Id}) channel.`").ConfigureAwait(false); - // else - // await channel.SendMessageAsync($"`Disabled logging voice presence updates for {voiceChannel.Name} ({voiceChannel.Id}) channel.`").ConfigureAwait(false); - //} } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/Migration.cs b/src/NadekoBot/Modules/Administration/Commands/Migration.cs index 7027488a..9d323245 100644 --- a/src/NadekoBot/Modules/Administration/Commands/Migration.cs +++ b/src/NadekoBot/Modules/Administration/Commands/Migration.cs @@ -195,12 +195,9 @@ namespace NadekoBot.Modules.Administration guildConfig.GenerateCurrencyChannelIds = new HashSet(data.GenerateCurrencyChannels.Select(gc => new GCChannelId() { ChannelId = gc.Key })); selfAssRoles.AddRange(data.ListOfSelfAssignableRoles.Select(r => new SelfAssignedRole() { GuildId = guildConfig.GuildId, RoleId = r }).ToArray()); var logSetting = guildConfig.LogSetting; - guildConfig.LogSetting.IsLogging = data.LogChannel != null; - guildConfig.LogSetting.ChannelId = data.LogChannel ?? 0; guildConfig.LogSetting.IgnoredChannels = new HashSet(data.LogserverIgnoreChannels.Select(id => new IgnoredLogChannel() { ChannelId = id })); - guildConfig.LogSetting.LogUserPresence = data.LogPresenceChannel != null; - guildConfig.LogSetting.UserPresenceChannelId = data.LogPresenceChannel ?? 0; + guildConfig.LogSetting.LogUserPresenceId = data.LogPresenceChannel; guildConfig.FollowedStreams = new HashSet(data.ObservingStreams.Select(x => diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index 26273f63..7a6efa3e 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -3785,6 +3785,60 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to log. + /// + public static string log_cmd { + get { + return ResourceManager.GetString("log_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Toggles logging event. Disables it if it's active anywhere on the server. Enables if it's not active. Use `{0}logevents` to see a lit of all events you can subscribe to.. + /// + public static string log_desc { + get { + return ResourceManager.GetString("log_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}log userpresence` or `{0}log userbanned`. + /// + public static string log_usage { + get { + return ResourceManager.GetString("log_usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to logevents. + /// + public static string logevents_cmd { + get { + return ResourceManager.GetString("logevents_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Shows a list of all events you can subscribe to with `{0}log`. + /// + public static string logevents_desc { + get { + return ResourceManager.GetString("logevents_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}logevents`. + /// + public static string logevents_usage { + get { + return ResourceManager.GetString("logevents_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to logignore. /// @@ -3822,7 +3876,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to Logs server activity in this channel.. + /// Looks up a localized string similar to Enables or Disables ALL log events. If enabled, all log events will log to this channel.. /// public static string logserver_desc { get { @@ -3831,7 +3885,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to `{0}logserver`. + /// Looks up a localized string similar to `{0}logserver enable` or `{0}logserver disable`. /// public static string logserver_usage { get { diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 0a3ae214..57d5ea51 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -229,10 +229,10 @@ logserver - Logs server activity in this channel. + Enables or Disables ALL log events. If enabled, all log events will log to this channel. - `{0}logserver` + `{0}logserver enable` or `{0}logserver disable` logignore @@ -2745,4 +2745,22 @@ `{0}type @someone` + + logevents + + + Shows a list of all events you can subscribe to with `{0}log` + + + `{0}logevents` + + + log + + + Toggles logging event. Disables it if it's active anywhere on the server. Enables if it's not active. Use `{0}logevents` to see a lit of all events you can subscribe to. + + + `{0}log userpresence` or `{0}log userbanned` + \ No newline at end of file diff --git a/src/NadekoBot/Services/Database/Models/IgnoredLogChannel.cs b/src/NadekoBot/Services/Database/Models/IgnoredLogChannel.cs index 40198c7f..12985445 100644 --- a/src/NadekoBot/Services/Database/Models/IgnoredLogChannel.cs +++ b/src/NadekoBot/Services/Database/Models/IgnoredLogChannel.cs @@ -1,4 +1,6 @@ -namespace NadekoBot.Services.Database.Models +using System.ComponentModel.DataAnnotations.Schema; + +namespace NadekoBot.Services.Database.Models { public class IgnoredLogChannel : DbEntity { diff --git a/src/NadekoBot/Services/Database/Models/LogSetting.cs b/src/NadekoBot/Services/Database/Models/LogSetting.cs index b5e841fb..9ec79ae7 100644 --- a/src/NadekoBot/Services/Database/Models/LogSetting.cs +++ b/src/NadekoBot/Services/Database/Models/LogSetting.cs @@ -4,31 +4,28 @@ namespace NadekoBot.Services.Database.Models { public class LogSetting : DbEntity { - public bool IsLogging { get; set; } - public ulong ChannelId { get; set; } public HashSet IgnoredChannels { get; set; } - public bool MessageUpdated { get; set; } = true; - public bool MessageDeleted { get; set; } = true; - - public bool UserJoined { get; set; } = true; - public bool UserLeft { get; set; } = true; - public bool UserBanned { get; set; } = true; - public bool UserUnbanned { get; set; } = true; - public bool UserUpdated { get; set; } = true; - - public bool ChannelCreated { get; set; } = true; - public bool ChannelDestroyed { get; set; } = true; - public bool ChannelUpdated { get; set; } = true; + public ulong? LogOtherId { get; set; } = null; + public ulong? MessageUpdatedId { get; set; } = null; + public ulong? MessageDeletedId { get; set; } = null; + + public ulong? UserJoinedId { get; set; } = null; + public ulong? UserLeftId { get; set; } = null; + public ulong? UserBannedId { get; set; } = null; + public ulong? UserUnbannedId { get; set; } = null; + public ulong? UserUpdatedId { get; set; } = null; + + public ulong? ChannelCreatedId { get; set; } = null; + public ulong? ChannelDestroyedId { get; set; } = null; + public ulong? ChannelUpdatedId { get; set; } = null; //userpresence - public bool LogUserPresence { get; set; } = false; - public ulong UserPresenceChannelId { get; set; } + public ulong? LogUserPresenceId { get; set; } = null; //voicepresence - public bool LogVoicePresence { get; set; } = false; - public ulong VoicePresenceChannelId { get; set; } - public HashSet IgnoredVoicePresenceChannelIds { get; set; } - + public ulong? LogVoicePresenceId { get; set; } = null; + public ulong? LogVoicePresenceTTSId { get; set; } = null; + public HashSet IgnoredVoicePresenceChannels { get; set; } } } diff --git a/src/NadekoBot/Services/Database/NadekoContext.cs b/src/NadekoBot/Services/Database/NadekoContext.cs index 6752343a..d66238ec 100644 --- a/src/NadekoBot/Services/Database/NadekoContext.cs +++ b/src/NadekoBot/Services/Database/NadekoContext.cs @@ -44,11 +44,11 @@ namespace NadekoBot.Services.Database this.Database.Migrate(); EnsureSeedData(); } - //Uncomment this to db initialisation with dotnet ef migration add [module] - //protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - //{ - // optionsBuilder.UseSqlite("Filename=./data/NadekoBot.db"); - //} + ////Uncomment this to db initialisation with dotnet ef migration add [module] + ////protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + ////{ + //// optionsBuilder.UseSqlite("Filename=./data/NadekoBot.db"); + ////} public void EnsureSeedData() { @@ -231,6 +231,17 @@ namespace NadekoBot.Services.Database .IsUnique(); + #endregion + + #region PokeGame + var ignoredLogChannel = modelBuilder.Entity(); + + //ignoredLogChannel.HasMany(i => i.IgnoredChannels) + // .WithOne(ls => ls.LogSetting); + //ignoredLogChannel.HasMany(i => i.IgnoredVoicePresenceChannels) + // .WithOne(ls => ls.LogSetting); + + #endregion } } diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs index 96f0cc22..62af3958 100644 --- a/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs @@ -17,7 +17,7 @@ namespace NadekoBot.Services.Database.Repositories.Impl _set.Include(gc => gc.LogSetting) .ThenInclude(ls => ls.IgnoredChannels) .Include(gc => gc.LogSetting) - .ThenInclude(ls => ls.IgnoredVoicePresenceChannelIds) + .ThenInclude(ls => ls.IgnoredVoicePresenceChannels) .Include(gc => gc.RootPermission) .ThenInclude(gc => gc.Previous) .Include(gc => gc.RootPermission) @@ -42,10 +42,8 @@ namespace NadekoBot.Services.Database.Repositories.Impl { config = _set .Include(gc => gc.FollowedStreams) - .Include(gc => gc.LogSetting) - .ThenInclude(ls => ls.IgnoredChannels) .Include(gc => gc.LogSetting) - .ThenInclude(ls => ls.IgnoredVoicePresenceChannelIds) + .ThenInclude(ls => ls.IgnoredChannels) .Include(gc => gc.FilterInvitesChannelIds) .Include(gc => gc.FilterWordsChannelIds) .Include(gc => gc.FilteredWords) diff --git a/src/NadekoBot/project.json b/src/NadekoBot/project.json index cbf49aa2..1bfebb6f 100644 --- a/src/NadekoBot/project.json +++ b/src/NadekoBot/project.json @@ -31,6 +31,7 @@ "Microsoft.EntityFrameworkCore": "1.1.0", "Microsoft.EntityFrameworkCore.Design": "1.1.0", "Microsoft.EntityFrameworkCore.Sqlite": "1.1.0", + "Npgsql.EntityFrameworkCore.PostgreSQL": "1.1.0", "Microsoft.Extensions.Configuration": "1.1.0", "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0", "Microsoft.Extensions.Configuration.Json": "1.1.0", From 9ea7f42d548f1f040154fd8d72505f657d43b1bc Mon Sep 17 00:00:00 2001 From: Kwoth Date: Fri, 23 Dec 2016 22:17:19 +0100 Subject: [PATCH 02/14] Woopsie daisy, hopefuly you had fun xd --- src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs index 110905cc..2c1b9245 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs @@ -67,6 +67,7 @@ namespace NadekoBot.Modules.Gambling if (!removed) { await channel.SendErrorAsync($"{guildUser.Mention} You don't have enough {Gambling.CurrencyPluralName}.").ConfigureAwait(false); + return; } //heads = true //tails = false From d9d944e5440a85bacc4e727792092490da313973 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 24 Dec 2016 02:45:51 +0100 Subject: [PATCH 03/14] Music fixes, hangman earser -> eraser, thx cake --- src/NadekoBot/Modules/Music/Music.cs | 42 ++++++++++++++++------------ src/NadekoBot/data/hangman.json | 2 +- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/NadekoBot/Modules/Music/Music.cs b/src/NadekoBot/Modules/Music/Music.cs index 3b52abaa..7495af35 100644 --- a/src/NadekoBot/Modules/Music/Music.cs +++ b/src/NadekoBot/Modules/Music/Music.cs @@ -310,27 +310,31 @@ namespace NadekoBot.Modules.Music await channel.SendErrorAsync($"🎵 Failed to find any songs.").ConfigureAwait(false); return; } - var idArray = ids as string[] ?? ids.ToArray(); - var count = idArray.Length; + var count = ids.Count(); - var msg = - await channel.SendMessageAsync($"🎵 Attempting to queue **{count}** songs".SnPl(count) + "...").ConfigureAwait(false); + var msg = await channel.SendMessageAsync($"🎵 Attempting to queue **{count}** songs".SnPl(count) + "...").ConfigureAwait(false); var cancelSource = new CancellationTokenSource(); - var tasks = Task.WhenAll(idArray.Select(async id => - { - if (cancelSource.Token.IsCancellationRequested) - return; - try - { - await QueueSong(((IGuildUser)umsg.Author), channel, ((IGuildUser)umsg.Author).VoiceChannel, id, true).ConfigureAwait(false); - } - catch (SongNotFoundException) { } - catch { try { cancelSource.Cancel(); } catch { } } - })); + var gusr = (IGuildUser)umsg.Author; - await Task.WhenAny(tasks, Task.Delay(Timeout.Infinite, cancelSource.Token)); + while (ids.Any() && !cancelSource.IsCancellationRequested) + { + var tasks = Task.WhenAll(ids.Take(5).Select(async id => + { + if (cancelSource.Token.IsCancellationRequested) + return; + try + { + await QueueSong(gusr, channel, gusr.VoiceChannel, id, true).ConfigureAwait(false); + } + catch (SongNotFoundException) { } + catch { try { cancelSource.Cancel(); } catch { } } + })); + + await Task.WhenAny(tasks, Task.Delay(Timeout.Infinite, cancelSource.Token)); + ids = ids.Skip(5); + } await msg.ModifyAsync(m => m.Content = "✅ Playlist queue complete.").ConfigureAwait(false); } @@ -386,11 +390,12 @@ namespace NadekoBot.Modules.Music var dir = new DirectoryInfo(arg); var fileEnum = dir.GetFiles("*", SearchOption.AllDirectories) .Where(x => !x.Attributes.HasFlag(FileAttributes.Hidden | FileAttributes.System)); + var gusr = (IGuildUser)umsg.Author; foreach (var file in fileEnum) { try { - await QueueSong(((IGuildUser)umsg.Author), channel, ((IGuildUser)umsg.Author).VoiceChannel, file.FullName, true, MusicType.Local).ConfigureAwait(false); + await QueueSong(gusr, channel, gusr.VoiceChannel, file.FullName, true, MusicType.Local).ConfigureAwait(false); } catch (PlaylistFullException) { @@ -636,9 +641,10 @@ namespace NadekoBot.Modules.Music } IUserMessage msg = null; try { msg = await channel.SendMessageAsync($"🎶 Attempting to load **{mpl.Songs.Count}** songs...").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } + + var usr = (IGuildUser)umsg.Author; foreach (var item in mpl.Songs) { - var usr = (IGuildUser)umsg.Author; try { await QueueSong(usr, channel, usr.VoiceChannel, item.Query, true, item.ProviderType).ConfigureAwait(false); diff --git a/src/NadekoBot/data/hangman.json b/src/NadekoBot/data/hangman.json index 40f1dd82..e13fd5ab 100644 --- a/src/NadekoBot/data/hangman.json +++ b/src/NadekoBot/data/hangman.json @@ -2579,7 +2579,7 @@ "ImageUrl": "https://www.randomlists.com/img/things/drill_press.jpg" }, { - "Word": "earser", + "Word": "eraser", "ImageUrl": "https://www.randomlists.com/img/things/earser.jpg" }, { From bdcf98761d6546d0ff51727feb147332945b0e25 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 24 Dec 2016 07:36:21 +0100 Subject: [PATCH 04/14] Offline stream notifs are deleted after 60 seconds --- .../Searches/Commands/StreamNotificationCommands.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/NadekoBot/Modules/Searches/Commands/StreamNotificationCommands.cs b/src/NadekoBot/Modules/Searches/Commands/StreamNotificationCommands.cs index b81626f2..8a09497e 100644 --- a/src/NadekoBot/Modules/Searches/Commands/StreamNotificationCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/StreamNotificationCommands.cs @@ -108,7 +108,13 @@ namespace NadekoBot.Modules.Searches var channel = server?.GetTextChannel(fs.ChannelId); if (channel == null) return; - try { await channel.EmbedAsync(fs.GetEmbed(newStatus).Build()).ConfigureAwait(false); } catch { } + try + { + var msg = await channel.EmbedAsync(fs.GetEmbed(newStatus).Build()).ConfigureAwait(false); + if (!newStatus.IsLive) + msg.DeleteAfter(60); + } + catch { } } } catch { } From 32bf0a3c46308424e2e36aef895a6702eb1ce9fd Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 24 Dec 2016 07:49:59 +0100 Subject: [PATCH 05/14] Commandlist updated, -mdls is alphabetical now --- docs/Commands List.md | 19 ++++++++++--------- src/NadekoBot/Modules/Help/Help.cs | 6 ++++-- src/NadekoBot/Resources/CommandStrings.resx | 8 ++++---- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/docs/Commands List.md b/docs/Commands List.md index 3537e8b7..3f2af4f9 100644 --- a/docs/Commands List.md +++ b/docs/Commands List.md @@ -57,10 +57,10 @@ Command and aliases | Description | Usage `.lcsc` | Leaves Cross server channel instance from this channel. **Requires ManageServer server permission.** | `.lcsc` `.fwmsgs` | Toggles forwarding of non-command messages sent to bot's DM to the bot owners **Bot Owner only.** | `.fwmsgs` `.fwtoall` | Toggles whether messages will be forwarded to all bot owners or only to the first one specified in the credentials.json **Bot Owner only.** | `.fwtoall` -`.logserver` | Logs server activity in this channel. **Requires Administrator server permission.** **Bot Owner only.** | `.logserver` +`.logserver` | Enables or Disables ALL log events. If enabled, all log events will log to this channel. **Requires Administrator server permission.** **Bot Owner only.** | `.logserver enable` or `.logserver disable` `.logignore` | Toggles whether the .logserver command ignores this channel. Useful if you have hidden admin channel and public log channel. **Requires Administrator server permission.** **Bot Owner only.** | `.logignore` -`.userpresence` | Starts logging to this channel when someone from the server goes online/offline/idle. **Requires Administrator server permission.** | `.userpresence` -`.voicepresence` | Toggles logging to this channel whenever someone joins or leaves a voice channel you are currently in. **Requires Administrator server permission.** | `.voicepresence` +`.logevents` | Shows a list of all events you can subscribe to with `.log` **Requires Administrator server permission.** | `.logevents` +`.log` | Toggles logging event. Disables it if it's active anywhere on the server. Enables if it's not active. Use `.logevents` to see a lit of all events you can subscribe to. **Requires Administrator server permission.** | `.log userpresence` or `.log userbanned` `.repeatinvoke` `.repinv` | Immediately shows the repeat message and restarts the timer. **Requires ManageMessages server permission.** | `.repinv` `.repeat` | Repeat a message every X minutes. If no parameters are specified, repeat is disabled. **Requires ManageMessages server permission.** | `.repeat 5 Hello there` `.migratedata` | Migrate data from old bot configuration **Bot Owner only.** | `.migratedata` @@ -158,10 +158,11 @@ Command and aliases | Description | Usage `>poll` | Creates a poll which requires users to send the number of the voting option to the bot. **Requires ManageMessages server permission.** | `>poll Question?;Answer1;Answ 2;A_3` `>publicpoll` `>ppoll` | Creates a public poll which requires users to type a number of the voting option in the channel command is ran in. **Requires ManageMessages server permission.** | `>ppoll Question?;Answer1;Answ 2;A_3` `>pollend` | Stops active poll on this server and prints the results in this channel. **Requires ManageMessages server permission.** | `>pollend` +`>acrophobia` `>acro` | Starts an Acrophobia game. Second argment is optional round length in seconds. (default is 60) | `>acro` or `>acro 30` `>cleverbot` | Toggles cleverbot session. When enabled, the bot will reply to messages starting with bot mention in the server. Custom reactions starting with %mention% won't work if cleverbot is enabled. **Requires ManageMessages server permission.** | `>cleverbot` `>hangmanlist` | Shows a list of hangman term types. | `> hangmanlist` `>hangman` | Starts a game of hangman in the channel. Use `>hangmanlist` to see a list of available term types. Defaults to 'all'. | `>hangman` or `>hangman movies` -`>pick` | Picks the currency planted in this channel. | `>pick` +`>pick` | Picks the currency planted in this channel. 60 seconds cooldown. | `>pick` `>plant` | Spend a unit of currency to plant it in this channel. (If bot is restarted or crashes, the currency will be lost) | `>plant` `>gencurrency` `>gc` | Toggles currency generation on this channel. Every posted message will have chance to spawn currency. Chance is specified by the Bot Owner. (default is 2%) **Requires ManageMessages server permission.** | `>gc` `>typestart` | Starts a typing contest. | `>typestart` @@ -248,13 +249,13 @@ Command and aliases | Description | Usage `;removeperm` `;rp` | Removes a permission from a given position in Permissions list. | `;rp 1` `;moveperm` `;mp` | Moves permission from one position to another in Permissions list. | `;mp 2 4` `;srvrcmd` `;sc` | Sets a command's permission at the server level. | `;sc "command name" disable` -`;srvrmdl` `;sm` | Sets a module's permission at the server level. | `;sm "module name" enable` +`;srvrmdl` `;sm` | Sets a module's permission at the server level. | `;sm ModuleName enable` `;usrcmd` `;uc` | Sets a command's permission at the user level. | `;uc "command name" enable SomeUsername` -`;usrmdl` `;um` | Sets a module's permission at the user level. | `;um "module name" enable SomeUsername` +`;usrmdl` `;um` | Sets a module's permission at the user level. | `;um ModuleName enable SomeUsername` `;rolecmd` `;rc` | Sets a command's permission at the role level. | `;rc "command name" disable MyRole` -`;rolemdl` `;rm` | Sets a module's permission at the role level. | `;rm "module name" enable MyRole` +`;rolemdl` `;rm` | Sets a module's permission at the role level. | `;rm ModuleName enable MyRole` `;chnlcmd` `;cc` | Sets a command's permission at the channel level. | `;cc "command name" enable SomeChannel` -`;chnlmdl` `;cm` | Sets a module's permission at the channel level. | `;cm "module name" enable SomeChannel` +`;chnlmdl` `;cm` | Sets a module's permission at the channel level. | `;cm ModuleName enable SomeChannel` `;allchnlmdls` `;acm` | Enable or disable all modules in a specified channel. | `;acm enable #SomeChannel` `;allrolemdls` `;arm` | Enable or disable all modules for a specific role. | `;arm [enable/disable] MyRole` `;allusrmdls` `;aum` | Enable or disable all modules for a specific user. | `;aum enable @someone` @@ -287,7 +288,7 @@ Command and aliases | Description | Usage ### Searches Command and aliases | Description | Usage ----------------|--------------|------- -`~weather` `~we` | Shows weather data for a specified city and a country. BOTH ARE REQUIRED. Use country abbrevations. | `~we Moscow RF` +`~weather` `~we` | Shows weather data for a specified city. You can also specify a country after a comma. | `~we Moscow, RU` `~youtube` `~yt` | Searches youtubes and shows the first result | `~yt query` `~imdb` `~omdb` | Queries omdb for movies or series, show first result. | `~imdb Batman vs Superman` `~randomcat` `~meow` | Shows a random cat image. | `~meow` diff --git a/src/NadekoBot/Modules/Help/Help.cs b/src/NadekoBot/Modules/Help/Help.cs index 2f25f31a..f1f1ea0e 100644 --- a/src/NadekoBot/Modules/Help/Help.cs +++ b/src/NadekoBot/Modules/Help/Help.cs @@ -38,8 +38,10 @@ namespace NadekoBot.Modules.Help public async Task Modules(IUserMessage umsg) { - await umsg.Channel.SendMessageAsync("📜 **List of modules:** ```css\n• " + string.Join("\n• ", NadekoBot.CommandService.Modules.Select(m => m.Name)) + $"\n``` ℹ️ **Type** `-commands module_name` **to get a list of commands in that module.** ***e.g.*** `-commands games`") - .ConfigureAwait(false); + var embed = new EmbedBuilder().WithOkColor().WithFooter(efb => efb.WithText($" ℹ️ Type `-cmds ModuleName` to get a list of commands in that module. eg `-cmds games`")) + .WithTitle("📜 List Of Modules").WithDescription("\n• " + string.Join("\n• ", NadekoBot.CommandService.Modules.Select(m => m.Name).OrderBy(s=>s))) + .Build(); + await umsg.Channel.EmbedAsync(embed).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index fb2998b9..3289c998 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -988,7 +988,7 @@ Sets a module's permission at the server level. - `{0}sm "module name" enable` + `{0}sm ModuleName enable` srvrcmd sc @@ -1006,7 +1006,7 @@ Sets a module's permission at the role level. - `{0}rm "module name" enable MyRole` + `{0}rm ModuleName enable MyRole` rolecmd rc @@ -1024,7 +1024,7 @@ Sets a module's permission at the channel level. - `{0}cm "module name" enable SomeChannel` + `{0}cm ModuleName enable SomeChannel` chnlcmd cc @@ -1042,7 +1042,7 @@ Sets a module's permission at the user level. - `{0}um "module name" enable SomeUsername` + `{0}um ModuleName enable SomeUsername` usrcmd uc From 937f775db4d547627b3bef0e6afdb44a2320a439 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 24 Dec 2016 08:05:43 +0100 Subject: [PATCH 06/14] together tube readded --- src/NadekoBot/Modules/Utility/Utility.cs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/NadekoBot/Modules/Utility/Utility.cs b/src/NadekoBot/Modules/Utility/Utility.cs index e4e2fe31..a61d6f69 100644 --- a/src/NadekoBot/Modules/Utility/Utility.cs +++ b/src/NadekoBot/Modules/Utility/Utility.cs @@ -15,6 +15,7 @@ using Discord.API; using Embed = Discord.API.Embed; using EmbedAuthor = Discord.API.EmbedAuthor; using EmbedField = Discord.API.EmbedField; +using System.Net.Http; namespace NadekoBot.Modules.Utility { @@ -27,6 +28,27 @@ namespace NadekoBot.Modules.Utility } + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task TogetherTube(IUserMessage imsg) + { + var channel = (ITextChannel)imsg.Channel; + + Uri target; + using (var http = new HttpClient()) + { + var res = await http.GetAsync("https://togethertube.com/room/create").ConfigureAwait(false); + target = res.RequestMessage.RequestUri; + } + + await channel.EmbedAsync(new EmbedBuilder().WithOkColor() + .WithAuthor(eab => eab.WithIconUrl("https://togethertube.com/assets/img/favicons/favicon-32x32.png") + .WithName("Together Tube") + .WithUrl("https://togethertube.com/")) + .WithDescription($"{imsg.Author.Mention} Here is your room link:\n{target}") + .Build()); + } + [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] public async Task WhosPlaying(IUserMessage umsg, [Remainder] string game = null) From 82704166ab7230c315616cb676b25efd1f493368 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 24 Dec 2016 08:30:20 +0100 Subject: [PATCH 07/14] .stats now show music stats, filter commands cleaned up --- .../Permissions/Commands/FilterCommands.cs | 23 +++--- src/NadekoBot/Modules/Utility/Utility.cs | 73 ++++--------------- 2 files changed, 27 insertions(+), 69 deletions(-) diff --git a/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs b/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs index d6f22fb5..ab2558f5 100644 --- a/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs +++ b/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs @@ -2,6 +2,7 @@ using Discord.Commands; using Microsoft.EntityFrameworkCore; using NadekoBot.Attributes; +using NadekoBot.Extensions; using NadekoBot.Services; using System.Collections.Concurrent; using System.Linq; @@ -77,12 +78,12 @@ namespace NadekoBot.Modules.Permissions if (enabled) { InviteFilteringServers.Add(channel.Guild.Id); - await channel.SendMessageAsync("✅ `Invite filtering enabled on this server.`").ConfigureAwait(false); + await channel.SendConfirmAsync("Invite filtering enabled on this server.").ConfigureAwait(false); } else { InviteFilteringServers.TryRemove(channel.Guild.Id); - await channel.SendMessageAsync("ℹ️ `Invite filtering disabled on this server.`").ConfigureAwait(false); + await channel.SendConfirmAsync("Invite filtering disabled on this server.").ConfigureAwait(false); } } @@ -110,12 +111,12 @@ namespace NadekoBot.Modules.Permissions if (removed == 0) { InviteFilteringChannels.Add(channel.Id); - await channel.SendMessageAsync("✅ `Invite filtering enabled on this channel.`").ConfigureAwait(false); + await channel.SendConfirmAsync("Invite filtering enabled on this channel.").ConfigureAwait(false); } else { InviteFilteringChannels.TryRemove(channel.Id); - await channel.SendMessageAsync("ℹ️ `Invite filtering disabled on this channel.`").ConfigureAwait(false); + await channel.SendConfirmAsync("Invite filtering disabled on this channel.").ConfigureAwait(false); } } @@ -136,12 +137,12 @@ namespace NadekoBot.Modules.Permissions if (enabled) { WordFilteringServers.Add(channel.Guild.Id); - await channel.SendMessageAsync("✅ `Word filtering enabled on this server.`").ConfigureAwait(false); + await channel.SendConfirmAsync("Word filtering enabled on this server.").ConfigureAwait(false); } else { WordFilteringServers.TryRemove(channel.Guild.Id); - await channel.SendMessageAsync("ℹ️ `Word filtering disabled on this server.`").ConfigureAwait(false); + await channel.SendConfirmAsync("Word filtering disabled on this server.").ConfigureAwait(false); } } @@ -169,12 +170,12 @@ namespace NadekoBot.Modules.Permissions if (removed == 0) { WordFilteringChannels.Add(channel.Id); - await channel.SendMessageAsync("✅ `Word filtering enabled on this channel.`").ConfigureAwait(false); + await channel.SendConfirmAsync("Word filtering enabled on this channel.").ConfigureAwait(false); } else { WordFilteringChannels.TryRemove(channel.Id); - await channel.SendMessageAsync("ℹ️ `Word filtering disabled on this channel.`").ConfigureAwait(false); + await channel.SendConfirmAsync("Word filtering disabled on this channel.").ConfigureAwait(false); } } @@ -207,13 +208,13 @@ namespace NadekoBot.Modules.Permissions if (removed == 0) { filteredWords.Add(word); - await channel.SendMessageAsync($"✅ Word `{word}` successfully added to the list of filtered words.") + await channel.SendConfirmAsync($"Word `{word}` successfully added to the list of filtered words.") .ConfigureAwait(false); } else { filteredWords.TryRemove(word); - await channel.SendMessageAsync($"ℹ️ Word `{word}` removed from the list of filtered words.") + await channel.SendConfirmAsync($"Word `{word}` removed from the list of filtered words.") .ConfigureAwait(false); } } @@ -227,7 +228,7 @@ namespace NadekoBot.Modules.Permissions ConcurrentHashSet filteredWords; ServerFilteredWords.TryGetValue(channel.Guild.Id, out filteredWords); - await channel.SendMessageAsync($"ℹ️ `List of banned words:`\n" + string.Join(",\n", filteredWords)) + await channel.SendConfirmAsync($"List of filtered words", string.Join("\n", filteredWords)) .ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/Utility/Utility.cs b/src/NadekoBot/Modules/Utility/Utility.cs index a61d6f69..f79e5fd1 100644 --- a/src/NadekoBot/Modules/Utility/Utility.cs +++ b/src/NadekoBot/Modules/Utility/Utility.cs @@ -207,64 +207,21 @@ namespace NadekoBot.Modules.Utility var stats = NadekoBot.Stats; await channel.EmbedAsync( - new Embed() - { - Author = new EmbedAuthor() - { - Name = $"NadekoBot v{StatsService.BotVersion}", - Url = "http://nadekobot.readthedocs.io/en/latest/", - IconUrl = "https://cdn.discordapp.com/avatars/116275390695079945/b21045e778ef21c96d175400e779f0fb.jpg" - }, - Fields = new[] { - new EmbedField() { - Name = Format.Bold("Author"), - Value = stats.Author, - Inline = true - }, - new EmbedField() { - Name = Format.Bold("Library"), - Value = stats.Library, - Inline = true - }, - new EmbedField() { - Name = Format.Bold("Bot ID"), - Value = NadekoBot.Client.GetCurrentUser().Id.ToString(), - Inline = true - }, - new EmbedField() { - Name = Format.Bold("Commands Ran"), - Value = stats.CommandsRan.ToString(), - Inline = true - }, - new EmbedField() { - Name = Format.Bold("Messages"), - Value = $"{stats.MessageCounter} ({stats.MessagesPerSecond:F2}/sec)", - Inline = true - }, - new EmbedField() { - Name = Format.Bold("Memory"), - Value = $"{stats.Heap} MB", - Inline = true - }, - new EmbedField() { - Name = Format.Bold("Owner ID(s)"), - Value = stats.OwnerIds, - Inline = true - }, - new EmbedField() { - Name = Format.Bold("Uptime"), - Value = stats.GetUptimeString("\n"), - Inline = true - }, - new EmbedField() { - Name = Format.Bold("Presence"), - Value = $"{NadekoBot.Client.GetGuilds().Count} Servers\n{stats.TextChannels} Text Channels\n{stats.VoiceChannels} Voice Channels", - Inline = true - }, - - }, - Color = 0x00bbd6 - }); + new EmbedBuilder().WithOkColor() + .WithAuthor(eab => eab.WithName($"NadekoBot v{StatsService.BotVersion}") + .WithUrl("http://nadekobot.readthedocs.io/en/latest/") + .WithIconUrl("https://cdn.discordapp.com/avatars/116275390695079945/b21045e778ef21c96d175400e779f0fb.jpg")) + .AddField(efb => efb.WithName(Format.Bold("Author")).WithValue(stats.Author).WithIsInline(true)) + .AddField(efb => efb.WithName(Format.Bold("Library")).WithValue(stats.Library).WithIsInline(true)) + .AddField(efb => efb.WithName(Format.Bold("Bot ID")).WithValue(NadekoBot.Client.GetCurrentUser().Id.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName(Format.Bold("Commands Ran")).WithValue(stats.CommandsRan.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName(Format.Bold("Messages")).WithValue($"{stats.MessageCounter} ({stats.MessagesPerSecond:F2}/sec)").WithIsInline(true)) + .AddField(efb => efb.WithName(Format.Bold("Memory")).WithValue($"{stats.Heap} MB").WithIsInline(true)) + .AddField(efb => efb.WithName(Format.Bold("Owner ID(s)")).WithValue(stats.OwnerIds).WithIsInline(true)) + .AddField(efb => efb.WithName(Format.Bold("Uptime")).WithValue(stats.GetUptimeString("\n")).WithIsInline(true)) + .AddField(efb => efb.WithName(Format.Bold("Presence")).WithValue($"{NadekoBot.Client.GetGuilds().Count} Servers\n{stats.TextChannels} Text Channels\n{stats.VoiceChannels} Voice Channels").WithIsInline(true)) + .WithFooter(efb => efb.WithText($"Playing {Music.Music.MusicPlayers.Where(mp => mp.Value.CurrentSong != null).Count()} songs, {Music.Music.MusicPlayers.Sum(mp => mp.Value.Playlist.Count)} queued.")) + .Build()); } private Regex emojiFinder { get; } = new Regex(@"<:(?.+?):(?\d*)>", RegexOptions.Compiled); From 9b26bd9ee5fd5ed305faf2b9e6ec72b35e4ef0df Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 24 Dec 2016 10:55:51 +0100 Subject: [PATCH 08/14] Can roll fate dice now with `$roll 5dF` --- .../Gambling/Commands/DiceRollCommand.cs | 39 +++++++++++++++++-- src/NadekoBot/Modules/Utility/Utility.cs | 2 + src/NadekoBot/Resources/CommandStrings.resx | 4 +- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs index 7b2c8118..71e17453 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs @@ -19,6 +19,9 @@ namespace NadekoBot.Modules.Gambling public class DriceRollCommands { private Regex dndRegex { get; } = new Regex(@"^(?\d+)d(?\d+)(?:\+(?\d+))?(?:\-(?\d+))?$", RegexOptions.Compiled); + private Regex fudgeRegex { get; } = new Regex(@"^(?\d+)d(?:F|f)$", RegexOptions.Compiled); + + private readonly char[] fateRolls = new[] { '-', ' ', '+' }; [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] @@ -86,6 +89,17 @@ namespace NadekoBot.Modules.Gambling await InternallDndRoll(umsg, arg, false).ConfigureAwait(false); } + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task FateRoll(IUserMessage msg, string arg) + { + var channel = (ITextChannel)msg.Channel; + + int n1; + Match match; + + } + private async Task InternalRoll(IUserMessage umsg, int num, bool ordered) { var channel = (ITextChannel)umsg.Channel; @@ -141,12 +155,29 @@ namespace NadekoBot.Modules.Gambling if (channel == null) return; - var rng = new NadekoRandom(); Match match; - if ((match = dndRegex.Match(arg)).Length != 0) + int n1; + int n2; + if ((match = fudgeRegex.Match(arg)).Length != 0 && + int.TryParse(match.Groups["n1"].ToString(), out n1) && + n1 > 0 && n1 < 500) { - int n1; - int n2; + var rng = new NadekoRandom(); + + var rolls = new List(); + + for (int i = 0; i < n1; i++) + { + rolls.Add(fateRolls[rng.Next(0, fateRolls.Length)]); + } + var embed = new EmbedBuilder().WithOkColor().WithDescription($"{umsg.Author.Mention} rolled {n1} fate {(n1 == 1 ? "die" : "dice")}.") + .AddField(efb => efb.WithName(Format.Bold("Result")) + .WithValue(string.Join(" ", rolls.Select(c => Format.Code($"[{c}]"))))); + await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + } + else if ((match = dndRegex.Match(arg)).Length != 0) + { + var rng = new NadekoRandom(); if (int.TryParse(match.Groups["n1"].ToString(), out n1) && int.TryParse(match.Groups["n2"].ToString(), out n2) && n1 <= 50 && n2 <= 100000 && n1 > 0 && n2 > 0) diff --git a/src/NadekoBot/Modules/Utility/Utility.cs b/src/NadekoBot/Modules/Utility/Utility.cs index f79e5fd1..5de70a5f 100644 --- a/src/NadekoBot/Modules/Utility/Utility.cs +++ b/src/NadekoBot/Modules/Utility/Utility.cs @@ -220,7 +220,9 @@ namespace NadekoBot.Modules.Utility .AddField(efb => efb.WithName(Format.Bold("Owner ID(s)")).WithValue(stats.OwnerIds).WithIsInline(true)) .AddField(efb => efb.WithName(Format.Bold("Uptime")).WithValue(stats.GetUptimeString("\n")).WithIsInline(true)) .AddField(efb => efb.WithName(Format.Bold("Presence")).WithValue($"{NadekoBot.Client.GetGuilds().Count} Servers\n{stats.TextChannels} Text Channels\n{stats.VoiceChannels} Voice Channels").WithIsInline(true)) +#if !GLOBAL_NADEKO .WithFooter(efb => efb.WithText($"Playing {Music.Music.MusicPlayers.Where(mp => mp.Value.CurrentSong != null).Count()} songs, {Music.Music.MusicPlayers.Sum(mp => mp.Value.Playlist.Count)} queued.")) +#endif .Build()); } diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 3289c998..fb067b65 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -1192,10 +1192,10 @@ roll - Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice. If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. + Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice. If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. Y can be a letter 'F' if you want to roll fate dice instead of dnd. - `{0}roll` or `{0}roll 7` or `{0}roll 3d5` + `{0}roll` or `{0}roll 7` or `{0}roll 3d5` or `{0}roll 5dF` rolluo From 6cdb4415842f4c6c28cc0c25324fd989325fc123 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 24 Dec 2016 11:01:06 +0100 Subject: [PATCH 09/14] Rolls prettier --- .../Modules/Gambling/Commands/DiceRollCommand.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs index 71e17453..4894d7c0 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs @@ -165,7 +165,7 @@ namespace NadekoBot.Modules.Gambling var rng = new NadekoRandom(); var rolls = new List(); - + for (int i = 0; i < n1; i++) { rolls.Add(fateRolls[rng.Next(0, fateRolls.Length)]); @@ -192,8 +192,11 @@ namespace NadekoBot.Modules.Gambling { arr[i] = rng.Next(1, n2 + 1) + add - sub; } - var elemCnt = 0; - await channel.SendConfirmAsync($"{umsg.Author.Mention} rolled {n1} {(n1 == 1 ? "die" : "dice")} `1 to {n2}` +`{add}` -`{sub}`.\n`Result:` " + string.Join(", ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => elemCnt++ % 2 == 0 ? $"**{x}**" : x.ToString()))).ConfigureAwait(false); + + var embed = new EmbedBuilder().WithOkColor().WithDescription($"{umsg.Author.Mention} rolled {n1} {(n1 == 1 ? "die" : "dice")} `1 to {n2}` +`{add}` -`{sub}`") + .AddField(efb => efb.WithName(Format.Bold("Result")) + .WithValue(string.Join(" ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => Format.Code(x.ToString()))))); + await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); } } } From ae10c92455d0ae03d8ab3dccb86e53a0e5d03ccf Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 24 Dec 2016 11:15:22 +0100 Subject: [PATCH 10/14] Repeat won't repost if the last message is the same --- .../Modules/Administration/Commands/LogCommand.cs | 2 ++ .../Modules/Administration/Commands/MessageRepeater.cs | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs index e2a49b11..374b97d5 100644 --- a/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs @@ -695,6 +695,8 @@ namespace NadekoBot.Modules.Administration logSetting.LogUserPresenceId = logSetting.LogVoicePresenceId = logSetting.LogVoicePresenceTTSId = (action.Value ? channel.Id : (ulong?)null); + + await uow.CompleteAsync().ConfigureAwait(false); } if (action.Value) await channel.SendMessageAsync("✅ Logging all events on this channel.").ConfigureAwait(false); diff --git a/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs b/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs index 583f0f05..2063a381 100644 --- a/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs +++ b/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs @@ -50,10 +50,16 @@ namespace NadekoBot.Modules.Administration { while (!token.IsCancellationRequested) { + var toSend = "🔄 " + Repeater.Message; await Task.Delay(Repeater.Interval, token).ConfigureAwait(false); + + var lastMsgInChannel = (await Channel.GetMessagesAsync(1)).FirstOrDefault(); + if (lastMsgInChannel.Id == oldMsg.Id) //don't send if it's the same message in the channel + continue; + if (oldMsg != null) try { await oldMsg.DeleteAsync(); } catch { } - try { oldMsg = await Channel.SendMessageAsync("🔄 " + Repeater.Message).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); try { source.Cancel(); } catch { } } + try { oldMsg = await Channel.SendMessageAsync(toSend).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); try { source.Cancel(); } catch { } } } } catch (OperationCanceledException) { } From 129fa9f827d2fb3a1317744152212676f1fe0c68 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 24 Dec 2016 11:50:08 +0100 Subject: [PATCH 11/14] Hangman now shows all guessed letters --- .../Games/Commands/Hangman/HangmanGame.cs | 23 +++++++++++---- src/NadekoBot/_Extensions/Extensions.cs | 28 ++++++++++++++++--- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs b/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs index 048f51f3..d8bf3e7c 100644 --- a/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs +++ b/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs @@ -116,7 +116,8 @@ namespace NadekoBot.Modules.Games.Commands.Hangman var embed = new EmbedBuilder().WithTitle("Hangman Game") .WithDescription(toSend) .AddField(efb => efb.WithName("It was").WithValue(Term.Word)) - .WithImage(eib => eib.WithUrl(Term.ImageUrl)); + .WithImage(eib => eib.WithUrl(Term.ImageUrl)) + .WithFooter(efb => efb.WithText(string.Join(" ", Guesses))); if (Errors >= MaxErrors) await GameChannel.EmbedAsync(embed.WithErrorColor().Build()).ConfigureAwait(false); else @@ -134,7 +135,13 @@ namespace NadekoBot.Modules.Games.Commands.Hangman MessagesSinceLastPost = 0; Task.Run(async () => { - try { await GameChannel.SendConfirmAsync("Hangman Game", ScrambledWord + "\n" + GetHangman()).ConfigureAwait(false); } catch { } + try + { + await GameChannel.SendConfirmAsync("Hangman Game", + ScrambledWord + "\n" + GetHangman(), + footer: string.Join(" ", Guesses)).ConfigureAwait(false); + } + catch { } }); } return Task.CompletedTask; @@ -151,9 +158,11 @@ namespace NadekoBot.Modules.Games.Commands.Hangman { if (Guesses.Contains(guess)) { + MessagesSinceLastPost = 0; ++Errors; if (Errors < MaxErrors) - await GameChannel.SendErrorAsync("Hangman Game", $"{msg.Author.Mention} Letter `{guess}` has already been used.\n" + ScrambledWord + "\n" + GetHangman()).ConfigureAwait(false); + await GameChannel.SendErrorAsync("Hangman Game", $"{msg.Author.Mention} Letter `{guess}` has already been used.\n" + ScrambledWord + "\n" + GetHangman(), + footer: string.Join(" ", Guesses)).ConfigureAwait(false); else await End().ConfigureAwait(false); return; @@ -170,14 +179,18 @@ namespace NadekoBot.Modules.Games.Commands.Hangman await End().ConfigureAwait(false); return; } - try { await GameChannel.SendConfirmAsync("Hangman Game", $"{msg.Author.Mention} guessed a letter `{guess}`!\n" + ScrambledWord + "\n" + GetHangman()).ConfigureAwait(false); } catch { } + MessagesSinceLastPost = 0; + try { await GameChannel.SendConfirmAsync("Hangman Game", $"{msg.Author.Mention} guessed a letter `{guess}`!\n" + ScrambledWord + "\n" + GetHangman(), + footer: string.Join(" ", Guesses)).ConfigureAwait(false); } catch { } } else { + MessagesSinceLastPost = 0; ++Errors; if (Errors < MaxErrors) - await GameChannel.SendErrorAsync("Hangman Game", $"{msg.Author.Mention} Letter `{guess}` does not exist.\n" + ScrambledWord + "\n" + GetHangman()).ConfigureAwait(false); + await GameChannel.SendErrorAsync("Hangman Game", $"{msg.Author.Mention} Letter `{guess}` does not exist.\n" + ScrambledWord + "\n" + GetHangman(), + footer: string.Join(" ", Guesses)).ConfigureAwait(false); else await End().ConfigureAwait(false); } diff --git a/src/NadekoBot/_Extensions/Extensions.cs b/src/NadekoBot/_Extensions/Extensions.cs index 4c98b5dd..168fb87a 100644 --- a/src/NadekoBot/_Extensions/Extensions.cs +++ b/src/NadekoBot/_Extensions/Extensions.cs @@ -114,14 +114,34 @@ namespace NadekoBot.Extensions public static Task EmbedAsync(this IMessageChannel ch, Discord.API.Embed embed, string msg = "") => ch.SendMessageAsync(msg, embed: embed); - public static Task SendErrorAsync(this IMessageChannel ch, string title, string error, string url = null) - => ch.SendMessageAsync("", embed: new Embed() { Description = error, Title = title, Url = url, Color = NadekoBot.ErrorColor }); + public static Task SendErrorAsync(this IMessageChannel ch, string title, string error, string url = null, string footer = null) + => ch.SendMessageAsync("", embed: new Embed() + { + Description = error, + Title = title, + Url = url, + Color = NadekoBot.ErrorColor, + Footer = new Discord.API.EmbedFooter() + { + Text = footer + } + }); public static Task SendErrorAsync(this IMessageChannel ch, string error) => ch.SendMessageAsync("", embed: new Embed() { Description = error, Color = NadekoBot.ErrorColor }); - public static Task SendConfirmAsync(this IMessageChannel ch, string title, string text, string url = null) - => ch.SendMessageAsync("", embed: new Embed() { Description = text, Title = title, Url = url, Color = NadekoBot.OkColor }); + public static Task SendConfirmAsync(this IMessageChannel ch, string title, string text, string url = null, string footer = null) + => ch.SendMessageAsync("", embed: new Embed() + { + Description = text, + Title = title, + Url = url, + Color = NadekoBot.OkColor, + Footer = new Discord.API.EmbedFooter() + { + Text = footer + } + }); public static Task SendConfirmAsync(this IMessageChannel ch, string text) => ch.SendMessageAsync("", embed: new Embed() { Description = text, Color = NadekoBot.OkColor }); From 11245283be9e8863e54f74afdfd8476d9eaab078 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 24 Dec 2016 12:26:37 +0100 Subject: [PATCH 12/14]
properly handled in ~ani and ~mang --- .../Gambling/Commands/DiceRollCommand.cs | 11 --- .../Searches/Commands/AnimeSearchCommands.cs | 81 +++++-------------- src/NadekoBot/_Extensions/Extensions.cs | 3 + 3 files changed, 25 insertions(+), 70 deletions(-) diff --git a/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs index 4894d7c0..f1c3252a 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs @@ -89,17 +89,6 @@ namespace NadekoBot.Modules.Gambling await InternallDndRoll(umsg, arg, false).ConfigureAwait(false); } - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - public async Task FateRoll(IUserMessage msg, string arg) - { - var channel = (ITextChannel)msg.Channel; - - int n1; - Match match; - - } - private async Task InternalRoll(IUserMessage umsg, int num, bool ordered) { var channel = (ITextChannel)umsg.Channel; diff --git a/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs b/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs index a21ea1f5..b90be209 100644 --- a/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs @@ -46,7 +46,8 @@ namespace NadekoBot.Modules.Searches anilistToken = JObject.Parse(stringContent)["access_token"].ToString(); } } - catch (Exception ex) { + catch (Exception ex) + { _log.Error(ex); } }, null, TimeSpan.FromSeconds(0), TimeSpan.FromMinutes(29)); @@ -69,34 +70,15 @@ namespace NadekoBot.Modules.Searches return; } - var embed = new Discord.API.Embed() - { - Description = animeData.Synopsis, - Title = animeData.title_english, - Url = animeData.Link, - Image = new Discord.API.EmbedImage() { - Url = animeData.image_url_lge - }, - Fields = new[] { - new Discord.API.EmbedField() { - Inline = true, - Name = "Episodes", - Value = animeData.total_episodes.ToString() - }, - new Discord.API.EmbedField() { - Inline = true, - Name = "Status", - Value = animeData.AiringStatus.ToString() - }, - new Discord.API.EmbedField() { - Inline = true, - Name = "Genres", - Value = String.Join(", ", animeData.Genres) - } - }, - Color = NadekoBot.OkColor - }; - await channel.EmbedAsync(embed).ConfigureAwait(false); + var embed = new EmbedBuilder().WithColor(NadekoBot.OkColor) + .WithDescription(animeData.Synopsis.Replace("
", Environment.NewLine)) + .WithTitle(animeData.title_english) + .WithUrl(animeData.Link) + .WithImageUrl(animeData.image_url_lge) + .AddField(efb => efb.WithName("Episodes").WithValue(animeData.total_episodes.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName("Status").WithValue(animeData.AiringStatus.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName("Genres").WithValue(String.Join(", ", animeData.Genres)).WithIsInline(true)); + await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -116,36 +98,16 @@ namespace NadekoBot.Modules.Searches return; } - var embed = new Discord.API.Embed() - { - Description = mangaData.Synopsis, - Title = mangaData.title_english, - Url = mangaData.Link, - Image = new Discord.API.EmbedImage() - { - Url = mangaData.image_url_lge - }, - Fields = new[] { - new Discord.API.EmbedField() { - Inline = true, - Name = "Chapters", - Value = mangaData.total_chapters.ToString() - }, - new Discord.API.EmbedField() { - Inline = true, - Name = "Status", - Value = mangaData.publishing_status.ToString() - }, - new Discord.API.EmbedField() { - Inline = true, - Name = "Genres", - Value = String.Join(", ", mangaData.Genres) - } - }, - Color = NadekoBot.OkColor - }; + var embed = new EmbedBuilder().WithColor(NadekoBot.OkColor) + .WithDescription(mangaData.Synopsis) + .WithTitle(mangaData.title_english) + .WithUrl(mangaData.Link) + .WithImageUrl(mangaData.image_url_lge) + .AddField(efb => efb.WithName("Episodes").WithValue(mangaData.total_chapters.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName("Status").WithValue(mangaData.publishing_status.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName("Genres").WithValue(String.Join(", ", mangaData.Genres)).WithIsInline(true)); - await channel.EmbedAsync(embed).ConfigureAwait(false); + await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); } private async Task GetAnimeData(string query) @@ -165,7 +127,8 @@ namespace NadekoBot.Modules.Searches return await Task.Run(() => { try { return JsonConvert.DeserializeObject(aniData); } catch { return null; } }).ConfigureAwait(false); } } - catch (Exception ex) { + catch (Exception ex) + { _log.Warn(ex, "Failed anime search for {0}", query); return null; } diff --git a/src/NadekoBot/_Extensions/Extensions.cs b/src/NadekoBot/_Extensions/Extensions.cs index 168fb87a..439f8c1a 100644 --- a/src/NadekoBot/_Extensions/Extensions.cs +++ b/src/NadekoBot/_Extensions/Extensions.cs @@ -25,6 +25,9 @@ namespace NadekoBot.Extensions http.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); } + public static EmbedBuilder WithImageUrl(this EmbedBuilder eb, string url) => + eb.WithImage(eib => eib.WithUrl(url)); + public static EmbedBuilder WithOkColor(this EmbedBuilder eb) => eb.WithColor(NadekoBot.OkColor); From f3052eb4e58efc25bea4e855c7602dff2fa070b4 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 24 Dec 2016 12:49:18 +0100 Subject: [PATCH 13/14] ~ani/~manga searches now have score --- .../Modules/Searches/Commands/AnimeSearchCommands.cs | 8 +++++--- .../Modules/Searches/Commands/Models/AnimeResult.cs | 2 ++ .../Modules/Searches/Commands/Models/MangaResult.cs | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs b/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs index b90be209..52f9fda0 100644 --- a/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs @@ -77,7 +77,8 @@ namespace NadekoBot.Modules.Searches .WithImageUrl(animeData.image_url_lge) .AddField(efb => efb.WithName("Episodes").WithValue(animeData.total_episodes.ToString()).WithIsInline(true)) .AddField(efb => efb.WithName("Status").WithValue(animeData.AiringStatus.ToString()).WithIsInline(true)) - .AddField(efb => efb.WithName("Genres").WithValue(String.Join(", ", animeData.Genres)).WithIsInline(true)); + .AddField(efb => efb.WithName("Genres").WithValue(String.Join(", ", animeData.Genres)).WithIsInline(true)) + .WithFooter(efb => efb.WithText("Score: " + animeData.average_score + " / 100")); await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); } @@ -99,13 +100,14 @@ namespace NadekoBot.Modules.Searches } var embed = new EmbedBuilder().WithColor(NadekoBot.OkColor) - .WithDescription(mangaData.Synopsis) + .WithDescription(mangaData.Synopsis.Replace("
", Environment.NewLine)) .WithTitle(mangaData.title_english) .WithUrl(mangaData.Link) .WithImageUrl(mangaData.image_url_lge) .AddField(efb => efb.WithName("Episodes").WithValue(mangaData.total_chapters.ToString()).WithIsInline(true)) .AddField(efb => efb.WithName("Status").WithValue(mangaData.publishing_status.ToString()).WithIsInline(true)) - .AddField(efb => efb.WithName("Genres").WithValue(String.Join(", ", mangaData.Genres)).WithIsInline(true)); + .AddField(efb => efb.WithName("Genres").WithValue(String.Join(", ", mangaData.Genres)).WithIsInline(true)) + .WithFooter(efb => efb.WithText("Score: " + mangaData.average_score + " / 100")); await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); } diff --git a/src/NadekoBot/Modules/Searches/Commands/Models/AnimeResult.cs b/src/NadekoBot/Modules/Searches/Commands/Models/AnimeResult.cs index 3d08da6e..e5d779c0 100644 --- a/src/NadekoBot/Modules/Searches/Commands/Models/AnimeResult.cs +++ b/src/NadekoBot/Modules/Searches/Commands/Models/AnimeResult.cs @@ -13,6 +13,8 @@ namespace NadekoBot.Modules.Searches.Models public string description; public string image_url_lge; public string[] Genres; + public string average_score; + public string Link => "http://anilist.co/anime/" + id; public string Synopsis => description?.Substring(0, description.Length > 500 ? 500 : description.Length) + "..."; } diff --git a/src/NadekoBot/Modules/Searches/Commands/Models/MangaResult.cs b/src/NadekoBot/Modules/Searches/Commands/Models/MangaResult.cs index 5e262209..a0d47962 100644 --- a/src/NadekoBot/Modules/Searches/Commands/Models/MangaResult.cs +++ b/src/NadekoBot/Modules/Searches/Commands/Models/MangaResult.cs @@ -10,6 +10,7 @@ namespace NadekoBot.Modules.Searches.Models public int total_volumes; public string description; public string[] Genres; + public string average_score; public string Link => "http://anilist.co/manga/" + id; public string Synopsis => description?.Substring(0, description.Length > 500 ? 500 : description.Length) + "..."; } From 88e1f15d6e3212140378e7e3e2aeab869fd51446 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 24 Dec 2016 14:13:48 +0100 Subject: [PATCH 14/14] Log commands are owner only --- src/NadekoBot/Modules/Administration/Commands/LogCommand.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs index 374b97d5..8e2d76b8 100644 --- a/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs @@ -736,6 +736,7 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.Administrator)] + [OwnerOnly] public async Task LogEvents(IUserMessage imsg) { await imsg.Channel.SendConfirmAsync("Log events you can subscribe to:", String.Join(", ", Enum.GetNames(typeof(LogType)).Cast())); @@ -744,6 +745,7 @@ namespace NadekoBot.Modules.Administration [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.Administrator)] + [OwnerOnly] public async Task Log(IUserMessage imsg, LogType type) { var channel = (ITextChannel)imsg.Channel;