From 0a7bbd60f77870e8f3e41334a4a19e1a4f14adf0 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Fri, 31 Mar 2017 14:07:18 +0200 Subject: [PATCH] Startup commands added. Closes #195; .sclist .scadd .scrm .scclr. Won't support music commands atm, but that can come in the future, there is support for it (your current voice channel is recorded when adding) --- .../Attributes/OwnerOnlyAttribute.cs | 2 +- ...0170331093025_startup-commands.Designer.cs | 1385 +++++++++++++++++ .../20170331093025_startup-commands.cs | 51 + .../NadekoSqliteContextModelSnapshot.cs | 39 + .../Modules/Administration/Administration.cs | 2 +- .../Administration/Commands/SelfCommands.cs | 168 +- .../Commands/UserPunishCommands.cs | 5 +- .../CustomReactions/CustomReactions.cs | 2 +- .../Games/Commands/CleverBotCommands.cs | 2 +- .../Resources/CommandStrings.Designer.cs | 135 ++ src/NadekoBot/Resources/CommandStrings.resx | 45 + .../Resources/ResponseStrings.Designer.cs | 72 + src/NadekoBot/Resources/ResponseStrings.resx | 24 + src/NadekoBot/Services/CommandHandler.cs | 274 ++-- .../Services/Database/Models/BotConfig.cs | 13 + .../Repositories/IBotConfigRepository.cs | 7 +- .../Repositories/Impl/BotConfigRepository.cs | 11 +- 17 files changed, 2090 insertions(+), 147 deletions(-) create mode 100644 src/NadekoBot/Migrations/20170331093025_startup-commands.Designer.cs create mode 100644 src/NadekoBot/Migrations/20170331093025_startup-commands.cs diff --git a/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs b/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs index 410a24af..eefc489c 100644 --- a/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs +++ b/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs @@ -6,6 +6,6 @@ namespace NadekoBot.Attributes public class OwnerOnlyAttribute : PreconditionAttribute { public override Task CheckPermissions(ICommandContext context, CommandInfo executingCommand,IDependencyMap depMap) => - Task.FromResult((NadekoBot.Credentials.IsOwner(context.User) ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("Not owner"))); + Task.FromResult((NadekoBot.Credentials.IsOwner(context.User) || NadekoBot.Client.CurrentUser.Id == context.User.Id ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("Not owner"))); } } \ No newline at end of file diff --git a/src/NadekoBot/Migrations/20170331093025_startup-commands.Designer.cs b/src/NadekoBot/Migrations/20170331093025_startup-commands.Designer.cs new file mode 100644 index 00000000..a91943d7 --- /dev/null +++ b/src/NadekoBot/Migrations/20170331093025_startup-commands.Designer.cs @@ -0,0 +1,1385 @@ +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("20170331093025_startup-commands")] + partial class startupcommands + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { + modelBuilder + .HasAnnotation("ProductVersion", "1.1.0-rtm-22752"); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Action"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Seconds"); + + b.Property("UserThreshold"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId") + .IsUnique(); + + b.ToTable("AntiRaidSetting"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamIgnore", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AntiSpamSettingId"); + + b.Property("ChannelId"); + + b.Property("DateAdded"); + + b.HasKey("Id"); + + b.HasIndex("AntiSpamSettingId"); + + b.ToTable("AntiSpamIgnore"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Action"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("MessageThreshold"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId") + .IsUnique(); + + b.ToTable("AntiSpamSetting"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("DateAdded"); + + 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("BetflipMultiplier"); + + b.Property("Betroll100Multiplier"); + + b.Property("Betroll67Multiplier"); + + b.Property("Betroll91Multiplier"); + + b.Property("BufferSize"); + + b.Property("CurrencyDropAmount"); + + b.Property("CurrencyGenerationChance"); + + b.Property("CurrencyGenerationCooldown"); + + b.Property("CurrencyName"); + + b.Property("CurrencyPluralName"); + + b.Property("CurrencySign"); + + b.Property("DMHelpString"); + + b.Property("DateAdded"); + + b.Property("ErrorColor"); + + b.Property("ForwardMessages"); + + b.Property("ForwardToAllOwners"); + + b.Property("HelpString"); + + b.Property("Locale"); + + b.Property("MigrationVersion"); + + b.Property("MinimumBetAmount"); + + b.Property("OkColor"); + + b.Property("RemindMessageFormat"); + + b.Property("RotatingStatuses"); + + b.Property("TriviaCurrencyReward"); + + 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("DateAdded"); + + 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("DateAdded"); + + 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.CommandAlias", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Mapping"); + + b.Property("Trigger"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("CommandAlias"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("CommandName"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Seconds"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("CommandCooldown"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandPrice", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("CommandName"); + + b.Property("DateAdded"); + + b.Property("Price"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.HasIndex("Price") + .IsUnique(); + + b.ToTable("CommandPrice"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ConvertUnit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + 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("DateAdded"); + + 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("DateAdded"); + + 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("AutoDeleteTrigger"); + + b.Property("DateAdded"); + + b.Property("DmResponse"); + + 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.DiscordUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AvatarId"); + + b.Property("DateAdded"); + + b.Property("Discriminator"); + + b.Property("UserId"); + + b.Property("Username"); + + b.HasKey("Id"); + + b.HasAlternateKey("UserId"); + + b.ToTable("DiscordUser"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Donator", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Amount"); + + b.Property("DateAdded"); + + 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("DateAdded"); + + 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("DateAdded"); + + 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("DateAdded"); + + 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("DateAdded"); + + 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("DateAdded"); + + 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("DateAdded"); + + 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("Locale"); + + b.Property("LogSettingId"); + + b.Property("MuteRoleName"); + + b.Property("PermissionRole"); + + b.Property("RootPermissionId"); + + b.Property("SendChannelByeMessage"); + + b.Property("SendChannelGreetMessage"); + + b.Property("SendDmGreetMessage"); + + b.Property("TimeZoneId"); + + b.Property("VerbosePermissions"); + + b.Property("VoicePlusTextEnabled"); + + b.Property("WarningsInitialized"); + + b.HasKey("Id"); + + b.HasIndex("GuildId") + .IsUnique(); + + b.HasIndex("LogSettingId"); + + b.HasIndex("RootPermissionId"); + + b.ToTable("GuildConfigs"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildRepeater", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("GuildId"); + + b.Property("Interval"); + + b.Property("Message"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("GuildRepeater"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("DateAdded"); + + 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("DateAdded"); + + 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("ChannelCreated"); + + b.Property("ChannelCreatedId"); + + b.Property("ChannelDestroyed"); + + b.Property("ChannelDestroyedId"); + + b.Property("ChannelId"); + + b.Property("ChannelUpdated"); + + b.Property("ChannelUpdatedId"); + + b.Property("DateAdded"); + + b.Property("IsLogging"); + + b.Property("LogOtherId"); + + b.Property("LogUserPresence"); + + b.Property("LogUserPresenceId"); + + b.Property("LogVoicePresence"); + + b.Property("LogVoicePresenceId"); + + 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("UserMutedId"); + + b.Property("UserPresenceChannelId"); + + b.Property("UserUnbanned"); + + b.Property("UserUnbannedId"); + + b.Property("UserUpdated"); + + b.Property("UserUpdatedId"); + + b.Property("VoicePresenceChannelId"); + + b.HasKey("Id"); + + b.ToTable("LogSettings"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("DateAdded"); + + 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("DateAdded"); + + b.Property("Name"); + + b.HasKey("Id"); + + b.ToTable("MusicPlaylists"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("MutedUserId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + 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.Permissionv2", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Index"); + + b.Property("PrimaryTarget"); + + b.Property("PrimaryTargetId"); + + b.Property("SecondaryTarget"); + + b.Property("SecondaryTargetName"); + + b.Property("State"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("Permissionv2"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("DateAdded"); + + 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("DateAdded"); + + 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("DateAdded"); + + 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("DateAdded"); + + 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("DateAdded"); + + 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.SelfAssignedRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildId"); + + b.Property("RoleId"); + + b.HasKey("Id"); + + b.HasIndex("GuildId", "RoleId") + .IsUnique(); + + b.ToTable("SelfAssignableRoles"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.StartupCommand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("ChannelId"); + + b.Property("ChannelName"); + + b.Property("CommandText"); + + b.Property("DateAdded"); + + b.Property("GuildId"); + + b.Property("GuildName"); + + b.Property("Index"); + + b.Property("VoiceChannelId"); + + b.Property("VoiceChannelName"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("StartupCommand"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("UnmuteAt"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("UnmuteTimer"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.UserPokeTypes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("UserId"); + + b.Property("type"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("PokeGame"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.VcRoleInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("RoleId"); + + b.Property("VoiceChannelId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("VcRoleInfo"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AffinityId"); + + b.Property("ClaimerId"); + + b.Property("DateAdded"); + + b.Property("Price"); + + b.Property("WaifuId"); + + b.HasKey("Id"); + + b.HasIndex("AffinityId"); + + b.HasIndex("ClaimerId"); + + b.HasIndex("WaifuId") + .IsUnique(); + + b.ToTable("WaifuInfo"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuUpdate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("NewId"); + + b.Property("OldId"); + + b.Property("UpdateType"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("NewId"); + + b.HasIndex("OldId"); + + b.HasIndex("UserId"); + + b.ToTable("WaifuUpdates"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Warning", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("Forgiven"); + + b.Property("ForgivenBy"); + + b.Property("GuildId"); + + b.Property("Moderator"); + + b.Property("Reason"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.ToTable("Warnings"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.WarningPunishment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Count"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Punishment"); + + b.Property("Time"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("WarningPunishment"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig") + .WithOne("AntiRaidSetting") + .HasForeignKey("NadekoBot.Services.Database.Models.AntiRaidSetting", "GuildConfigId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamIgnore", b => + { + b.HasOne("NadekoBot.Services.Database.Models.AntiSpamSetting") + .WithMany("IgnoredChannels") + .HasForeignKey("AntiSpamSettingId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamSetting", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig") + .WithOne("AntiSpamSetting") + .HasForeignKey("NadekoBot.Services.Database.Models.AntiSpamSetting", "GuildConfigId") + .OnDelete(DeleteBehavior.Cascade); + }); + + 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.CommandAlias", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("CommandAliases") + .HasForeignKey("GuildConfigId"); + }); + + 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.CommandPrice", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("CommandPrices") + .HasForeignKey("BotConfigId"); + }); + + 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.GuildRepeater", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("GuildRepeaters") + .HasForeignKey("GuildConfigId"); + }); + + 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.MutedUserId", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("MutedUsers") + .HasForeignKey("GuildConfigId"); + }); + + 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.Permissionv2", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("Permissions") + .HasForeignKey("GuildConfigId"); + }); + + 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"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.StartupCommand", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("StartupCommands") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("UnmuteTimers") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.VcRoleInfo", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("VcRoleInfos") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b => + { + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Affinity") + .WithMany() + .HasForeignKey("AffinityId"); + + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Claimer") + .WithMany() + .HasForeignKey("ClaimerId"); + + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Waifu") + .WithOne() + .HasForeignKey("NadekoBot.Services.Database.Models.WaifuInfo", "WaifuId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuUpdate", b => + { + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "New") + .WithMany() + .HasForeignKey("NewId"); + + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Old") + .WithMany() + .HasForeignKey("OldId"); + + b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.WarningPunishment", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("WarnPunishments") + .HasForeignKey("GuildConfigId"); + }); + } + } +} diff --git a/src/NadekoBot/Migrations/20170331093025_startup-commands.cs b/src/NadekoBot/Migrations/20170331093025_startup-commands.cs new file mode 100644 index 00000000..d3cd52a9 --- /dev/null +++ b/src/NadekoBot/Migrations/20170331093025_startup-commands.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace NadekoBot.Migrations +{ + public partial class startupcommands : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "StartupCommand", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + BotConfigId = table.Column(nullable: true), + ChannelId = table.Column(nullable: false), + ChannelName = table.Column(nullable: true), + CommandText = table.Column(nullable: true), + DateAdded = table.Column(nullable: true), + GuildId = table.Column(nullable: true), + GuildName = table.Column(nullable: true), + Index = table.Column(nullable: false), + VoiceChannelId = table.Column(nullable: true), + VoiceChannelName = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_StartupCommand", x => x.Id); + table.ForeignKey( + name: "FK_StartupCommand_BotConfig_BotConfigId", + column: x => x.BotConfigId, + principalTable: "BotConfig", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_StartupCommand_BotConfigId", + table: "StartupCommand", + column: "BotConfigId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "StartupCommand"); + } + } +} diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index 97e9b393..83771957 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -950,6 +950,38 @@ namespace NadekoBot.Migrations b.ToTable("SelfAssignableRoles"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.StartupCommand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("ChannelId"); + + b.Property("ChannelName"); + + b.Property("CommandText"); + + b.Property("DateAdded"); + + b.Property("GuildId"); + + b.Property("GuildName"); + + b.Property("Index"); + + b.Property("VoiceChannelId"); + + b.Property("VoiceChannelName"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("StartupCommand"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b => { b.Property("Id") @@ -1288,6 +1320,13 @@ namespace NadekoBot.Migrations .HasForeignKey("BotConfigId"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.StartupCommand", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("StartupCommands") + .HasForeignKey("BotConfigId"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b => { b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") diff --git a/src/NadekoBot/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs index 2f076ae3..905243ba 100644 --- a/src/NadekoBot/Modules/Administration/Administration.cs +++ b/src/NadekoBot/Modules/Administration/Administration.cs @@ -32,7 +32,7 @@ namespace NadekoBot.Modules.Administration } - private static Task DelMsgOnCmd_Handler(SocketUserMessage msg, CommandInfo cmd) + private static Task DelMsgOnCmd_Handler(IUserMessage msg, CommandInfo cmd) { var _ = Task.Run(async () => { diff --git a/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs index 89d23094..3af86611 100644 --- a/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs @@ -10,6 +10,8 @@ using System.Net.Http; using System.Threading.Tasks; using Discord.WebSocket; using NadekoBot.Services; +using NadekoBot.Services.Database.Models; +using Microsoft.EntityFrameworkCore; namespace NadekoBot.Modules.Administration { @@ -31,6 +33,166 @@ namespace NadekoBot.Modules.Administration _forwardDMs = config.ForwardMessages; _forwardDMsToAllOwners = config.ForwardToAllOwners; } + + var _ = Task.Run(async () => + { +#if !GLOBAL_NADEKO + await Task.Delay(2000); +#else + await Task.Delay(10000); +#endif + foreach (var cmd in NadekoBot.BotConfig.StartupCommands) + { + if (cmd.GuildId != null) + { + var guild = NadekoBot.Client.GetGuild(cmd.GuildId.Value); + var channel = guild?.GetChannel(cmd.ChannelId) as SocketTextChannel; + if (channel == null) + continue; + + try + { + var msg = await channel.SendMessageAsync(cmd.CommandText).ConfigureAwait(false); + await NadekoBot.CommandHandler.TryRunCommand(guild, channel, msg).ConfigureAwait(false); + //msg.DeleteAfter(5); + } + catch { } + } + } + }); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [OwnerOnly] + public async Task StartupCommandAdd([Remainder] string cmdText) + { + var guser = ((IGuildUser)Context.User); + var cmd = new StartupCommand() + { + CommandText = cmdText, + ChannelId = Context.Channel.Id, + ChannelName = Context.Channel.Name, + GuildId = Context.Guild?.Id, + GuildName = Context.Guild?.Name, + VoiceChannelId = guser.VoiceChannel?.Id, + VoiceChannelName = guser.VoiceChannel?.Name, + }; + using (var uow = DbHandler.UnitOfWork()) + { + uow.BotConfig + .GetOrCreate(set => set.Include(x => x.StartupCommands)) + .StartupCommands.Add(cmd); + await uow.CompleteAsync().ConfigureAwait(false); + } + + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() + .WithTitle(GetText("scadd")) + .AddField(efb => efb.WithName(GetText("server")) + .WithValue(cmd.GuildId == null ? $"-" : $"{cmd.GuildName}/{cmd.GuildId}").WithIsInline(true)) + .AddField(efb => efb.WithName(GetText("channel")) + .WithValue($"{cmd.ChannelName}/{cmd.ChannelId}").WithIsInline(true)) + .AddField(efb => efb.WithName(GetText("command_text")) + .WithValue(cmdText).WithIsInline(false))); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [OwnerOnly] + public async Task StartupCommands(int page = 1) + { + if (page < 1) + return; + page -= 1; + IEnumerable scmds; + using (var uow = DbHandler.UnitOfWork()) + { + scmds = uow.BotConfig + .GetOrCreate(set => set.Include(x => x.StartupCommands)) + .StartupCommands + .OrderBy(x => x.Id) + .ToArray(); + } + scmds = scmds.Skip(page * 5).Take(5); + if (!scmds.Any()) + { + await ReplyErrorLocalized("startcmdlist_none").ConfigureAwait(false); + } + else + { + await Context.Channel.SendConfirmAsync("", string.Join("\n--\n", scmds.Select(x => + { + string str = Format.Code(GetText("server")) + ": " + (x.GuildId == null ? "-" : x.GuildName + "/" + x.GuildId); + + str += $@" +{Format.Code(GetText("channel"))}: {x.ChannelName}/{x.ChannelId} +{Format.Code(GetText("command_text"))}: {x.CommandText}"; + return str; + })),footer: GetText("page", page + 1)) + .ConfigureAwait(false); + } + } + + [NadekoCommand, Usage, Description, Aliases] + [OwnerOnly] + public async Task Wait(int miliseconds) + { + if (miliseconds <= 0) + return; + Context.Message.DeleteAfter(0); + try + { + var msg = await Context.Channel.SendConfirmAsync($"⏲ {miliseconds}ms") + .ConfigureAwait(false); + msg.DeleteAfter(miliseconds / 1000); + } + catch { } + + await Task.Delay(miliseconds); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [OwnerOnly] + public async Task StartupCommandRemove([Remainder] string cmdText) + { + StartupCommand cmd; + using (var uow = DbHandler.UnitOfWork()) + { + var cmds = uow.BotConfig + .GetOrCreate(set => set.Include(x => x.StartupCommands)) + .StartupCommands; + cmd = cmds + .FirstOrDefault(x => x.CommandText.ToLowerInvariant() == cmdText.ToLowerInvariant()); + + if (cmd != null) + { + cmds.Remove(cmd); + await uow.CompleteAsync().ConfigureAwait(false); + } + } + + if(cmd == null) + await ReplyErrorLocalized("scrm_fail").ConfigureAwait(false); + else + await ReplyConfirmLocalized("scrm").ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [OwnerOnly] + public async Task StartupCommandsClear() + { + using (var uow = DbHandler.UnitOfWork()) + { + uow.BotConfig + .GetOrCreate(set => set.Include(x => x.StartupCommands)) + .StartupCommands + .Clear(); + uow.Complete(); + } + + await ReplyConfirmLocalized("startcmds_cleared").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -68,7 +230,7 @@ namespace NadekoBot.Modules.Administration } - public static async Task HandleDmForwarding(SocketMessage msg, List ownerChannels) + public static async Task HandleDmForwarding(IUserMessage msg, List ownerChannels) { if (_forwardDMs && ownerChannels.Any()) { @@ -157,7 +319,7 @@ namespace NadekoBot.Modules.Administration else { await server.DeleteAsync().ConfigureAwait(false); - await ReplyConfirmLocalized("deleted_server",Format.Bold(server.Name)).ConfigureAwait(false); + await ReplyConfirmLocalized("deleted_server", Format.Bold(server.Name)).ConfigureAwait(false); } } @@ -332,4 +494,4 @@ namespace NadekoBot.Modules.Administration } } } -} +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs b/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs index ded760c2..f37b864c 100644 --- a/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs @@ -61,7 +61,10 @@ namespace NadekoBot.Modules.Administration switch (p.Punishment) { case PunishmentAction.Mute: - await MuteCommands.TimedMute(user, TimeSpan.FromMinutes(p.Time)); + if (p.Time == 0) + await MuteCommands.MuteUser(user).ConfigureAwait(false); + else + await MuteCommands.TimedMute(user, TimeSpan.FromMinutes(p.Time)).ConfigureAwait(false); break; case PunishmentAction.Kick: await user.KickAsync().ConfigureAwait(false); diff --git a/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs b/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs index f28a7bc9..ac6fd4c9 100644 --- a/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs +++ b/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs @@ -59,7 +59,7 @@ namespace NadekoBot.Modules.CustomReactions public void ClearStats() => ReactionStats.Clear(); - public static CustomReaction TryGetCustomReaction(SocketUserMessage umsg) + public static CustomReaction TryGetCustomReaction(IUserMessage umsg) { var channel = umsg.Channel as SocketTextChannel; if (channel == null) diff --git a/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs b/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs index 0e85e4b0..fd426be3 100644 --- a/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs @@ -40,7 +40,7 @@ namespace NadekoBot.Modules.Games _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s"); } - public static async Task TryAsk(SocketUserMessage msg) + public static async Task TryAsk(IUserMessage msg) { var channel = msg.Channel as ITextChannel; diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index 61163a92..20c12253 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -7889,6 +7889,114 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to scadd. + /// + public static string startupcommandadd_cmd { + get { + return ResourceManager.GetString("startupcommandadd_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Adds a command to the list of commands which will be executed automatically in the current channel, in the order they were added in, by the bot when it startups up.. + /// + public static string startupcommandadd_desc { + get { + return ResourceManager.GetString("startupcommandadd_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}scadd .stats`. + /// + public static string startupcommandadd_usage { + get { + return ResourceManager.GetString("startupcommandadd_usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to scrm. + /// + public static string startupcommandremove_cmd { + get { + return ResourceManager.GetString("startupcommandremove_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Removes a startup command with the provided command text.. + /// + public static string startupcommandremove_desc { + get { + return ResourceManager.GetString("startupcommandremove_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}scrm .stats`. + /// + public static string startupcommandremove_usage { + get { + return ResourceManager.GetString("startupcommandremove_usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to sclist. + /// + public static string startupcommands_cmd { + get { + return ResourceManager.GetString("startupcommands_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lists all startup commands in the order they will be executed in.. + /// + public static string startupcommands_desc { + get { + return ResourceManager.GetString("startupcommands_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}sclist`. + /// + public static string startupcommands_usage { + get { + return ResourceManager.GetString("startupcommands_usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to scclr. + /// + public static string startupcommandsclear_cmd { + get { + return ResourceManager.GetString("startupcommandsclear_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Removes all startup commands.. + /// + public static string startupcommandsclear_desc { + get { + return ResourceManager.GetString("startupcommandsclear_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}scclr`. + /// + public static string startupcommandsclear_usage { + get { + return ResourceManager.GetString("startupcommandsclear_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to startwar sw. /// @@ -9131,6 +9239,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to wait. + /// + public static string wait_cmd { + get { + return ResourceManager.GetString("wait_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Used only as a startup command. Waits a certain number of miliseconds before continuing the execution of the following startup commands.. + /// + public static string wait_desc { + get { + return ResourceManager.GetString("wait_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}wait 3000`. + /// + public static string wait_usage { + get { + return ResourceManager.GetString("wait_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to warn. /// diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index db8b3f50..5d1d0539 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3240,6 +3240,42 @@ `{0}warn @b1nzy` + + scadd + + + Adds a command to the list of commands which will be executed automatically in the current channel, in the order they were added in, by the bot when it startups up. + + + `{0}scadd .stats` + + + scrm + + + Removes a startup command with the provided command text. + + + `{0}scrm .stats` + + + scclr + + + Removes all startup commands. + + + `{0}scclr` + + + sclist + + + Lists all startup commands in the order they will be executed in. + + + `{0}sclist` + unban @@ -3249,6 +3285,15 @@ `{0}unban kwoth#1234` or `{0}unban 123123123` + + wait + + + Used only as a startup command. Waits a certain number of miliseconds before continuing the execution of the following startup commands. + + + `{0}wait 3000` + warnclear warnc diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index 34e12752..ea980b1f 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -231,6 +231,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Channel. + /// + public static string administration_channel { + get { + return ResourceManager.GetString("administration_channel", resourceCulture); + } + } + /// /// Looks up a localized string similar to Cleaned up.. /// @@ -240,6 +249,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Command Text. + /// + public static string administration_command_text { + get { + return ResourceManager.GetString("administration_command_text", resourceCulture); + } + } + /// /// Looks up a localized string similar to Content. /// @@ -1233,6 +1251,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to New startup command added.. + /// + public static string administration_scadd { + get { + return ResourceManager.GetString("administration_scadd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Startup command successfully removed.. + /// + public static string administration_scrm { + get { + return ResourceManager.GetString("administration_scrm", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Startup command not found.. + /// + public static string administration_scrm_fail { + get { + return ResourceManager.GetString("administration_scrm_fail", resourceCulture); + } + } + /// /// Looks up a localized string similar to You already have {0} role.. /// @@ -1332,6 +1377,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Server. + /// + public static string administration_server { + get { + return ResourceManager.GetString("administration_server", resourceCulture); + } + } + /// /// Looks up a localized string similar to New avatar set!. /// @@ -1486,6 +1540,24 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to No startup commands on this page.. + /// + public static string administration_startcmdlist_none { + get { + return ResourceManager.GetString("administration_startcmdlist_none", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cleared all startup commands.. + /// + public static string administration_startcmds_cleared { + get { + return ResourceManager.GetString("administration_startcmds_cleared", resourceCulture); + } + } + /// /// Looks up a localized string similar to Text channel created.. /// diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index a94761da..92087d6b 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2278,6 +2278,12 @@ Owner ID: {2} Competitive playtime + + Channel + + + Command Text + Moderator @@ -2287,6 +2293,24 @@ Owner ID: {2} Reason + + New startup command added. + + + Startup command successfully removed. + + + Startup command not found. + + + Server + + + No startup commands on this page. + + + Cleared all startup commands. + User {0} has been unbanned. diff --git a/src/NadekoBot/Services/CommandHandler.cs b/src/NadekoBot/Services/CommandHandler.cs index 17521cab..31f30932 100644 --- a/src/NadekoBot/Services/CommandHandler.cs +++ b/src/NadekoBot/Services/CommandHandler.cs @@ -37,7 +37,7 @@ namespace NadekoBot.Services private List ownerChannels { get; set; } = new List(); - public event Func CommandExecuted = delegate { return Task.CompletedTask; }; + public event Func CommandExecuted = delegate { return Task.CompletedTask; }; //userid/msg count public ConcurrentDictionary UserMessagesSent { get; } = new ConcurrentDictionary(); @@ -109,7 +109,7 @@ namespace NadekoBot.Services return Task.CompletedTask; } - private async Task TryRunCleverbot(SocketUserMessage usrMsg, IGuild guild) + private async Task TryRunCleverbot(IUserMessage usrMsg, IGuild guild) { if (guild == null) return false; @@ -130,14 +130,13 @@ namespace NadekoBot.Services return false; } - private bool IsBlacklisted(IGuild guild, SocketUserMessage usrMsg) => - usrMsg.Author?.Id == 193022505026453504 || // he requested to be blacklisted from self-hosted bots + private bool IsBlacklisted(IGuild guild, IUserMessage usrMsg) => (guild != null && BlacklistCommands.BlacklistedGuilds.Contains(guild.Id)) || BlacklistCommands.BlacklistedChannels.Contains(usrMsg.Channel.Id) || BlacklistCommands.BlacklistedUsers.Contains(usrMsg.Author.Id); private const float _oneThousandth = 1.0f / 1000; - private Task LogSuccessfulExecution(SocketUserMessage usrMsg, ExecuteCommandResult exec, SocketTextChannel channel, int exec1, int exec2, int exec3, int total) + private Task LogSuccessfulExecution(IUserMessage usrMsg, ExecuteCommandResult exec, ITextChannel channel, int exec1, int exec2, int exec3, int total) { _log.Info("Command Executed after {4}/{5}/{6}/{7}s\n\t" + "User: {0}\n\t" + @@ -156,7 +155,7 @@ namespace NadekoBot.Services return Task.CompletedTask; } - private void LogErroredExecution(SocketUserMessage usrMsg, ExecuteCommandResult exec, SocketTextChannel channel, int exec1, int exec2, int exec3, int total) + private void LogErroredExecution(IUserMessage usrMsg, ExecuteCommandResult exec, ITextChannel channel, int exec1, int exec2, int exec3, int total) { _log.Warn("Command Errored after {5}/{6}/{7}/{8}s\n\t" + "User: {0}\n\t" + @@ -176,7 +175,7 @@ namespace NadekoBot.Services ); } - private async Task InviteFiltered(IGuild guild, SocketUserMessage usrMsg) + private async Task InviteFiltered(IGuild guild, IUserMessage usrMsg) { if ((Permissions.FilterCommands.InviteFilteringChannels.Contains(usrMsg.Channel.Id) || Permissions.FilterCommands.InviteFilteringServers.Contains(guild.Id)) && @@ -196,7 +195,7 @@ namespace NadekoBot.Services return false; } - private async Task WordFiltered(IGuild guild, SocketUserMessage usrMsg) + private async Task WordFiltered(IGuild guild, IUserMessage usrMsg) { var filteredChannelWords = Permissions.FilterCommands.FilteredWordsForChannel(usrMsg.Channel.Id, guild.Id) ?? new ConcurrentHashSet(); var filteredServerWords = Permissions.FilterCommands.FilteredWordsForServer(guild.Id) ?? new ConcurrentHashSet(); @@ -232,8 +231,6 @@ namespace NadekoBot.Services if (msg.Author.IsBot || !NadekoBot.Ready) //no bots, wait until bot connected and initialized return; - var execTime = Environment.TickCount; - var usrMsg = msg as SocketUserMessage; if (usrMsg == null) //has to be an user message, not system/other messages. return; @@ -248,131 +245,7 @@ namespace NadekoBot.Services var channel = msg.Channel as SocketTextChannel; var guild = channel?.Guild; - if (guild != null && guild.OwnerId != msg.Author.Id) - { - if (await InviteFiltered(guild, usrMsg).ConfigureAwait(false)) - return; - - if (await WordFiltered(guild, usrMsg).ConfigureAwait(false)) - return; - } - - if (IsBlacklisted(guild, usrMsg)) - return; - - var exec1 = Environment.TickCount - execTime; - - var cleverBotRan = await Task.Run(() => TryRunCleverbot(usrMsg, guild)).ConfigureAwait(false); - if (cleverBotRan) - return; - - var exec2 = Environment.TickCount - execTime; - - // maybe this message is a custom reaction - // todo log custom reaction executions. return struct with info - var cr = await Task.Run(() => CustomReactions.TryGetCustomReaction(usrMsg)).ConfigureAwait(false); - if (cr != null) //if it was, don't execute the command - { - try - { - if (guild != null) - { - PermissionCache pc; - if (!Permissions.Cache.TryGetValue(guild.Id, out pc)) - { - using (var uow = DbHandler.UnitOfWork()) - { - var config = uow.GuildConfigs.For(guild.Id, - set => set.Include(x => x.Permissions)); - Permissions.UpdateCache(config); - } - Permissions.Cache.TryGetValue(guild.Id, out pc); - if (pc == null) - throw new Exception("Cache is null."); - } - int index; - if ( - !pc.Permissions.CheckPermissions(usrMsg, cr.Trigger, "ActualCustomReactions", - out index)) - { - //todo print in guild actually - var returnMsg = - $"Permission number #{index + 1} **{pc.Permissions[index].GetCommand(guild)}** is preventing this action."; - _log.Info(returnMsg); - return; - } - } - await cr.Send(usrMsg).ConfigureAwait(false); - - if (cr.AutoDeleteTrigger) - { - try { await msg.DeleteAsync().ConfigureAwait(false); } catch { } - } - } - catch (Exception ex) - { - _log.Warn("Sending CREmbed failed"); - _log.Warn(ex); - } - return; - } - - var exec3 = Environment.TickCount - execTime; - - string messageContent = usrMsg.Content; - if (guild != null) - { - ConcurrentDictionary maps; - if (Modules.Utility.Utility.CommandMapCommands.AliasMaps.TryGetValue(guild.Id, out maps)) - { - string newMessageContent; - if (maps.TryGetValue(messageContent.Trim().ToLowerInvariant(), out newMessageContent)) - { - _log.Info(@"--Mapping Command-- - GuildId: {0} - Trigger: {1} - Mapping: {2}", guild.Id, messageContent, newMessageContent); - var oldMessageContent = messageContent; - messageContent = newMessageContent; - - try { await usrMsg.Channel.SendConfirmAsync($"{oldMessageContent} => {newMessageContent}").ConfigureAwait(false); } catch { } - } - } - } - - - // execute the command and measure the time it took - var exec = await Task.Run(() => ExecuteCommand(new CommandContext(_client, usrMsg), messageContent, DependencyMap.Empty, MultiMatchHandling.Best)).ConfigureAwait(false); - execTime = Environment.TickCount - execTime; - - if (exec.Result.IsSuccess) - { - await CommandExecuted(usrMsg, exec.CommandInfo).ConfigureAwait(false); - await LogSuccessfulExecution(usrMsg, exec, channel, exec1, exec2, exec3, execTime).ConfigureAwait(false); - } - else if (!exec.Result.IsSuccess && exec.Result.Error != CommandError.UnknownCommand) - { - LogErroredExecution(usrMsg, exec, channel, exec1, exec2, exec3, execTime); - if (guild != null && exec.CommandInfo != null && exec.Result.Error == CommandError.Exception) - { - if (exec.PermissionCache != null && exec.PermissionCache.Verbose) - try { await msg.Channel.SendMessageAsync("⚠️ " + exec.Result.ErrorReason).ConfigureAwait(false); } catch { } - } - } - else - { - if (msg.Channel is IPrivateChannel) - { - // rofl, gotta do this to prevent dm help message being sent to - // users who are voting on private polls (sending a number in a DM) - int vote; - if (int.TryParse(msg.Content, out vote)) return; - - await msg.Channel.SendMessageAsync(Help.DMHelpString).ConfigureAwait(false); - - await SelfCommands.HandleDmForwarding(msg, ownerChannels).ConfigureAwait(false); - } - } + await TryRunCommand(guild, channel, usrMsg); } catch (Exception ex) { @@ -388,6 +261,137 @@ namespace NadekoBot.Services return Task.CompletedTask; } + public async Task TryRunCommand(SocketGuild guild, ITextChannel channel, IUserMessage usrMsg) + { + var execTime = Environment.TickCount; + + if (guild != null && guild.OwnerId != usrMsg.Author.Id) + { + if (await InviteFiltered(guild, usrMsg).ConfigureAwait(false)) + return; + + if (await WordFiltered(guild, usrMsg).ConfigureAwait(false)) + return; + } + + if (IsBlacklisted(guild, usrMsg)) + return; + + var exec1 = Environment.TickCount - execTime; + + var cleverBotRan = await Task.Run(() => TryRunCleverbot(usrMsg, guild)).ConfigureAwait(false); + if (cleverBotRan) + return; + + var exec2 = Environment.TickCount - execTime; + + // maybe this message is a custom reaction + // todo log custom reaction executions. return struct with info + var cr = await Task.Run(() => CustomReactions.TryGetCustomReaction(usrMsg)).ConfigureAwait(false); + if (cr != null) //if it was, don't execute the command + { + try + { + if (guild != null) + { + PermissionCache pc; + if (!Permissions.Cache.TryGetValue(guild.Id, out pc)) + { + using (var uow = DbHandler.UnitOfWork()) + { + var config = uow.GuildConfigs.For(guild.Id, + set => set.Include(x => x.Permissions)); + Permissions.UpdateCache(config); + } + Permissions.Cache.TryGetValue(guild.Id, out pc); + if (pc == null) + throw new Exception("Cache is null."); + } + int index; + if ( + !pc.Permissions.CheckPermissions(usrMsg, cr.Trigger, "ActualCustomReactions", + out index)) + { + //todo print in guild actually + var returnMsg = + $"Permission number #{index + 1} **{pc.Permissions[index].GetCommand(guild)}** is preventing this action."; + _log.Info(returnMsg); + return; + } + } + await cr.Send(usrMsg).ConfigureAwait(false); + + if (cr.AutoDeleteTrigger) + { + try { await usrMsg.DeleteAsync().ConfigureAwait(false); } catch { } + } + } + catch (Exception ex) + { + _log.Warn("Sending CREmbed failed"); + _log.Warn(ex); + } + return; + } + + var exec3 = Environment.TickCount - execTime; + + string messageContent = usrMsg.Content; + if (guild != null) + { + ConcurrentDictionary maps; + if (Modules.Utility.Utility.CommandMapCommands.AliasMaps.TryGetValue(guild.Id, out maps)) + { + string newMessageContent; + if (maps.TryGetValue(messageContent.Trim().ToLowerInvariant(), out newMessageContent)) + { + _log.Info(@"--Mapping Command-- + GuildId: {0} + Trigger: {1} + Mapping: {2}", guild.Id, messageContent, newMessageContent); + var oldMessageContent = messageContent; + messageContent = newMessageContent; + + try { await usrMsg.Channel.SendConfirmAsync($"{oldMessageContent} => {newMessageContent}").ConfigureAwait(false); } catch { } + } + } + } + + + // execute the command and measure the time it took + var exec = await Task.Run(() => ExecuteCommand(new CommandContext(_client, usrMsg), messageContent, DependencyMap.Empty, MultiMatchHandling.Best)).ConfigureAwait(false); + execTime = Environment.TickCount - execTime; + + if (exec.Result.IsSuccess) + { + await CommandExecuted(usrMsg, exec.CommandInfo).ConfigureAwait(false); + await LogSuccessfulExecution(usrMsg, exec, channel, exec1, exec2, exec3, execTime).ConfigureAwait(false); + } + else if (!exec.Result.IsSuccess && exec.Result.Error != CommandError.UnknownCommand) + { + LogErroredExecution(usrMsg, exec, channel, exec1, exec2, exec3, execTime); + if (guild != null && exec.CommandInfo != null && exec.Result.Error == CommandError.Exception) + { + if (exec.PermissionCache != null && exec.PermissionCache.Verbose) + try { await usrMsg.Channel.SendMessageAsync("⚠️ " + exec.Result.ErrorReason).ConfigureAwait(false); } catch { } + } + } + else + { + if (usrMsg.Channel is IPrivateChannel) + { + // rofl, gotta do this to prevent dm help message being sent to + // users who are voting on private polls (sending a number in a DM) + int vote; + if (int.TryParse(usrMsg.Content, out vote)) return; + + await usrMsg.Channel.SendMessageAsync(Help.DMHelpString).ConfigureAwait(false); + + await SelfCommands.HandleDmForwarding(usrMsg, ownerChannels).ConfigureAwait(false); + } + } + } + public Task ExecuteCommandAsync(CommandContext context, int argPos, IDependencyMap dependencyMap = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) => ExecuteCommand(context, context.Message.Content.Substring(argPos), dependencyMap, multiMatchHandling); diff --git a/src/NadekoBot/Services/Database/Models/BotConfig.cs b/src/NadekoBot/Services/Database/Models/BotConfig.cs index 8ff90e8a..b25dc744 100644 --- a/src/NadekoBot/Services/Database/Models/BotConfig.cs +++ b/src/NadekoBot/Services/Database/Models/BotConfig.cs @@ -61,6 +61,19 @@ Nadeko Support Server: https://discord.gg/nadekobot"; public string OkColor { get; set; } = "71cd40"; public string ErrorColor { get; set; } = "ee281f"; public string Locale { get; set; } = null; + public List StartupCommands { get; set; } + } + + public class StartupCommand : DbEntity, IIndexed + { + public int Index { get; set; } + public string CommandText { get; set; } + public ulong ChannelId { get; set; } + public string ChannelName { get; set; } + public ulong? GuildId { get; set; } + public string GuildName { get; set; } + public ulong? VoiceChannelId { get; set; } + public string VoiceChannelName { get; set; } } public class PlayingStatus :DbEntity diff --git a/src/NadekoBot/Services/Database/Repositories/IBotConfigRepository.cs b/src/NadekoBot/Services/Database/Repositories/IBotConfigRepository.cs index 7f9f3dd5..7a2adf63 100644 --- a/src/NadekoBot/Services/Database/Repositories/IBotConfigRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/IBotConfigRepository.cs @@ -1,9 +1,12 @@ -using NadekoBot.Services.Database.Models; +using Microsoft.EntityFrameworkCore; +using NadekoBot.Services.Database.Models; +using System; +using System.Linq; namespace NadekoBot.Services.Database.Repositories { public interface IBotConfigRepository : IRepository { - BotConfig GetOrCreate(); + BotConfig GetOrCreate(Func, IQueryable> includes = null); } } diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/BotConfigRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/BotConfigRepository.cs index 2aa0bf83..1e40f86c 100644 --- a/src/NadekoBot/Services/Database/Repositories/Impl/BotConfigRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/Impl/BotConfigRepository.cs @@ -1,6 +1,7 @@ using NadekoBot.Services.Database.Models; using System.Linq; using Microsoft.EntityFrameworkCore; +using System; namespace NadekoBot.Services.Database.Repositories.Impl { @@ -10,15 +11,21 @@ namespace NadekoBot.Services.Database.Repositories.Impl { } - public BotConfig GetOrCreate() + public BotConfig GetOrCreate(Func, IQueryable> includes = null) { - var config = _set.Include(bc => bc.RotatingStatusMessages) + BotConfig config; + + if (includes == null) + config = _set.Include(bc => bc.RotatingStatusMessages) .Include(bc => bc.RaceAnimals) .Include(bc => bc.Blacklist) .Include(bc => bc.EightBallResponses) .Include(bc => bc.ModulePrefixes) + .Include(bc => bc.StartupCommands) //.Include(bc => bc.CommandCosts) .FirstOrDefault(); + else + config = includes(_set).FirstOrDefault(); if (config == null) {