From 2d73f4bdfde4dd4adcd1d832928178eada46d260 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Thu, 30 Mar 2017 03:51:54 +0200 Subject: [PATCH 01/98] .warn command, needs testing --- ...0170330000613_warning-commands.Designer.cs | 1346 +++++++++++++++++ .../20170330000613_warning-commands.cs | 78 + .../NadekoSqliteContextModelSnapshot.cs | 55 + .../Modules/Administration/Administration.cs | 95 -- .../Commands/LocalizationCommands.cs | 21 +- .../Commands/UserPunishCommands.cs | 358 +++++ .../Resources/CommandStrings.Designer.cs | 135 ++ src/NadekoBot/Resources/CommandStrings.resx | 45 + .../Resources/ResponseStrings.Designer.cs | 117 ++ src/NadekoBot/Resources/ResponseStrings.resx | 39 + .../Services/Database/IUnitOfWork.cs | 1 + .../Services/Database/Models/GuildConfig.cs | 10 +- .../Services/Database/Models/Warning.cs | 12 + .../Services/Database/NadekoContext.cs | 5 + .../Repositories/IWarningsRepository.cs | 11 + .../Impl/GuildConfigRepository.cs | 33 +- .../Repositories/Impl/WarningsRepository.cs | 37 + src/NadekoBot/Services/Database/UnitOfWork.cs | 3 + 18 files changed, 2293 insertions(+), 108 deletions(-) create mode 100644 src/NadekoBot/Migrations/20170330000613_warning-commands.Designer.cs create mode 100644 src/NadekoBot/Migrations/20170330000613_warning-commands.cs create mode 100644 src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs create mode 100644 src/NadekoBot/Services/Database/Models/Warning.cs create mode 100644 src/NadekoBot/Services/Database/Repositories/IWarningsRepository.cs create mode 100644 src/NadekoBot/Services/Database/Repositories/Impl/WarningsRepository.cs diff --git a/src/NadekoBot/Migrations/20170330000613_warning-commands.Designer.cs b/src/NadekoBot/Migrations/20170330000613_warning-commands.Designer.cs new file mode 100644 index 00000000..28a99d1d --- /dev/null +++ b/src/NadekoBot/Migrations/20170330000613_warning-commands.Designer.cs @@ -0,0 +1,1346 @@ +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("20170330000613_warning-commands")] + partial class warningcommands + { + 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.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.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/20170330000613_warning-commands.cs b/src/NadekoBot/Migrations/20170330000613_warning-commands.cs new file mode 100644 index 00000000..5fb96271 --- /dev/null +++ b/src/NadekoBot/Migrations/20170330000613_warning-commands.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace NadekoBot.Migrations +{ + public partial class warningcommands : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "WarningsInitialized", + table: "GuildConfigs", + nullable: false, + defaultValue: false); + + migrationBuilder.CreateTable( + name: "Warnings", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + DateAdded = table.Column(nullable: true), + Forgiven = table.Column(nullable: false), + ForgivenBy = table.Column(nullable: true), + GuildId = table.Column(nullable: false), + Moderator = table.Column(nullable: true), + Reason = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Warnings", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "WarningPunishment", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Count = table.Column(nullable: false), + DateAdded = table.Column(nullable: true), + GuildConfigId = table.Column(nullable: true), + Punishment = table.Column(nullable: false), + Time = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_WarningPunishment", x => x.Id); + table.ForeignKey( + name: "FK_WarningPunishment_GuildConfigs_GuildConfigId", + column: x => x.GuildConfigId, + principalTable: "GuildConfigs", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_WarningPunishment_GuildConfigId", + table: "WarningPunishment", + column: "GuildConfigId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Warnings"); + + migrationBuilder.DropTable( + name: "WarningPunishment"); + + migrationBuilder.DropColumn( + name: "WarningsInitialized", + table: "GuildConfigs"); + } + } +} diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index 18195d44..97e9b393 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -559,6 +559,8 @@ namespace NadekoBot.Migrations b.Property("VoicePlusTextEnabled"); + b.Property("WarningsInitialized"); + b.HasKey("Id"); b.HasIndex("GuildId") @@ -1060,6 +1062,52 @@ namespace NadekoBot.Migrations 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") @@ -1285,6 +1333,13 @@ namespace NadekoBot.Migrations .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/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs index 4eb9d28c..2f076ae3 100644 --- a/src/NadekoBot/Modules/Administration/Administration.cs +++ b/src/NadekoBot/Modules/Administration/Administration.cs @@ -218,101 +218,6 @@ namespace NadekoBot.Modules.Administration } } - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequireUserPermission(GuildPermission.BanMembers)] - [RequireBotPermission(GuildPermission.BanMembers)] - public async Task Ban(IGuildUser user, [Remainder] string msg = null) - { - if (Context.User.Id != user.Guild.OwnerId && (user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max())) - { - await ReplyErrorLocalized("hierarchy").ConfigureAwait(false); - return; - } - if (!string.IsNullOrWhiteSpace(msg)) - { - try - { - await user.SendErrorAsync(GetText("bandm", Format.Bold(Context.Guild.Name), msg)); - } - catch - { - // ignored - } - } - - await Context.Guild.AddBanAsync(user, 7).ConfigureAwait(false); - await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() - .WithTitle("⛔️ " + GetText("banned_user")) - .AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true)) - .AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true))) - .ConfigureAwait(false); - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequireUserPermission(GuildPermission.KickMembers)] - [RequireUserPermission(GuildPermission.ManageMessages)] - [RequireBotPermission(GuildPermission.BanMembers)] - public async Task Softban(IGuildUser user, [Remainder] string msg = null) - { - if (Context.User.Id != user.Guild.OwnerId && user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max()) - { - await ReplyErrorLocalized("hierarchy").ConfigureAwait(false); - return; - } - - if (!string.IsNullOrWhiteSpace(msg)) - { - try - { - await user.SendErrorAsync(GetText("sbdm", Format.Bold(Context.Guild.Name), msg)); - } - catch - { - // ignored - } - } - - await Context.Guild.AddBanAsync(user, 7).ConfigureAwait(false); - try { await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); } - catch { await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); } - - await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() - .WithTitle("☣ " + GetText("sb_user")) - .AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true)) - .AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true))) - .ConfigureAwait(false); - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequireUserPermission(GuildPermission.KickMembers)] - [RequireBotPermission(GuildPermission.KickMembers)] - public async Task Kick(IGuildUser user, [Remainder] string msg = null) - { - if (Context.Message.Author.Id != user.Guild.OwnerId && user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max()) - { - await ReplyErrorLocalized("hierarchy").ConfigureAwait(false); - return; - } - if (!string.IsNullOrWhiteSpace(msg)) - { - try - { - await user.SendErrorAsync(GetText("kickdm", Format.Bold(Context.Guild.Name), msg)); - } - catch { } - } - - await user.KickAsync().ConfigureAwait(false); - await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() - .WithTitle(GetText("kicked_user")) - .AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true)) - .AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true))) - .ConfigureAwait(false); - } - [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [RequireUserPermission(GuildPermission.DeafenMembers)] diff --git a/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs b/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs index b61b2722..bc4a0952 100644 --- a/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs @@ -16,25 +16,26 @@ namespace NadekoBot.Modules.Administration [Group] public class LocalizationCommands : NadekoSubmodule { + //Română, România private ImmutableDictionary supportedLocales { get; } = new Dictionary() { - {"zh-TW", "Chinese (Traditional), China" }, - {"zh-CN", "Chinese (Simplified), China"}, + {"zh-TW", "繁體中文, 台灣" }, + {"zh-CN", "简体中文, 中华人民共和国"}, {"nl-NL", "Dutch, Netherlands"}, {"en-US", "English, United States"}, - {"fr-FR", "French, France"}, + {"fr-FR", "Français, France"}, {"de-DE", "German, Germany"}, {"he-IL", "Hebrew, Israel" }, - {"it-IT", "Italian, Italy" }, + {"it-IT", "Italiano, Italia" }, //{"ja-JP", "Japanese, Japan"}, - {"ko-KR", "Korean, Korea" }, + {"ko-KR", "Korean, South Korea" }, {"nb-NO", "Norwegian (bokmål), Norway"}, - {"pl-PL", "Polish, Poland" }, - {"pt-BR", "Portuguese, Brazil"}, + {"pl-PL", "Polski, Polska" }, + {"pt-BR", "Português Brasileiro, Brasil"}, {"ru-RU", "Russian, Russia"}, - {"sr-Cyrl-RS", "Serbian, Serbia - Cyrillic"}, - {"es-ES", "Spanish, Spain"}, - {"sv-SE", "Swedish, Sweden"}, + {"sr-Cyrl-RS", "Српски, Србија"}, + {"es-ES", "Español, España"}, + {"sv-SE", "Svenska, Sverige"}, {"tr-TR", "Turkish, Turkey" } }.ToImmutableDictionary(); diff --git a/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs b/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs new file mode 100644 index 00000000..0f54037f --- /dev/null +++ b/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs @@ -0,0 +1,358 @@ +using Discord; +using Discord.Commands; +using Discord.WebSocket; +using Microsoft.EntityFrameworkCore; +using NadekoBot.Attributes; +using NadekoBot.Extensions; +using NadekoBot.Services; +using NadekoBot.Services.Database.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace NadekoBot.Modules.Administration +{ + public partial class Administration + { + [Group] + public class UserPunishCommands : NadekoSubmodule + { + private async Task InternalWarn(IGuild guild, ulong userId, string modName, string reason) + { + if (string.IsNullOrWhiteSpace(reason)) + reason = "-"; + + var guildId = guild.Id; + + var warn = new Warning() + { + UserId = userId, + GuildId = guildId, + Forgiven = false, + Reason = reason, + Moderator = modName, + }; + + int warnings; + List ps; + using (var uow = DbHandler.UnitOfWork()) + { + ps = uow.GuildConfigs.For(guildId, set => set.Include(x => x.WarnPunishments)) + .WarnPunishments; + + uow.Warnings.Add(warn); + + warnings = uow.Warnings + .For(guildId, userId) + .Where(w => !w.Forgiven && w.UserId == userId) + .Count(); + + uow.Complete(); + } + + var p = ps.FirstOrDefault(x => x.Count == warnings); + + if (p != null) + { + var user = await guild.GetUserAsync(userId); + if (user == null) + return; + switch (p.Punishment) + { + case PunishmentAction.Mute: + await MuteCommands.TimedMute(user, TimeSpan.FromMinutes(p.Time)); + break; + case PunishmentAction.Kick: + await user.KickAsync().ConfigureAwait(false); + break; + case PunishmentAction.Ban: + await guild.AddBanAsync(user).ConfigureAwait(false); + break; + default: + break; + } + } + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public async Task Warn(IGuildUser user, [Remainder] string reason = null) + { + try + { + await (await user.CreateDMChannelAsync()).EmbedAsync(new EmbedBuilder().WithErrorColor() + .WithDescription(GetText("warned_on", Context.Guild.ToString())) + .AddField(efb => efb.WithName(GetText("moderator")).WithValue(Context.User.ToString())) + .AddField(efb => efb.WithName(GetText("reason")).WithValue(reason ?? "-"))) + .ConfigureAwait(false); + } + catch { } + await InternalWarn(Context.Guild, user.Id, Context.User.ToString(), reason).ConfigureAwait(false); + + await ReplyConfirmLocalized("user_warned", Format.Bold(user.ToString())).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public Task Warnlog(int page, IGuildUser user) + => Warnlog(page, user.Id); + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public Task Warnlog(IGuildUser user) + => Warnlog(user.Id); + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public Task Warnlog(int page, ulong userId) + => InternalWarnlog(userId, page - 1); + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public Task Warnlog(ulong userId) + => InternalWarnlog(userId, 0); + + private async Task InternalWarnlog(ulong userId, int page) + { + if (page < 0) + return; + Warning[] warnings; + using (var uow = DbHandler.UnitOfWork()) + { + warnings = uow.Warnings.For(Context.Guild.Id, userId); + } + + warnings = warnings.Skip(page * 9) + .Take(9) + .ToArray(); + + var embed = new EmbedBuilder().WithOkColor() + .WithTitle(GetText("warnlog_for", (Context.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString())) + .WithFooter(efb => efb.WithText(GetText("page", page + 1))); + + if (!warnings.Any()) + { + embed.WithDescription(GetText("warnings_none")); + } + else + { + foreach (var w in warnings) + { + var name = GetText("warned_on_by", w.DateAdded.Value.ToString("dd.MM.yyy"), w.DateAdded.Value.ToString("HH:mm"), w.Moderator); + if (w.Forgiven) + name = Format.Strikethrough(name) + GetText("warn_cleared_by", w.ForgivenBy); + + embed.AddField(x => x + .WithName(name) + .WithValue(w.Reason)); + } + } + + await Context.Channel.EmbedAsync(embed); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public Task Warnclear(IGuildUser user) + => Warnclear(user.Id); + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public async Task Warnclear(ulong userId) + { + using (var uow = DbHandler.UnitOfWork()) + { + await uow.Warnings.ForgiveAll(Context.Guild.Id, userId, Context.User.ToString()).ConfigureAwait(false); + uow.Complete(); + } + + await ReplyConfirmLocalized("warnings_cleared", + (Context.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString()).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public async Task WarnPunish(int number, PunishmentAction punish, int time = 0) + { + if (punish != PunishmentAction.Mute && time != 0) + return; + if (number <= 0) + return; + + using (var uow = DbHandler.UnitOfWork()) + { + var ps = uow.GuildConfigs.For(Context.Guild.Id).WarnPunishments; + var p = ps.FirstOrDefault(x => x.Count == number); + + if (p == null) + { + ps.Add(new WarningPunishment() + { + Count = number, + Punishment = punish, + Time = time, + }); + } + else + { + p.Count = number; + p.Punishment = punish; + p.Time = time; + uow._context.Update(p); + } + uow.Complete(); + } + + await ReplyConfirmLocalized("warn_punish_set", + Format.Bold(punish.ToString()), + Format.Bold(number.ToString())).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + public async Task WarnPunish(int number) + { + if (number <= 0) + return; + + using (var uow = DbHandler.UnitOfWork()) + { + var ps = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.WarnPunishments)).WarnPunishments; + var p = ps.FirstOrDefault(x => x.Count == number); + + if (p != null) + { + uow._context.Remove(p); + uow.Complete(); + } + } + + await ReplyConfirmLocalized("warn_punish_rem", + Format.Bold(number.ToString())).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task WarnPunishList() + { + WarningPunishment[] ps; + using (var uow = DbHandler.UnitOfWork()) + { + ps = uow.GuildConfigs.For(Context.Guild.Id, gc => gc.Include(x => x.WarnPunishments)) + .WarnPunishments + .OrderBy(x => x.Count) + .ToArray(); + } + + await Context.Channel.SendConfirmAsync( + GetText("warn_punish_list"), + string.Join("\n", ps.Select(x => $"{x.Count} -> {x.Punishment}"))).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + [RequireBotPermission(GuildPermission.BanMembers)] + public async Task Ban(IGuildUser user, [Remainder] string msg = null) + { + if (Context.User.Id != user.Guild.OwnerId && (user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max())) + { + await ReplyErrorLocalized("hierarchy").ConfigureAwait(false); + return; + } + if (!string.IsNullOrWhiteSpace(msg)) + { + try + { + await user.SendErrorAsync(GetText("bandm", Format.Bold(Context.Guild.Name), msg)); + } + catch + { + // ignored + } + } + + await Context.Guild.AddBanAsync(user, 7).ConfigureAwait(false); + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() + .WithTitle("⛔️ " + GetText("banned_user")) + .AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true))) + .ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.KickMembers)] + [RequireUserPermission(GuildPermission.ManageMessages)] + [RequireBotPermission(GuildPermission.BanMembers)] + public async Task Softban(IGuildUser user, [Remainder] string msg = null) + { + if (Context.User.Id != user.Guild.OwnerId && user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max()) + { + await ReplyErrorLocalized("hierarchy").ConfigureAwait(false); + return; + } + + if (!string.IsNullOrWhiteSpace(msg)) + { + try + { + await user.SendErrorAsync(GetText("sbdm", Format.Bold(Context.Guild.Name), msg)); + } + catch + { + // ignored + } + } + + await Context.Guild.AddBanAsync(user, 7).ConfigureAwait(false); + try { await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); } + catch { await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); } + + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() + .WithTitle("☣ " + GetText("sb_user")) + .AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true))) + .ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.KickMembers)] + [RequireBotPermission(GuildPermission.KickMembers)] + public async Task Kick(IGuildUser user, [Remainder] string msg = null) + { + if (Context.Message.Author.Id != user.Guild.OwnerId && user.GetRoles().Select(r => r.Position).Max() >= ((IGuildUser)Context.User).GetRoles().Select(r => r.Position).Max()) + { + await ReplyErrorLocalized("hierarchy").ConfigureAwait(false); + return; + } + if (!string.IsNullOrWhiteSpace(msg)) + { + try + { + await user.SendErrorAsync(GetText("kickdm", Format.Bold(Context.Guild.Name), msg)); + } + catch { } + } + + await user.KickAsync().ConfigureAwait(false); + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() + .WithTitle(GetText("kicked_user")) + .AddField(efb => efb.WithName(GetText("username")).WithValue(user.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName("ID").WithValue(user.Id.ToString()).WithIsInline(true))) + .ConfigureAwait(false); + } + } + } +} diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index cc7550b6..bba6abe1 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -9104,6 +9104,141 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to warn. + /// + public static string warn_cmd { + get { + return ResourceManager.GetString("warn_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warns a user.. + /// + public static string warn_desc { + get { + return ResourceManager.GetString("warn_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}warn @b1nzy`. + /// + public static string warn_usage { + get { + return ResourceManager.GetString("warn_usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to warnclear warnc. + /// + public static string warnclear_cmd { + get { + return ResourceManager.GetString("warnclear_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Clears all warnings from a certain user.. + /// + public static string warnclear_desc { + get { + return ResourceManager.GetString("warnclear_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}warnclear @PoorDude`. + /// + public static string warnclear_usage { + get { + return ResourceManager.GetString("warnclear_usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to warnlog. + /// + public static string warnlog_cmd { + get { + return ResourceManager.GetString("warnlog_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to See a list of warnings of a certain user.. + /// + public static string warnlog_desc { + get { + return ResourceManager.GetString("warnlog_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}warnlog @b1nzy`. + /// + public static string warnlog_usage { + get { + return ResourceManager.GetString("warnlog_usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to warnpunish warnp. + /// + public static string warnpunish_cmd { + get { + return ResourceManager.GetString("warnpunish_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sets a punishment for a certain number of warnings. Provide no punishment to remove.. + /// + public static string warnpunish_desc { + get { + return ResourceManager.GetString("warnpunish_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}warnpunish 5 Ban` or `{0}warnpunish 3`. + /// + public static string warnpunish_usage { + get { + return ResourceManager.GetString("warnpunish_usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to warnpunishlist warnpl. + /// + public static string warnpunishlist_cmd { + get { + return ResourceManager.GetString("warnpunishlist_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lists punishments for warnings.. + /// + public static string warnpunishlist_desc { + get { + return ResourceManager.GetString("warnpunishlist_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}warnpunishlist`. + /// + public static string warnpunishlist_usage { + get { + return ResourceManager.GetString("warnpunishlist_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to weather we. /// diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 790df4de..1f236f0a 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3222,4 +3222,49 @@ `{0}alias allin $bf 100 h` or `{0}alias "linux thingy" >loonix Spyware Windows` + + warnlog + + + See a list of warnings of a certain user. + + + `{0}warnlog @b1nzy` + + + warn + + + Warns a user. + + + `{0}warn @b1nzy` + + + warnclear warnc + + + Clears all warnings from a certain user. + + + `{0}warnclear @PoorDude` + + + warnpunishlist warnpl + + + Lists punishments for warnings. + + + `{0}warnpunishlist` + + + warnpunish warnp + + + Sets a punishment for a certain number of warnings. Provide no punishment to remove. + + + `{0}warnpunish 5 Ban` or `{0}warnpunish 3` + \ No newline at end of file diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index 1b0cd969..b440fe8a 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -736,6 +736,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Moderator. + /// + public static string administration_moderator { + get { + return ResourceManager.GetString("administration_moderator", resourceCulture); + } + } + /// /// Looks up a localized string similar to {0} moved from {1} to {2}. /// @@ -907,6 +916,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to page {0}. + /// + public static string administration_page { + get { + return ResourceManager.GetString("administration_page", resourceCulture); + } + } + /// /// Looks up a localized string similar to Error. Most likely I don't have sufficient permissions.. /// @@ -1060,6 +1078,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Reason. + /// + public static string administration_reason { + get { + return ResourceManager.GetString("administration_reason", resourceCulture); + } + } + /// /// Looks up a localized string similar to Successfully removed role {0} from user {1}. /// @@ -1648,6 +1675,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to User {0} has been warned.. + /// + public static string administration_user_warned { + get { + return ResourceManager.GetString("administration_user_warned", resourceCulture); + } + } + /// /// Looks up a localized string similar to Username. /// @@ -1765,6 +1801,87 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to cleared by {0}. + /// + public static string administration_warn_cleared_by { + get { + return ResourceManager.GetString("administration_warn_cleared_by", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warning punishment list. + /// + public static string administration_warn_punish_list { + get { + return ResourceManager.GetString("administration_warn_punish_list", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Having {0} warnings will no longer trigger a punishment.. + /// + public static string administration_warn_punish_rem { + get { + return ResourceManager.GetString("administration_warn_punish_rem", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to I will apply {0} punishment to users with {1} warnings.. + /// + public static string administration_warn_punish_set { + get { + return ResourceManager.GetString("administration_warn_punish_set", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warned on {0} server. + /// + public static string administration_warned_on { + get { + return ResourceManager.GetString("administration_warned_on", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to On {0} at {1} by {2}. + /// + public static string administration_warned_on_by { + get { + return ResourceManager.GetString("administration_warned_on_by", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All warnings have been cleared for {0}.. + /// + public static string administration_warnings_cleared { + get { + return ResourceManager.GetString("administration_warnings_cleared", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No warning on this page.. + /// + public static string administration_warnings_none { + get { + return ResourceManager.GetString("administration_warnings_none", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warnlog for {0}. + /// + public static string administration_warnlog_for { + get { + return ResourceManager.GetString("administration_warnlog_for", resourceCulture); + } + } + /// /// Looks up a localized string similar to User {0} from text chat. /// diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 6f8446b9..f8523242 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2278,4 +2278,43 @@ Owner ID: {2} Competitive playtime + + Moderator + + + page {0} + + + Reason + + + User {0} has been warned. + + + Warned on {0} server + + + On {0} at {1} by {2} + + + All warnings have been cleared for {0}. + + + No warning on this page. + + + Warnlog for {0} + + + cleared by {0} + + + Warning punishment list + + + Having {0} warnings will no longer trigger a punishment. + + + I will apply {0} punishment to users with {1} warnings. + \ No newline at end of file diff --git a/src/NadekoBot/Services/Database/IUnitOfWork.cs b/src/NadekoBot/Services/Database/IUnitOfWork.cs index c1c9479e..52cb01cf 100644 --- a/src/NadekoBot/Services/Database/IUnitOfWork.cs +++ b/src/NadekoBot/Services/Database/IUnitOfWork.cs @@ -23,6 +23,7 @@ namespace NadekoBot.Services.Database IPokeGameRepository PokeGame { get; } IWaifuRepository Waifus { get; } IDiscordUserRepository DiscordUsers { get; } + IWarningsRepository Warnings { get; } int Complete(); Task CompleteAsync(); diff --git a/src/NadekoBot/Services/Database/Models/GuildConfig.cs b/src/NadekoBot/Services/Database/Models/GuildConfig.cs index 00693f16..4fe497c1 100644 --- a/src/NadekoBot/Services/Database/Models/GuildConfig.cs +++ b/src/NadekoBot/Services/Database/Models/GuildConfig.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using static NadekoBot.Modules.Administration.Administration; namespace NadekoBot.Services.Database.Models { @@ -72,10 +71,19 @@ namespace NadekoBot.Services.Database.Models public HashSet UnmuteTimers { get; set; } = new HashSet(); public HashSet VcRoleInfos { get; set; } public HashSet CommandAliases { get; set; } = new HashSet(); + public List WarnPunishments { get; set; } = new List(); + public bool WarningsInitialized { get; set; } //public List ProtectionIgnoredChannels { get; set; } = new List(); } + public class WarningPunishment : DbEntity + { + public int Count { get; set; } + public PunishmentAction Punishment { get; set; } + public int Time { get; set; } + } + public class CommandAlias : DbEntity { public string Trigger { get; set; } diff --git a/src/NadekoBot/Services/Database/Models/Warning.cs b/src/NadekoBot/Services/Database/Models/Warning.cs new file mode 100644 index 00000000..e5c8f4ff --- /dev/null +++ b/src/NadekoBot/Services/Database/Models/Warning.cs @@ -0,0 +1,12 @@ +namespace NadekoBot.Services.Database.Models +{ + public class Warning : DbEntity + { + public ulong GuildId { get; set; } + public ulong UserId { get; set; } + public string Reason { get; set; } + public bool Forgiven { get; set; } + public string ForgivenBy { get; set; } + public string Moderator { get; set; } + } +} diff --git a/src/NadekoBot/Services/Database/NadekoContext.cs b/src/NadekoBot/Services/Database/NadekoContext.cs index 4efb6150..a82cfde8 100644 --- a/src/NadekoBot/Services/Database/NadekoContext.cs +++ b/src/NadekoBot/Services/Database/NadekoContext.cs @@ -40,6 +40,7 @@ namespace NadekoBot.Services.Database public DbSet CurrencyTransactions { get; set; } public DbSet PokeGame { get; set; } public DbSet WaifuUpdates { get; set; } + public DbSet Warnings { get; set; } //logging public DbSet LogSettings { get; set; } @@ -272,6 +273,10 @@ namespace NadekoBot.Services.Database du.HasAlternateKey(w => w.UserId); #endregion + + #region Warnings + var warn = modelBuilder.Entity(); + #endregion } } } diff --git a/src/NadekoBot/Services/Database/Repositories/IWarningsRepository.cs b/src/NadekoBot/Services/Database/Repositories/IWarningsRepository.cs new file mode 100644 index 00000000..2b2e5ac4 --- /dev/null +++ b/src/NadekoBot/Services/Database/Repositories/IWarningsRepository.cs @@ -0,0 +1,11 @@ +using NadekoBot.Services.Database.Models; +using System.Threading.Tasks; + +namespace NadekoBot.Services.Database.Repositories +{ + public interface IWarningsRepository : IRepository + { + Warning[] For(ulong guildId, ulong userId); + Task ForgiveAll(ulong guildId, ulong userId, string mod); + } +} diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs index 7098888d..01a44677 100644 --- a/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs @@ -12,6 +12,18 @@ namespace NadekoBot.Services.Database.Repositories.Impl { } + private List DefaultWarnPunishments => + new List() { + new WarningPunishment() { + Count = 3, + Punishment = PunishmentAction.Kick + }, + new WarningPunishment() { + Count = 5, + Punishment = PunishmentAction.Ban + } + }; + public IEnumerable GetAllGuildConfigs() => _set.Include(gc => gc.LogSetting) .ThenInclude(ls => ls.IgnoredChannels) @@ -64,10 +76,19 @@ namespace NadekoBot.Services.Database.Repositories.Impl _set.Add((config = new GuildConfig { GuildId = guildId, - Permissions = Permissionv2.GetDefaultPermlist + Permissions = Permissionv2.GetDefaultPermlist, + WarningsInitialized = true, + WarnPunishments = DefaultWarnPunishments, })); _context.SaveChanges(); } + + if (!config.WarningsInitialized) + { + config.WarningsInitialized = true; + config.WarnPunishments = DefaultWarnPunishments; + } + return config; } @@ -82,10 +103,18 @@ namespace NadekoBot.Services.Database.Repositories.Impl _set.Add((config = new GuildConfig { GuildId = guildId, - Permissions = Permissionv2.GetDefaultPermlist + Permissions = Permissionv2.GetDefaultPermlist, + WarningsInitialized = true, + WarnPunishments = DefaultWarnPunishments, })); _context.SaveChanges(); } + + if (!config.WarningsInitialized) + { + config.WarningsInitialized = true; + config.WarnPunishments = DefaultWarnPunishments; + } return config; } diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/WarningsRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/WarningsRepository.cs new file mode 100644 index 00000000..4bf4c293 --- /dev/null +++ b/src/NadekoBot/Services/Database/Repositories/Impl/WarningsRepository.cs @@ -0,0 +1,37 @@ +using NadekoBot.Services.Database.Models; +using Microsoft.EntityFrameworkCore; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace NadekoBot.Services.Database.Repositories.Impl +{ + public class WarningsRepository : Repository, IWarningsRepository + { + public WarningsRepository(DbContext context) : base(context) + { + } + + public Warning[] For(ulong guildId, ulong userId) + { + var query = _set.Where(x => x.GuildId == guildId && x.UserId == userId) + .OrderByDescending(x => x.DateAdded); + + return query.ToArray(); + } + + public async Task ForgiveAll(ulong guildId, ulong userId, string mod) + { + await _set.Where(x => x.GuildId == guildId && x.UserId == userId) + .ForEachAsync(x => + { + if (x.Forgiven != true) + { + x.Forgiven = true; + x.ForgivenBy = mod; + } + }) + .ConfigureAwait(false); + } + } +} diff --git a/src/NadekoBot/Services/Database/UnitOfWork.cs b/src/NadekoBot/Services/Database/UnitOfWork.cs index 032c0bb7..02e78a97 100644 --- a/src/NadekoBot/Services/Database/UnitOfWork.cs +++ b/src/NadekoBot/Services/Database/UnitOfWork.cs @@ -54,6 +54,9 @@ namespace NadekoBot.Services.Database private IDiscordUserRepository _discordUsers; public IDiscordUserRepository DiscordUsers => _discordUsers ?? (_discordUsers = new DiscordUserRepository(_context)); + private IWarningsRepository _warnings; + public IWarningsRepository Warnings => _warnings ?? (_warnings = new WarningsRepository(_context)); + public UnitOfWork(NadekoContext context) { _context = context; From 111b4bc4654db1e5eb98f7a9670e0cabb116feb5 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Thu, 30 Mar 2017 04:35:24 +0200 Subject: [PATCH 02/98] .unban added --- .../Commands/LocalizationCommands.cs | 4 +- .../Commands/UserPunishCommands.cs | 45 +++++++++++++++++++ .../Resources/CommandStrings.Designer.cs | 27 +++++++++++ src/NadekoBot/Resources/CommandStrings.resx | 9 ++++ .../Resources/ResponseStrings.Designer.cs | 18 ++++++++ src/NadekoBot/Resources/ResponseStrings.resx | 6 +++ 6 files changed, 107 insertions(+), 2 deletions(-) diff --git a/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs b/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs index bc4a0952..707d2af4 100644 --- a/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs @@ -24,11 +24,11 @@ namespace NadekoBot.Modules.Administration {"nl-NL", "Dutch, Netherlands"}, {"en-US", "English, United States"}, {"fr-FR", "Français, France"}, - {"de-DE", "German, Germany"}, + {"de-DE", "Deutsch, Deutschland"}, {"he-IL", "Hebrew, Israel" }, {"it-IT", "Italiano, Italia" }, //{"ja-JP", "Japanese, Japan"}, - {"ko-KR", "Korean, South Korea" }, + {"ko-KR", "한국어, 대한민국" }, {"nb-NO", "Norwegian (bokmål), Norway"}, {"pl-PL", "Polski, Polska" }, {"pt-BR", "Português Brasileiro, Brasil"}, diff --git a/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs b/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs index 0f54037f..53479589 100644 --- a/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs @@ -290,6 +290,51 @@ namespace NadekoBot.Modules.Administration .ConfigureAwait(false); } + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + [RequireBotPermission(GuildPermission.BanMembers)] + public async Task Unban([Remainder]string user) + { + var bans = await Context.Guild.GetBansAsync(); + + var bun = bans.FirstOrDefault(x => x.User.ToString().ToLowerInvariant() == user.ToLowerInvariant()); + + if (bun == null) + { + await ReplyErrorLocalized("user_not_found").ConfigureAwait(false); + return; + } + + await UnbanInternal(bun.User).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.BanMembers)] + [RequireBotPermission(GuildPermission.BanMembers)] + public async Task Unban(ulong userId) + { + var bans = await Context.Guild.GetBansAsync(); + + var bun = bans.FirstOrDefault(x => x.User.Id == userId); + + if (bun == null) + { + await ReplyErrorLocalized("user_not_found").ConfigureAwait(false); + return; + } + + await UnbanInternal(bun.User).ConfigureAwait(false); + } + + private async Task UnbanInternal(IUser user) + { + await Context.Guild.RemoveBanAsync(user).ConfigureAwait(false); + + await ReplyConfirmLocalized("unbanned_user", Format.Bold(user.ToString())).ConfigureAwait(false); + } + [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [RequireUserPermission(GuildPermission.KickMembers)] diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index bba6abe1..61163a92 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -8456,6 +8456,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to unban. + /// + public static string unban_cmd { + get { + return ResourceManager.GetString("unban_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unbans a user with the provided user#discrim or id.. + /// + public static string unban_desc { + get { + return ResourceManager.GetString("unban_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}unban kwoth#1234` or `{0}unban 123123123`. + /// + public static string unban_usage { + get { + return ResourceManager.GetString("unban_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to unclaim ucall uc. /// diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 1f236f0a..db8b3f50 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3240,6 +3240,15 @@ `{0}warn @b1nzy` + + unban + + + Unbans a user with the provided user#discrim or id. + + + `{0}unban kwoth#1234` or `{0}unban 123123123` + warnclear warnc diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index b440fe8a..a8e6ed17 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -1504,6 +1504,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to User {0} has been unbanned.. + /// + public static string administration_unbanned_user { + get { + return ResourceManager.GetString("administration_unbanned_user", resourceCulture); + } + } + /// /// Looks up a localized string similar to Undeafen successful.. /// @@ -1585,6 +1594,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to User not found.. + /// + public static string administration_user_not_found { + get { + return ResourceManager.GetString("administration_user_not_found", resourceCulture); + } + } + /// /// Looks up a localized string similar to User's role added. /// diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index f8523242..9ef50957 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2287,6 +2287,12 @@ Owner ID: {2} Reason + + User {0} has been unbanned. + + + User not found. + User {0} has been warned. From 090ad4f9811caa1d3c07bacb845905ad9d347b26 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Thu, 30 Mar 2017 15:53:29 +0200 Subject: [PATCH 03/98] fixed tweezers in hangman, language names are no longer in english --- .../Administration/Commands/LocalizationCommands.cs | 13 +++++++------ .../Modules/Games/Commands/Hangman/HangmanGame.cs | 2 +- src/NadekoBot/data/{hangman.json => hangman2.json} | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) rename src/NadekoBot/data/{hangman.json => hangman2.json} (99%) diff --git a/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs b/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs index 707d2af4..6930ad88 100644 --- a/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs @@ -17,26 +17,27 @@ namespace NadekoBot.Modules.Administration public class LocalizationCommands : NadekoSubmodule { //Română, România + //Bahasa Indonesia, Indonesia private ImmutableDictionary supportedLocales { get; } = new Dictionary() { {"zh-TW", "繁體中文, 台灣" }, {"zh-CN", "简体中文, 中华人民共和国"}, - {"nl-NL", "Dutch, Netherlands"}, + {"nl-NL", "Nederlands, Nederland"}, {"en-US", "English, United States"}, {"fr-FR", "Français, France"}, {"de-DE", "Deutsch, Deutschland"}, - {"he-IL", "Hebrew, Israel" }, + {"he-IL", "עברית, ישראל"}, {"it-IT", "Italiano, Italia" }, - //{"ja-JP", "Japanese, Japan"}, + //{"ja-JP", "日本語, 日本"}, {"ko-KR", "한국어, 대한민국" }, - {"nb-NO", "Norwegian (bokmål), Norway"}, + {"nb-NO", "Norsk, Norge"}, {"pl-PL", "Polski, Polska" }, {"pt-BR", "Português Brasileiro, Brasil"}, - {"ru-RU", "Russian, Russia"}, + {"ru-RU", "Русский, Россия"}, {"sr-Cyrl-RS", "Српски, Србија"}, {"es-ES", "Español, España"}, {"sv-SE", "Svenska, Sverige"}, - {"tr-TR", "Turkish, Turkey" } + {"tr-TR", "Türkçe, Türkiye"} }.ToImmutableDictionary(); [NadekoCommand, Usage, Description, Aliases] diff --git a/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs b/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs index b4b18e97..0f2f3bda 100644 --- a/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs +++ b/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs @@ -15,7 +15,7 @@ namespace NadekoBot.Modules.Games.Hangman { public class HangmanTermPool { - const string termsPath = "data/hangman.json"; + const string termsPath = "data/hangman2.json"; public static IReadOnlyDictionary data { get; } static HangmanTermPool() { diff --git a/src/NadekoBot/data/hangman.json b/src/NadekoBot/data/hangman2.json similarity index 99% rename from src/NadekoBot/data/hangman.json rename to src/NadekoBot/data/hangman2.json index e13fd5ab..b93e6aa5 100644 --- a/src/NadekoBot/data/hangman.json +++ b/src/NadekoBot/data/hangman2.json @@ -3023,7 +3023,7 @@ "ImageUrl": "https://www.randomlists.com/img/things/tv.jpg" }, { - "Word": "twezzers", + "Word": "tweezers", "ImageUrl": "https://www.randomlists.com/img/things/twezzers.jpg" }, { From 324360073bfe00093323edb10d0305d75a14447f Mon Sep 17 00:00:00 2001 From: Kwoth Date: Thu, 30 Mar 2017 16:00:27 +0200 Subject: [PATCH 04/98] spelling mistake --- src/NadekoBot/Modules/NadekoModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NadekoBot/Modules/NadekoModule.cs b/src/NadekoBot/Modules/NadekoModule.cs index d71a2ba9..8b6788dd 100644 --- a/src/NadekoBot/Modules/NadekoModule.cs +++ b/src/NadekoBot/Modules/NadekoModule.cs @@ -69,7 +69,7 @@ namespace NadekoBot.Modules LogManager.GetCurrentClassLogger().Warn(lowerModuleTypeName + "_" + key + " key is missing from " + cultureInfo + " response strings. PLEASE REPORT THIS."); text = NadekoBot.ResponsesResourceManager.GetString(lowerModuleTypeName + "_" + key, _usCultureInfo) ?? $"Error: dkey {lowerModuleTypeName + "_" + key} not found!"; if (string.IsNullOrWhiteSpace(text)) - return "I can't tell you is the command executed, because there was an error printing out the response. Key '" + + return "I can't tell you if the command is executed, because there was an error printing out the response. Key '" + lowerModuleTypeName + "_" + key + "' " + "is missing from resources. Please report this."; } return text; @@ -84,7 +84,7 @@ namespace NadekoBot.Modules } catch (FormatException) { - return "I cant tell if you command is executed, because there was an error printing out the response. Key '" + + return "I can't tell you if the command is executed, because there was an error printing out the response. Key '" + lowerModuleTypeName + "_" + key + "' " + "is not properly formatted. Please report this."; } } From 9cf03a1fb407cff41fc18917bbf9d73b8d4d4f52 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Thu, 30 Mar 2017 20:34:40 +0200 Subject: [PATCH 05/98] Finalized some things. closes #183 and #1059 --- .../Commands/UserPunishCommands.cs | 41 ++++++++++++++----- .../Resources/ResponseStrings.Designer.cs | 18 ++++++++ src/NadekoBot/Resources/ResponseStrings.resx | 6 +++ 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs b/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs index 53479589..ded760c2 100644 --- a/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs @@ -18,7 +18,7 @@ namespace NadekoBot.Modules.Administration [Group] public class UserPunishCommands : NadekoSubmodule { - private async Task InternalWarn(IGuild guild, ulong userId, string modName, string reason) + private async Task InternalWarn(IGuild guild, ulong userId, string modName, string reason) { if (string.IsNullOrWhiteSpace(reason)) reason = "-"; @@ -34,20 +34,20 @@ namespace NadekoBot.Modules.Administration Moderator = modName, }; - int warnings; + int warnings = 1; List ps; using (var uow = DbHandler.UnitOfWork()) { ps = uow.GuildConfigs.For(guildId, set => set.Include(x => x.WarnPunishments)) .WarnPunishments; - - uow.Warnings.Add(warn); - warnings = uow.Warnings + warnings += uow.Warnings .For(guildId, userId) .Where(w => !w.Forgiven && w.UserId == userId) .Count(); + uow.Warnings.Add(warn); + uow.Complete(); } @@ -57,7 +57,7 @@ namespace NadekoBot.Modules.Administration { var user = await guild.GetUserAsync(userId); if (user == null) - return; + return null; switch (p.Punishment) { case PunishmentAction.Mute: @@ -72,7 +72,10 @@ namespace NadekoBot.Modules.Administration default: break; } + return p.Punishment; } + + return null; } [NadekoCommand, Usage, Description, Aliases] @@ -89,9 +92,16 @@ namespace NadekoBot.Modules.Administration .ConfigureAwait(false); } catch { } - await InternalWarn(Context.Guild, user.Id, Context.User.ToString(), reason).ConfigureAwait(false); + var punishment = await InternalWarn(Context.Guild, user.Id, Context.User.ToString(), reason).ConfigureAwait(false); - await ReplyConfirmLocalized("user_warned", Format.Bold(user.ToString())).ConfigureAwait(false); + if (punishment == null) + { + await ReplyConfirmLocalized("user_warned", Format.Bold(user.ToString())).ConfigureAwait(false); + } + else + { + await ReplyConfirmLocalized("user_warned_and_punished", Format.Bold(user.ToString()), Format.Bold(punishment.ToString())).ConfigureAwait(false); + } } [NadekoCommand, Usage, Description, Aliases] @@ -146,7 +156,7 @@ namespace NadekoBot.Modules.Administration { var name = GetText("warned_on_by", w.DateAdded.Value.ToString("dd.MM.yyy"), w.DateAdded.Value.ToString("HH:mm"), w.Moderator); if (w.Forgiven) - name = Format.Strikethrough(name) + GetText("warn_cleared_by", w.ForgivenBy); + name = Format.Strikethrough(name) + " " + GetText("warn_cleared_by", w.ForgivenBy); embed.AddField(x => x .WithName(name) @@ -175,7 +185,7 @@ namespace NadekoBot.Modules.Administration } await ReplyConfirmLocalized("warnings_cleared", - (Context.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString()).ConfigureAwait(false); + Format.Bold((Context.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString())).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -254,9 +264,18 @@ namespace NadekoBot.Modules.Administration .ToArray(); } + string list; + if (ps.Any()) + { + list = string.Join("\n", ps.Select(x => $"{x.Count} -> {x.Punishment}")); + } + else + { + list = GetText("warnpl_none"); + } await Context.Channel.SendConfirmAsync( GetText("warn_punish_list"), - string.Join("\n", ps.Select(x => $"{x.Count} -> {x.Punishment}"))).ConfigureAwait(false); + list).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index a8e6ed17..34e12752 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -1702,6 +1702,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to User {0} has been warned and {1} punishment has been applied.. + /// + public static string administration_user_warned_and_punished { + get { + return ResourceManager.GetString("administration_user_warned_and_punished", resourceCulture); + } + } + /// /// Looks up a localized string similar to Username. /// @@ -1900,6 +1909,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to No punishments set.. + /// + public static string administration_warnpl_none { + get { + return ResourceManager.GetString("administration_warnpl_none", resourceCulture); + } + } + /// /// Looks up a localized string similar to User {0} from text chat. /// diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 9ef50957..a94761da 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2296,6 +2296,9 @@ Owner ID: {2} User {0} has been warned. + + User {0} has been warned and {1} punishment has been applied. + Warned on {0} server @@ -2311,6 +2314,9 @@ Owner ID: {2} Warnlog for {0} + + No punishments set. + cleared by {0} From 3703e39cc917956f5528b6b57e0b245a15eea2c0 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Fri, 31 Mar 2017 14:01:33 +0200 Subject: [PATCH 06/98] -cmds now splits into multiple messages if too long --- src/NadekoBot/Modules/Help/Help.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/NadekoBot/Modules/Help/Help.cs b/src/NadekoBot/Modules/Help/Help.cs index d6ceb1bd..4ca96023 100644 --- a/src/NadekoBot/Modules/Help/Help.cs +++ b/src/NadekoBot/Modules/Help/Help.cs @@ -55,8 +55,14 @@ namespace NadekoBot.Modules.Help await ReplyErrorLocalized("module_not_found").ConfigureAwait(false); return; } + var j = 0; + var groups = cmdsArray.GroupBy(x => j++ / 48).ToArray(); - await channel.SendTableAsync($"📃 **{GetText("list_of_commands")}**\n", cmdsArray, el => $"{el.Aliases.First(),-15} {"["+el.Aliases.Skip(1).FirstOrDefault()+"]",-8}").ConfigureAwait(false); + for (int i = 0; i < groups.Count(); i++) + { + await channel.SendTableAsync(i == 0 ? $"📃 **{GetText("list_of_commands")}**\n" : "", groups.ElementAt(i), el => $"{el.Aliases.First(),-15} {"[" + el.Aliases.Skip(1).FirstOrDefault() + "]",-8}").ConfigureAwait(false); + } + await ConfirmLocalized("commands_instr", Prefix).ConfigureAwait(false); } From 272bf6b85e41f69d355433ca82d738361d800f38 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Fri, 31 Mar 2017 14:03:22 +0200 Subject: [PATCH 07/98] Indonesian language completed --- .../Commands/LocalizationCommands.cs | 1 + .../Resources/ResponseStrings.id-ID.resx | 2285 +++++++++++++++++ .../ResponseStrings.sr-Cyrl-RS.Designer.cs | 260 -- 3 files changed, 2286 insertions(+), 260 deletions(-) create mode 100644 src/NadekoBot/Resources/ResponseStrings.id-ID.resx delete mode 100644 src/NadekoBot/Resources/ResponseStrings.sr-Cyrl-RS.Designer.cs diff --git a/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs b/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs index 6930ad88..2eb70e4c 100644 --- a/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs @@ -27,6 +27,7 @@ namespace NadekoBot.Modules.Administration {"fr-FR", "Français, France"}, {"de-DE", "Deutsch, Deutschland"}, {"he-IL", "עברית, ישראל"}, + {"id-ID", "Bahasa Indonesia, Indonesia" }, {"it-IT", "Italiano, Italia" }, //{"ja-JP", "日本語, 日本"}, {"ko-KR", "한국어, 대한민국" }, diff --git a/src/NadekoBot/Resources/ResponseStrings.id-ID.resx b/src/NadekoBot/Resources/ResponseStrings.id-ID.resx new file mode 100644 index 00000000..d2f4e2d2 --- /dev/null +++ b/src/NadekoBot/Resources/ResponseStrings.id-ID.resx @@ -0,0 +1,2285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Markas itu telah diklaim atau dihancurkan. + + + Markas itu telah dihancurkan. + + + Markas itu belum diklaim. + + + **DIHANCURKAN** markas #{0} di sebuah perang melawan {1} + + + {0} telah **MEMBATALKAN KLAIM** markas #{1} di sebuah perang melawan {2} + + + {0} Telah mengklaim sebuah markas #{1} di perang melawan {2} + + + @{0} Anda telah mengklaim markas #{1}. Anda tidak bisa mengklaim lagi. + + + Klaim dari @{0} di sebuah perang melawan {1} telah kadaluarsa. + + + Musuh + + + Info tentang perang melawan {0} + + + Jumlah markas yang salah. + + + Bukan ukuran perang yang benar. + + + Daftar perang aktif. + + + Tidak diklaim. + + + Anda tidak berpartisipasi di perang itu. + + + @{0} Antara anda tidak berpartisipasi di perang itu, atau markas itu telah dihancurkan. + + + Tidak ada perang aktif. + + + Ukuran + + + Perang melawan {0} telah dimulai. + + + Telah membuat perang melawan {0}. + + + Perang melawan {0} telah selesai. + + + Perang itu tidak ada. + + + Perang melawan {0} mulai! + + + Semua reaksi kustom telah dibersihkan. + + + Reaksi kustom telah dihapus. + + + Izin anda kurang. Dibutuhkan kepemilikan Bot untuk reaksi kostum global, dan Administrator untuk reaksi kustom server. + + + Daftar dari semua reaksi kustom. + + + Reaksi kustom. + + + Reaksi kustom baru + + + Tidak ada reaksi kustom yang ditemukan. + + + Tidak ada reaksi kustom ditemukan dengan id itu. + + + Tanggapan. + + + Status reaksi kustom + + + Status dibersihkan untuk reaksi kustom {0}. + + + Tidak ada data untuk aksi itu, aksi tidak dilakukan. + + + Aksi + + + Autohentai berhenti. + + + Tidak ada hasil yang ditemukan. + + + {0} sudah pingsan. + + + {0} sudah memiliki HP penuh. + + + Tipe anda sudah {0} + + + Digunakan {0}{1} di {2}{3} untuk {4} HP. + Kwoth used punch:type_icon: on Sanity:type_icon: for 50 damage. + + + Anda tidak bisa menyerang lagi tanpa serangan balik! + + + Anda tidak bisa menyerang diri sendiri. + + + {0} telah pingsan! + + + {0} disembuhkan dengan satu {1} + + + {0} memiliki {1} HP tersisa. + + + Anda tidak bisa menggunakan {0}. Ketik '{1}ml' untuk melihat daftar gerakan yang anda bisa gunakan. + + + Daftar gerakan untuk tipe {0} + + + Itu tidak efektif. + + + Anda tidak memiliki cukup {0} + + + {0} Dihidupkan dengan satu {1} + + + Anda menghidupkan diri sendiri dengan satu {0} + + + Tipe anda telah diganti ke {0} untuk sebuah {1} + + + Itu cukup efektif. + + + Itu sangatlah efektif! + + + Anda menggunakan terlalu banyak gerakan, jadi anda tidak bisa bergerak! + + + Tipe dari {0} adalah {1}. + + + Pengguna tidak ditemukan. + + + Anda pingsan, jadi anda tidak bisa bergerak! + + + **Penetapan role otomatis** ketika user bergabung sekarang telah **non aktif**. + + + **Penetapan role otomatis** ketika user bergabung sekarang telah **aktif**. + + + Lampiran + + + Avatar diubah. + + + Anda telah diban dari server {0}. +Alasan: {1} + + + 'banned' + PLURAL + + + Pengguna 'banned' + + + Nama bot diubah ke {0} + + + Status bot diubah ke {0}. + + + Penghapusan otomatis dari pesan 'bye' telah dimatikan. + + + Pesan 'bye' akan dihapus setelah {0} detik. + + + Pesan 'bye' sekarang: {0} + + + Nyalakan pesan 'bye' dengan menggunakan {0} + + + Pesan tinggal baru tersetel. + Fuzzy + + + Pengumuman tinggal dimatikan. + + + Pengumuman tinggal dinyalakan di channel ini. + + + Nama Channel telah diubah. + + + Nama lama. + + + Topik channel diubah. + + + Dibersihkan. + + + Konten + + + Berhasil membuat peran {0}. + + + Channel teks {0} telah dibuat. + + + Channel suara {0} telah dibuat. + + + Penulian berhasil. + + + Server {0} dihapus + + + Penghapusan otomatis telah diberhentikan karena invokasi pemerintah yang berhasil. + + + Sekarang akan secara otomatis menghapus invokasi perintah yang sukses. + + + Channel teks {0} dihapus. + + + Channel suara {0} dihapus. + + + Pesan dari + + + Berhasil menambahkan donatur baru. Jumlah donasi dari user ini: {0} 👑 + + + Terima kasih untuk orang yang terdaftar dibawah untuk menciptakan proyek ini! + + + Saya akan meneruskan DM kepada semua pemilik. + + + Saya akan meneruskan DM hanya ke pemilik pertama. + + + Saya akan meneruskan DM mulai dari sekarang. + + + Saya akan berhenti meneruskan DM mulai dari sekarang. + + + Penghapusan pesan sapaan otomatis telah dinonaktifkan. + + + Pesan pesan sapaan akan dihapus setelah {0} detik. + + + Pesan sapa DM sekarang: {0} + + + Aktifkan pesan sapa DM dengan mengetik {0} + + + Pesan sapa DM baru telah diset. + + + Pengumuman sapa DM dinonaktifkan. + + + Pengumuman sapa DM diaktifkan. + + + Pesan sapa sekarang: {0} + + + Aktifkan pesan sapa dengan mengetik {0} + + + Pesan sapa baru telah diset. + + + Pengumuman sapa dinonaktifkan. + + + Pengumuman sapa diaktifkan di channel ini. + + + Anda tidak bisa menggunakkan perintah ini pada pengguna dengan peran yang lebih tinggi atau setara dengan anda di dalam hierarki peran. + + + Gambar ditampilkan setelah {0} detik! + + + Format input tidak valid. + + + Parameter tidak valid. + + + {0} telah bergabung {1} + + + Anda telah dikeluarkan dari server (0}. +Alasan: {1} + + + Pengguna dikeluarkan + + + Daftar bahasa-bahasa + + + Bahasa server anda sekarang adalah {0} - {1} + + + Bahasa asli bot sekarang adalah {0} - {1} + + + Bahasa bot di set ke {0} - {1} + + + Gagal mengatur bahasa. Kunjungi bantuan untuk perintah ini. + + + Bahasa perintah ini sekarang di set ke {0} - {1} + + + {0} telah pergi {1} + + + Meninggalkan server {0} + + + Mencatat {0} event di channel ini. + + + Mencatat semua event di channel ini. + + + Pencatatan dinonaktifkan. + + + Event - event catatan yang anda dapat berlangganan: + + + Pencatatan akan mengabaikan {0} + + + Pencatatatn tidak akan mengabaikan {0} + + + Berhenti mencatat event {0}. + + + {0} telah menyebut peran - peran berikut + + + Pesan dari {0} `[Pemilik Bot]`: + + + Pesan terkirim. + + + {0} telah pindah dari {1} ke {2} + + + Pesan dihapus dalam #{0} + + + Pesan diperbarui dalam #{0} + + + Didiamkan. + PLURAL (users have been muted) + + + Didiamkan. + singular "User muted." + + + Kemungkinan besar saya tidak punya izin yang dibutuhkan untuk itu. + + + Peran diam baru telah diset + + + Saya butuh izin **Administrasi** untuk melakukan itu. + + + Pesan baru + + + Nama panggilan baru + + + Topik baru + + + Nama panggilan diubah + + + Tidak dapat menemukan server itu + + + Tidak ada potongan dengan ID itu ditemukan. + + + Pesan lama + + + Nama panggilan lama + + + Topik lama + + + Error. Kemungkinan besar saya tidak punya izin yang cukup. + + + Izin untuk server ini telah diatur ulang. + + + Perlindungan aktif + + + {0} telah **dinonaktifkan** pada server ini. + + + {0} diaktifkan + + + Error. Saya butuh izin ManageRoles + + + Tidak ada perlindungan diaktifkan. + + + Batas user harus diantara {0} dan {1}. + + + Jika {0} atau lebih user bergabung dalam {1} detik, Saya akan {2} mereka. + + + Waktu harus berada diantara {0} dan {1} detik. + + + Berhasil menghapus semua peran dari user {0} + + + Gagal menghapus peran. Saya tidak punya izin. + + + Warna dari peran {0} telah diubah. + + + Peran itu tidak ada. + + + Parameter yang ditentukan tidak valid. + + + Error disebabkan warna tidak valid atau tidak punya izin. + + + Berhasil menghapus peran {0} dari user {1} + + + Gagal menghapus peran. Saya tidak punya izin. + + + Nama peran diubah. + + + Gagal merubah nama peran. Saya tidak punya izin. + + + Anda tidak dapat mengedit peran yang lebih tinggi daripada peran tertinggi anda. + + + Pesan yang diputar: {0} telah dihapus + + + Peran {0} telah ditambahkan ke daftar. + + + {0} tidak ditemukan. Telah dibersihkan. + + + Peran {0} sudah ada di dalam daftar. + + + Ditambahkan. + + + Status bermain berotasi dinonaktifkan. + + + Status bermain berotasi diaktifkan + + + Ini adalah daftar status-status yang berotasi: +{0} + + + Tidak ada status bermain berotasi yang diset. + + + Anda sudah memiliki {0} peran. + + + Anda sudah memiliki {0} peran eksklusif yang ditetapkan sendiri. + + + Peran yang ditetapkan sendiri sekarang eksklusif! + + + Ada {0} peran yang ditetapkan sendiri + + + Peran itu tidak dapat ditetapkan sendiri. + + + Anda tidak memiliki {0} peran. + + + Peran yang ditetapkan sendiri sekarang tidak eksklusif! + + + Saya tidak dapat menambahkan peran itu pada anda. 'Saya tidak dapat menambahkan peran kepada pemilik atau peran lain yang lebih tinggi daripada peran saya di dalam hierarki peran.' + + + {0} telah dihapus dari daftar peran yang dapat ditetapkan sendiri. + + + Anda tidak lagi memiliki peran {0}. + + + Anda sekarang memiliki peran {0}. + + + Berhasil menambahkan peran {0} ke user {1} + + + Gagal menambahkan peran. Saya tidak punya izin. + + + Avatar baru telah diset! + + + Nama channel baru telah diset. + + + Permainan baru telah diset! + + + Aliran baru telah diset! + + + Topik channel baru telah diset! + + + Potongan {0} telah tersambung ulang. + + + Potongan {0} sedang menyambung ulang. + + + Mematikan + + + User tidak dapat mengirim lebih dari {0} pesan setiap {1} detik. + + + Mode lambat dimatikan. + + + Mode lambat dinyalakan. + + + Ban halus (Dikeluarkan) + PLURAL + + + {0} akan mengabaikan channel ini. + + + {0} tidak lagi akan mengabaikan channel ini. + + + Jika user memposting {0} pesan yang sama secara berurutan, Saya akan {1} mereka. + __IgnoredChannels__: {2} + + + Channel teks telah dibuat. + + + Channel teks telah dihancurkan. + + + penulian nonaktif. + + + Non-bisukan + singular + + + Nama pengguna + + + Nama pengguna telah diubah + + + Para pengguna + + + Pengguna dilarang + + + {0} telah **didiamkan** dari chatting. + + + {0} telah **tidak didiamkan** dari chatting. + + + User bergabung + + + User pergi + + + {0} telah **didiamkan** dari chat teks dan suara + + + Peran pengguna telah ditambahkan + + + Peran pengguna telah dihapuskan + + + {0} sekarang adalah {1} + + + {0} telah **tidak didiamkan** dari chat teks dan suara. + + + {0} telah bergabung di channel suara {1} . + + + {0} telah meninggalkan channel suara {1}. + + + {0} berpindah dari channel suara {1} ke {2}. + + + {0} telah **dibisukan** + + + {0} telah di **voice non-bisukan**. + + + Channel suara telah dibuat + + + Channel suara telah dihancurkan + + + Fitur suara + teks dinonaktifkan. + + + Fitur suara + teks diaktfikan. + + + Saya tidak memiliki izin **mengatur peran** dan/atau **mengatur channel**, jadi saya tidak dapat menjalankan 'suara+teks' di server {0}. + + + Anda mengaktifkan/menonaktifkan fitur ini dan **Saya tidak punya izin administrator**. Ini dapat menyebabkan beberapa isu, dan anda harus membersihkan sendiri channel-channel teks setelahnya. + + + Saya membutuhkan setidaknya izin **mengatur peran** dan **mengatur channel** untuk mengaktifkan fitur ini. (lebih memilih izin administrasi) + + + User {0} dari chat teks + + + User {0} dari chat teks dan suara + + + Pengguna {0} dari chat suara + + + Anda telah diban halus dari server {0}. +Alasan: {1} + + + Pengguna telah di unban + + + Migrasi selesai! + + + Error ketika migrasi, cek konsol bot untuk informasi lebih lanjut. + + + Pembaharuan kehadiran + + + Pengguna diban halus + + + Telah menyerahkan {0} ke {1} + + + Semoga lebih beruntung lain kali ^_^ + + + Selamat! Kamu memenangkan {0} karena hasil diatas {1} + + + Deck telah dikocok ulang. + + + Terlemparkan {0}. + User flipped tails. + + + Anda berhasil menebaknya! Anda memenangkan {0} + + + Angka tidak valid tertera. Anda dapat meleparkan 1 sampai {0} koin. + + + Tambahkan reaksi {0} pada pesan ini untuk mendapatkan {1}␣ + + + Event ini akan aktif selama {0} jam. + + + Event reaksi bunga telah dimulai! + + + Telah menghadiahi {0} ke {1} + X has gifted 15 flowers to Y + + + {0} memiliki {1} + X has Y flowers + + + Kepala + + + Leaderboard + + + Diserahkan {0} sampai {1} pengguna dari peran {2}. + + + Anda tidak bisa bertaruh lebih dari {0} + + + Anda tidak bisa bertaruh kurang dari {0} + + + Anda tidak memiliki cukup {0} + + + Tidak ada lagi kartu di dalam deck. + + + Pengguna yang diundi + + + Kamu mendapatkan {0}. + + + Bertaruh + + + WOAAHHHHHH!!! Selamat!!! x{0} + + + Sebuah {0}, x{1} + + + Wow! Beruntung! Three of a kind! x{0} + + + Good job! Dua {0} - bertaruh x{1} + + + Menang + + + User harus mengetikkan kode rahasia untuk mendapatkan {0}. +Berlangsung selama {1} detik. Jangan bilang bilang. Shhh. + + + Event SneakyGame berakhir. {0} pengguna telah menerima hadiah. + + + Event SneakyGameStatus telah dimulai + + + Ekor + + + berhasil mengambil {0} dari {1} + + + tidak dapat mengambil {0} dari{1} karena user itu tidak memiliki {2} sebanyak itu! + + + Kembali ke ToC + + + Hanya untuk pemilik bot + + + Memerlukan izin {0} channel. + + + Anda dapat mendukung project ini di patreon: <{0}> atau paypal: <{1}> + + + Daftar perintah dan alias + + + Daftar perintah telah dibuat ulang. + + + Ketik '{0}h CommandName' untuk melihat bantuan untuk perintah tersebut. Contoh '{0}h >8ball' + + + Saya tidak dapat menemukan perintah itu. Tolong verifikasi perintah itu ada sebelum mencoba lagi. + + + Deskripsi + + + Anda dapat mendukung projek NadekoBot di +Patreon <{0}> atau +Paypal <{1}> +Jangan lupa untuk meninggalkan nama atau ID Discord anda di dalam pesan. + +**Terima kasih**♥️ + + + **Daftar perintah**: <{0}> +**Panduan dan dokumentasi hosting dapat ditemukan disini**: <{1}> + + + Daftar perintah + + + Daftar modul + + + Ketik '{0}cmds ModuleName' untuk mendapatkan daftar perintah di dalam modul tersebut. Contoh '{0}cmds games' + + + Modul tersebut tidak ada. + + + Memerlukan izin {0} server. + + + Daftar isi + + + Penggunaan + + + Autohentai dimulai. Posting ulang setiap {0} detik dengan satu dari tanda berikut: +{1} + + + Tanda + + + Balap hewan + + + Gagal memulai karena tidak cukup peserta. + + + Balapan penuh!! Segera memulai. + + + {0} bergabung sebagai seekor {1} + + + {0} bergabung sebagai seekor {1} dan bertaruh {2}! + + + Ketik {0}jr untuk mengikuti balapan. + + + Dimulai dalam 20 detik atau ketika telah penuh. + + + Memulai dengan {0} peserta. + + + {0} sebagai {1} Memenangkan balapan! + + + {0} sebagai {1} Memenangkan balapan dan {2}! + + + Angka tidak valid. Anda dapat melemparkan {0}-{1} dadu bersamaan. + + + mendapatkan {0} + Someone rolled 35 + + + Dadu yang dilemparkan: {0} + Dice Rolled: 5 + + + Gagal memulai balapan. Balapan lain mungkin sedang berlangsung. + + + Tidak ada balapan di server ini + + + Angka kedua harus lebih besar daripada angka pertama. + + + Perubahan hati + + + Diklaim oleh + + + Perceraian + + + Suka + + + Harga + + + Tidak ada waifu yang belum diklaim. + + + Top Waifu + + + Afinitas anda sudah ditetapkan ke waifu tersebut atau anda sedang mencoba menghilangkan afinitas tanpa mempunyainya. + + + Mengubah afinitas mereka dari {0} ke {1} + +*Ini dapat ditanyakan moralitasnya.* 🤔 + Make sure to get the formatting right, and leave the thinking emoji + + + Anda harus menunggu {0} jam dan {1} menit untuk mengubah afinitas anda lagi. + + + Afinitas anda telah diulang. Anda tidak lagi memiliki seseorang yang anda sukai. + + + ingin menjadi waifu si {0}. Aww <3 + + + mengklaim {0} sebagai waifu dia seharga {1}! + + + Kamu telah menceraikan waifu yang menyukaimu. Kamu monster tanpa hati. +{0} menerima {1} sebagai kompensasi. + + + Anda tidak bisa merubah afinitas ke diri sendiri, anda egois. + + + 🎉 Cinta mereka dipenuhi! 🎉 +Nilai {0} sekarang adalah {1}! + + + Tidak ada waifu semurah itu. Anda harus membayar setidaknya {0} untuk mendapatkan waifu, meskipun harga mereka lebih rendah. + + + Anda harus membayar {0} atau lebih untuk mengklaim waifu tersebut! + + + Waifu itu bukan milikmu. + + + Anda tidak bisa mengklaim diri sendiri. + + + Anda baru saja bercerai. Anda harus menunggu {0} jam dan {1} menit untuk bercerai lagi. + + + Tidak seorangpun + + + Anda telah menceraikan waifu yang tidak menyukaimu. Anda menerima {0} kembali. + + + 8ball + + + Acrophobia + + + Permainan selesai tanpa pengajuan. + + + Tidak ada pilihan dikirim. Permainan selesai tanpa adanya pemenang. + + + Akronim adalah {0}. + + + Permainan Acrophobia sudah berlangsung di channel ini. + + + Permainan dimulai. Buat sebuah kalimat dengan akronim berikut: {0}. + + + Anda memiliki {0} detik untuk mengirimkan pengajuan. + + + {0} mengirim kalimat mereka. (total {1}) + + + Pilih dengan mengetik nomor dari pengajuan. + + + {0} mengirimkan pilihan mereka! + + + Pemenangnya adalah {0} dengan {1} poin. + + + {0} adalah pemenang karena merupakan satu-satunya pengguna yang mengajukan submisi! + + + Pertanyaan + + + Sebuah seri! Keduanya memilih {0} + + + {0} menang! {1} mengalahkan {2} + + + Waktu pengajuan selesai. + + + Animal Race telah berlangsung. + + + Total: {0} Rata - rata: {0} + + + Kategori + + + Cleverbot dinonaktifkan di server ini. + + + Cleverbot diaktifkan di server ini + + + Pembuatan mata uang telah dinonaktifkan di channel ini. + + + Pembuatan mata uang telah diaktifkan di channel ini. + + + {0} acak {1} telah muncul! + plural + + + Sebuah {0} muncul! + + + Gagal memuat pertanyaan + + + Permainan dimulai + + + Permainan Hangman dimulai + + + Permainan Hangman telah berlangsung di channel ini + + + Ada kesalahan saat memulai Hangman + Fuzzy + + + Daftar dari "{0}hangman" tipe istilah: + + + Leaderboard + + + Anda tidak punya cukup {0} + + + Tidak ada hasil + + + memilih {0} + Kwoth picked 5* + + + {0} menanam {1} + Kwoth planted 5* + + + Permainan trivia sedang berlangsung di server ini. + + + Permainan Trivia + + + {0} menebaknya! Jawabannya adalah: {1} + + + Tidak ada trivia yang sedang berlangsung di server ini. + + + {0} memiliki {1} poin + + + Berhenti setelah pertanyaan ini. + + + Waktu habis! Jawaban yang benar adalah {0} + + + {0} berhasil menebaknya dan memenangkan permainan! Jawabannya adalah: {1} + + + Anda tidak bisa bermain melawan diri sendiri. + + + Permainan TicTacToe sedang berlangsung di channel ini. + + + Sebuah seri! + + + telah membuat permainan TicTacToe. + + + {0} telah menang! + + + Mendapat tiga. + Fuzzy + + + TIdak ada jalan tersisa! + + + Waktu habis! + + + Giliran {0} + + + {0} vs {1} + + + Mencoba untuk mengantri {0} lagu... + + + Autoplay dimatikan. + + + Autoplay diaktifkan. + + + Volume awal di set ke {0}% + + + Antrian direktori selesai. + + + fairplay + + + Lagu selesai + + + Fair play dimatikan. + + + Fair play diaktifkan. + + + Dari posisi + + + id + + + Input tidak valid. + + + Sekarang, waktu bermain maksimal tidak memiliki batas. + + + Batas waktu bermain di set ke {0} detik. + + + Antrian maks untuk musik di set ke tidak terbatas. + + + Antrian maks untuk musik di set ke {0} lagu. + + + Anda harus berada di dalam channel suara di server ini. + + + Nama + + + Sekarang memutar + + + Tidak ada pemutar musik yang aktif. + + + Tidak ada hasil pencarian. + + + Pemutaran musik berhenti sebentar. + + + Antrian pemutar musik - Halaman {0}/{1} + + + Memutar lagu + + + `#{0}` - **{1}** oleh *{2}* ({3} lagu) + + + Halaman {1} playlist yang tersimpan + + + Playlist dihapus + + + Gagal untuk menghapus playlist. Playlist tidak ditemukan, atau anda bukan pemilik playlist tersebut. + + + Playlist dengan ID tersebut tidak ditemukan. + + + Antrian playlist selesai. + + + Playlist disimpan + + + Batasan milik {0} + + + Antrian + + + Antrian lagu + + + Antrian lagu dibersihkan + + + Antrian penuh pada {0}/{0}. + + + Menghapus lagu + context: "removed song #5" + + + Mengulang lagu yang diputar saat ini + + + Mengulang playlist + + + Musik diulang + + + Pengulangan musik diberhentikan. + + + Pemutaran kembali lagu dilanjutkan. + + + Pengulangan playlist dibatalkan. + + + Pengulangan playlist diaktifkan + + + Sekarang saya akan mengeluarkan lagu yang sedang diputar, yang telah diputar, yang dihentikan dan menghapus lagu-lagu di channel ini. + + + Lewat ke `{0}:{1}` + + + Lagu diacak + + + Lagu dipindahkan + + + {0}jam {1}menit {2}detik + + + Pada posisi + + + tidak terbatas + + + Volume harus di antara 0 dan 100 + + + Volume diset pada {0}% + + + Menonaktifkan pemakaian dari SEMUA MODUL pada channel {0}. + + + Mengaktifkan pemakaian dari SEMUA MODUL pada channel {0}. + + + Diizinkan + + + Menonaktifkan pemakaian dari SEMUA MODUL untuk peran {0}. + + + Mengaktifkan pemakaian dari SEMUA MODUL untuk peran {0}. + + + Menonaktifkan pemakaian dari SEMUA MODUL di server ini. + + + Mengaktifkan pemakaian dari SEMUA MODUL di server ini. + + + Menonaktifkan pemakaian dari SEMUA MODUL untuk pengguna {0}. + + + Mengaktifkan pemakaian dari SEMUA MODUL untuk pengguna {0}. + + + Mendaftarhitamkan {0} dengan ID {1} + + + Perintah {0} sekarang memiliki jeda selama {1} detik. + + + Perintah {0} sekarang tidak memiliki jeda dan semua jeda yang ada telah dibersihkan. + + + Tidak ada perintah jeda yang ditentukan. + + + Harga perintah + + + Menonaktifkan pemakaian pada {0} {1} pada channel {2}. + + + Mengaktifkan pemakaian pada {0} {1} pada channel {2}. + + + Ditolak + + + Menambahkan kata {0} pada daftar saringan kata. + + + Daftar saringan kata-kata + + + Mencabut kata {0} dari daftar saringan kata-kata. + + + Parameter kedua salah (Harus nomor diantara {0} dan {1}) + + + Penyaringan undangan dinonaktifkan di channel ini. + + + Penyaringan undangan diaktifkan di server ini. + + + Penyaringan undangan dinonaktifkan di server ini. + + + Penyaringan undangan diaktifkan di server ini. + + + Memindakan izin {0} dari #{1} kepada #{2} + + + Tidak dapat menemukan izin pada indeks #{0} + + + Tidak ada biaya di set. + + + perintah + Gen (of command) + + + modul + Gen. (of module) + + + Halaman perizinan {0} + + + Peran izin sekarang adalah {0} + + + Pengguna memerlukan {0} peran untuk dapat merubah izin. + + + Izin tidak ditemukan dalam indeks tersebut. + + + Mencabut izin #{0} - {1} + + + Menonaktifkan pemakaian pada {0} {1} untuk peran {2}. + + + Mengaktifkan pemakaian pada {0} {1} untuk peran {2}. + + + sec. + Short of seconds. + + + Menonaktifkan pemakaian dari {0} {1} pada server ini. + + + Mengaktifkan pemakaian dari {0} {1} pada server ini. + + + Menghapus {0} dengan ID {1} dari daftar hitam + + + tidak dapat diganti + + + Menonaktifkan pemakaian dari {0} {1} untuk {2} pengguna. + + + Mengaktifkan pemakaian dari {0} {1} untuk {2} pengguna. + + + Saya tidak akan lagi memperlihatkan izin peringatan. + + + Sekarang saya akan memperlihatkan izin peringatan. + + + Penyaringan kata pada channel ini dinonaktifkan. + + + Penyaringan kata pada channel ini diaktifkan. + + + Penyaringan kata pada server ini dinonaktifkan. + + + Penyaringan kata pada server ini diaktifkan. + + + Kemampuan + + + Belum ada anime favorit + + + Memulai terjemahan otomatis dari pesan di channel ini. Pesan pengguna akan otomatis dihapus. + + + Terjemahan bahasa otomatis anda telah dicabut. + + + Terjemahan bahasa otomatis anda telah diset pada {0}>{1} + + + Memulai terjemahan otomatis dari pesan-pesan di channel ini. + + + Menghentikan terjemahan otomatis dari pesan-pesan di channel ini. + + + Format input buruk, atau terjadi kesalahan. + + + Tidak dapat menemukan kartu tersebut. + + + fakta + + + Bab + + + Komik # + + + Kekalahan kompetitif + + + Kompetitif yang dimainkan + + + Tingkat kompetitif + + + Kemenangan kompetitif + + + Selesai + + + Kondisi + + + Biaya + + + Tanggal + + + Jelaskan: + + + Terjatuh. + + + Episode + + + Kesalahan terjadi. + + + Contoh + + + Gagal menemukan animu tersebut + + + Gagal menemukan mango tersebut + + + Aliran + + + Gagal menemukan definisi dari label tersebut. + + + Tinggi/Berat + + + {0}m/{1}kg + + + Kelembaban + + + Pencarian gambar untuk: + + + Gagal untuk menemukan film tersebut. + + + Kesalahan sumber atau target bahasa. + + + Candaan tidak dimuat. + + + Lintang/Bujur + + + Tingkat + + + Daftar dari {0}tempat yang ditandai + Don't translate {0}place + + + Lokasi + + + Barang barang sihir tidak dimuat. + + + Profil MAL {0} + + + Pemilik Bot tidak menentukan MashapeApiKey. Anda tidak dapat menggunakan fungsi ini. + + + Min/Maks + + + Channel tidak ditemukan. + + + Hasil tidak ditemukan. + + + Tertahan + + + url asli + + + Sebuah osu! API key diperlukan. + + + Gagal mengambil tanda osu! + + + Ditemukan diantara {0} gambar. Memperlihatkan acak {0}. + + + Pengguna tidak ditemukan! Silahkan cek daerah dan BattleTag sebelum mencoba lagi. + + + Rencana untuk menonton + + + Peron + + + Kemampuan tidak ditemukan. + + + Pokemon tidak ditemukan. + + + Tautan profil: + + + Kualitas + + + Waktu bermain cepat + + + Kemenangan cepat + + + Penilaian + + + Skor: + + + Pencarian untuk: + + + Gagal untuk mempersingkat url tersebut. + + + Url pendek + + + Ada sesuatu yang salah. + + + Harap menentukan parameter pencarian. + + + Status + + + Menyimpan url + + + Streamer {0} sedang offline. + + + Streamer {0} online dengan {1} penonton. + + + Anda mengikuti {0} stream di server ini. + + + Anda tidak mengikuti stream di server ini. + + + Stream tidak ditemukan. + + + Stream mungkin tidak ada. + + + Menghilangkan {0} stream ({1}) dari notifikasi. + + + Saya akan memberitahu channel ini saat status berubah. + + + Matahari terbit + + + Matahari terbenam + + + Temperatur + + + Judul: + + + Top 3 favorit anime: + + + Terjemahan: + + + Tipe + + + Gagal menemukan definisi untuk istilah tersebut + + + Url + + + Penonton + + + Menonton + + + Gagal menemukan istilah tersebut dalam wikia yang ditentukan. + + + Harap memasukkan target wikia, diikuti dengan pertanyaan pencarian. + + + Halaman tidak ditemukan. + + + Kecepatan angin + + + {0} champion paling sering di ban + + + Gagal menyodifikasi kalimat anda. + + + Bergabung + + + `{0}.` {1} [{2:F2}/s] - {3} total + /s and total need to be localized to fit the context - +`1.` + + + Halaman aktifitas #{0} + + + {0} total pengguna. + + + Penulis + + + ID Bot + + + Daftar fungsi di perintah {0)calc + + + {0} dari channel ini adalah {1} + + + Topik channel + + + Perintah dijalankan + + + {0} {1} sama dengan {2} {3} + + + Satuan yang dapat digunakan oleh converter + + + Tidak bisa mengubah {0} menjadi {1}: satuan tidak ditemukan + + + Tidak dapat mengubah {0} ke {1}: tipe untuk tidak sama + + + Dibuat di + + + Mengikuti saluran silang server. + + + Saluran silang server ditinggalkan. + + + Ini adalah token CSC anda + + + emoji kustom + + + Kesalahan + + + Ciri - ciri + + + ID + + + Indeks di luar jarak. + + + Daftar pengguna pada peran {0} + + + Anda tidak diizinkan untuk menggunakan perintah ini pada peran dengan banyak pengguna di dalamnya untuk mencegah penyalahgunaan. + + + Nilai {0} salah. + Invalid months value/ Invalid hours value + + + Bergabung Discord + + + Bergabung server + + + ID: {0} +Anggota: {1} +ID Pemilik: {2} + + + Server tidak ditemukan di halaman tersebut. + + + Daftar dari pengulangan + + + Anggota + + + Memori + + + Pesan + + + Pengulang pesan + + + Nama + + + Nama panggilan + + + Tidak seorangpun memainkan game tersebut + + + Tidak ada pengulangan aktif. + + + Tidak ada peran di halaman ini. + + + Tidak ada pecahan di halaman ini. + + + Tidak ada topik yang ditentukan + + + Pemilik + + + IDs pemilik + + + Kehadiran + + + {0} Servers +{1} Channel Teks +{2} Channel Suara + + + Menghapus semua kutipan dengan {0} kata kunci. + + + Halaman {0} dari kutipan + + + Tidak ada kutipan pada halaman ini. + + + Tidak ditemukan kutipan yang dapat anda hapus. + + + Kutipan ditambahkan + + + Kutipan #{0} dihapus. + + + Wilayah + + + Terdaftar pada + + + Saya akan mengigatakn {0} untuk {1} dalam {2} '({3:d:M.yyyy.} saat {4:HH:mm} + + + Bukan format waktu yang benar. Silakan periksa daftar perintah. + + + Template mengingatkan baru disetel. + + + Mengulang {0} setiap {1} hari, {2} jam dan {3} menit. + + + Daftar pemutaran. + + + Tidak ada pemutaran di server ini. + + + #{0} berhenti. + + + Tidak ada pesan mengulang ditemukan di server ini. + + + Hasil + + + Peran + + + Halaman #{0} dari semua peran di server ini: + + + Halaman #{0} dari peran untuk {1} + + + Tidak ada warna di format benar. Gunakan '#00ff00' sebagai contoh. + + + Memulai pemutaran di peran {0}. + + + Memberhentikan warna memutar untuk peran {0} + + + {0} pada server ini adalah {1} + + + Info server + + + Pecahan + + + Statistik pecahan + + + Pecahan **#{0}** sedang di dalam keadaan {1} di {2} server. + + + **Nama:** {0} **Tautan:** {1} + + + Emojis khusus tidak ditemukan. + + + Memainkan {0} lagu, {1} menunggu + + + Channel teks + + + Ini adalah tautan untuk ruangan anda: + + + Uptime + + + {0} dari pengguna {1} adalah {2} + Id of the user kwoth#1234 is 123123123123 + + + Pengguna + + + Channel suara + + + Anda telah bergabung pada perlombaan ini! + + + Hasil pemilihan saat ini + + + Tidak ada suara terkirim. + + + Pemilihan telah dimulai di server ini. + + + 📃 {0} telah membuat pemilihan yang memerlukan perhatian anda: + + + '{0}.' {1} dengan {2} suara. + + + {0} memilih. + Kwoth voted. + + + Kirim saya pesan pribadi dengan angka yang sesuai dari jawaban. + + + Kirim pesan dengan menggunakan nomor dari jawaban. + + + Terima kasih telah memilih, {0} + + + {0} total suara dikirim. + + + Mengambil barang tersebut dengan mengetik `{0}ambil` + + + Ambil dengan mengetik '{0}pick' + + + Pengguna tidak ditemukan. + + + halaman {0} + + + Anda harus berada pada channel suara di server ini. + + + Tidak ada peran untuk saluran suara. + + + {0} telah **dibisukan** dari teks dan saluran suara selama {1} menit. + + + Pengguna yang bergabung {0} channel suara akan mendapatkan peran {1}. + + + Pengguna yang bergabung {0} channel suara tidak lagi mendapatkan peran. + + + Peran channel suara + + + Mereaksi reaksi kustom menggunakan pesan dengan id {0} tidak akan dihapus secara otomatis. + + + Mereaksikan reaksi kustom menggunakan pesan dengan id {0} akan dihapus secara otomatis. + + + Pesan respon untuk reaksi kustom dengan id {0} tidak akan dikirim sebagai DM. + + + Pesan respon untuk reaksi kustom dengan id {0} akan dikirim sebagai DM. + + + Alias tidak ditemukan + + + Mengetik {0} sekarang akan menjadi alias dari {1}. + + + Daftar alias + + + Perintah {0} sekarang tidak memiliki alias. + + + Perintah {0} tidak mempunyai alias. + + + Waktu bermain kompetitif + + + \ No newline at end of file diff --git a/src/NadekoBot/Resources/ResponseStrings.sr-Cyrl-RS.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.sr-Cyrl-RS.Designer.cs deleted file mode 100644 index 4d43d571..00000000 --- a/src/NadekoBot/Resources/ResponseStrings.sr-Cyrl-RS.Designer.cs +++ /dev/null @@ -1,260 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace NadekoBot.Resources { - using System; - using System.Reflection; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - public class ResponseStrings_sr_SP { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - internal ResponseStrings_sr_SP() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - public static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NadekoBot.Resources.ResponseStrings-sr-SP", typeof(ResponseStrings_sr_SP).GetTypeInfo().Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - public static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to {0} has already fainted.. - /// - public static string pokemon_already_fainted { - get { - return ResourceManager.GetString("pokemon_already_fainted", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to {0} already has full HP.. - /// - public static string pokemon_already_full { - get { - return ResourceManager.GetString("pokemon_already_full", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Your type is already {0}. - /// - public static string pokemon_already_that_type { - get { - return ResourceManager.GetString("pokemon_already_that_type", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to used {0}{1} on {2}{3} for {4} damage.. - /// - public static string pokemon_attack { - get { - return ResourceManager.GetString("pokemon_attack", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You can't attack again without retaliation!. - /// - public static string pokemon_cant_attack_again { - get { - return ResourceManager.GetString("pokemon_cant_attack_again", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You can't attack yourself.. - /// - public static string pokemon_cant_attack_yourself { - get { - return ResourceManager.GetString("pokemon_cant_attack_yourself", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to {0} has fainted!. - /// - public static string pokemon_fainted { - get { - return ResourceManager.GetString("pokemon_fainted", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to healed {0} with one {1}. - /// - public static string pokemon_healed { - get { - return ResourceManager.GetString("pokemon_healed", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to {0} has {1} HP remaining.. - /// - public static string pokemon_hp_remaining { - get { - return ResourceManager.GetString("pokemon_hp_remaining", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You can't use {0}. Type `{1}ml` to see a list of moves you can use.. - /// - public static string pokemon_invalid_move { - get { - return ResourceManager.GetString("pokemon_invalid_move", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Movelist for {0} type. - /// - public static string pokemon_moves { - get { - return ResourceManager.GetString("pokemon_moves", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You don't have enough {0}. - /// - public static string pokemon_no_currency { - get { - return ResourceManager.GetString("pokemon_no_currency", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to It's not effective.. - /// - public static string pokemon_not_effective { - get { - return ResourceManager.GetString("pokemon_not_effective", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to revived {0} with one {1}. - /// - public static string pokemon_revive_other { - get { - return ResourceManager.GetString("pokemon_revive_other", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You revived yourself with one {0}. - /// - public static string pokemon_revive_yourself { - get { - return ResourceManager.GetString("pokemon_revive_yourself", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Your type has been changed to {0} for a {1}. - /// - public static string pokemon_settype_success { - get { - return ResourceManager.GetString("pokemon_settype_success", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to It's somewhat effective.. - /// - public static string pokemon_somewhat_effective { - get { - return ResourceManager.GetString("pokemon_somewhat_effective", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to It's super effective!. - /// - public static string pokemon_super_effective { - get { - return ResourceManager.GetString("pokemon_super_effective", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You used too many moves in a row, so you can't move!. - /// - public static string pokemon_too_many_moves { - get { - return ResourceManager.GetString("pokemon_too_many_moves", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Type of {0} is {1}. - /// - public static string pokemon_type_of_user { - get { - return ResourceManager.GetString("pokemon_type_of_user", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to User not found.. - /// - public static string pokemon_user_not_found { - get { - return ResourceManager.GetString("pokemon_user_not_found", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You fainted, so you are not able to move!. - /// - public static string pokemon_you_fainted { - get { - return ResourceManager.GetString("pokemon_you_fainted", resourceCulture); - } - } - } -} From 0a7bbd60f77870e8f3e41334a4a19e1a4f14adf0 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Fri, 31 Mar 2017 14:07:18 +0200 Subject: [PATCH 08/98] 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) { From 223b668628c6691a0b1f8fb1f731f58ffbfe3352 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 1 Apr 2017 11:15:37 +0200 Subject: [PATCH 09/98] softban is a separate punishment from kick now. Commandlist updated --- .../Modules/Administration/Commands/LogCommand.cs | 3 +++ .../Administration/Commands/ProtectionCommands.cs | 7 +++++++ .../Administration/Commands/UserPunishCommands.cs | 11 +++++++++++ src/NadekoBot/Resources/ResponseStrings.Designer.cs | 11 ++++++++++- src/NadekoBot/Resources/ResponseStrings.resx | 6 +++++- .../Services/Database/Models/AntiProtection.cs | 1 + 6 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs index f061f045..515c2f46 100644 --- a/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs @@ -307,6 +307,9 @@ namespace NadekoBot.Modules.Administration punishment = "🔇 " + logChannel.Guild.GetLogText("muted_pl").ToUpperInvariant(); break; case PunishmentAction.Kick: + punishment = "👢 " + logChannel.Guild.GetLogText("kicked_pl").ToUpperInvariant(); + break; + case PunishmentAction.Softban: punishment = "☣ " + logChannel.Guild.GetLogText("soft_banned_pl").ToUpperInvariant(); break; case PunishmentAction.Ban: diff --git a/src/NadekoBot/Modules/Administration/Commands/ProtectionCommands.cs b/src/NadekoBot/Modules/Administration/Commands/ProtectionCommands.cs index af7269c9..23f1eaf0 100644 --- a/src/NadekoBot/Modules/Administration/Commands/ProtectionCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/ProtectionCommands.cs @@ -188,6 +188,13 @@ namespace NadekoBot.Modules.Administration catch (Exception ex) { _log.Warn(ex, "I can't apply punishement"); } break; case PunishmentAction.Kick: + try + { + await gu.KickAsync().ConfigureAwait(false); + } + catch (Exception ex) { _log.Warn(ex, "I can't apply punishement"); } + break; + case PunishmentAction.Softban: try { await gu.Guild.AddBanAsync(gu, 7).ConfigureAwait(false); diff --git a/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs b/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs index f37b864c..f794d47a 100644 --- a/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs @@ -72,6 +72,17 @@ namespace NadekoBot.Modules.Administration case PunishmentAction.Ban: await guild.AddBanAsync(user).ConfigureAwait(false); break; + case PunishmentAction.Softban: + await guild.AddBanAsync(user).ConfigureAwait(false); + try + { + await guild.RemoveBanAsync(user).ConfigureAwait(false); + } + catch + { + await guild.RemoveBanAsync(user).ConfigureAwait(false); + } + break; default: break; } diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index ea980b1f..3d91002f 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -574,6 +574,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Kicked. + /// + public static string administration_kicked_pl { + get { + return ResourceManager.GetString("administration_kicked_pl", resourceCulture); + } + } + /// /// Looks up a localized string similar to User kicked. /// @@ -1504,7 +1513,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to soft-banned (kicked). + /// Looks up a localized string similar to soft-banned. /// public static string administration_soft_banned_pl { get { diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 92087d6b..c71eea89 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -740,7 +740,7 @@ Reason: {1} Slow mode initiated - soft-banned (kicked) + soft-banned PLURAL @@ -2284,6 +2284,10 @@ Owner ID: {2} Command Text + + Kicked + PLURAL + Moderator diff --git a/src/NadekoBot/Services/Database/Models/AntiProtection.cs b/src/NadekoBot/Services/Database/Models/AntiProtection.cs index 0172dd90..a90ee649 100644 --- a/src/NadekoBot/Services/Database/Models/AntiProtection.cs +++ b/src/NadekoBot/Services/Database/Models/AntiProtection.cs @@ -31,6 +31,7 @@ namespace NadekoBot.Services.Database.Models Mute, Kick, Ban, + Softban } public class AntiSpamIgnore : DbEntity From 83dbc562af0c74dc1d19f756f80f5c5b7a700657 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 1 Apr 2017 11:15:54 +0200 Subject: [PATCH 10/98] Woops --- docs/Commands List.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/Commands List.md b/docs/Commands List.md index 0ce3438d..715df776 100644 --- a/docs/Commands List.md +++ b/docs/Commands List.md @@ -26,9 +26,6 @@ Commands and aliases | Description | Usage `.removeallroles` `.rar` | Removes all roles from a mentioned user. **Requires ManageRoles server permission.** | `.rar @User` `.createrole` `.cr` | Creates a role with a given name. **Requires ManageRoles server permission.** | `.cr Awesome Role` `.rolecolor` `.rc` | Set a role's color to the hex or 0-255 rgb color value provided. **Requires ManageRoles server permission.** | `.rc Admin 255 200 100` or `.rc Admin ffba55` -`.ban` `.b` | Bans a user by ID or name with an optional message. **Requires BanMembers server permission.** | `.b "@some Guy" Your behaviour is toxic.` -`.softban` `.sb` | Bans and then unbans a user by ID or name with an optional message. **Requires KickMembers server permission.** **Requires ManageMessages server permission.** | `.sb "@some Guy" Your behaviour is toxic.` -`.kick` `.k` | Kicks a mentioned user. **Requires KickMembers server permission.** | `.k "@some Guy" Your behaviour is toxic.` `.deafen` `.deaf` | Deafens mentioned user or users. **Requires DeafenMembers server permission.** | `.deaf "@Someguy"` or `.deaf "@Someguy" "@Someguy"` `.undeafen` `.undef` | Undeafens mentioned user or users. **Requires DeafenMembers server permission.** | `.undef "@Someguy"` or `.undef "@Someguy" "@Someguy"` `.delvoichanl` `.dvch` | Deletes a voice channel with a given name. **Requires ManageChannels server permission.** | `.dvch VoiceChannelName` @@ -73,6 +70,11 @@ Commands and aliases | Description | Usage `.togglexclsar` `.tesar` | Toggles whether the self-assigned roles are exclusive. (So that any person can have only one of the self assignable roles) **Requires ManageRoles server permission.** | `.tesar` `.iam` | Adds a role to you that you choose. Role must be on a list of self-assignable roles. | `.iam Gamer` `.iamnot` `.iamn` | Removes a role to you that you choose. Role must be on a list of self-assignable roles. | `.iamn Gamer` +`.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. **Bot owner only** | `.scadd .stats` +`.sclist` | Lists all startup commands in the order they will be executed in. **Bot owner only** | `.sclist` +`.wait` | Used only as a startup command. Waits a certain number of miliseconds before continuing the execution of the following startup commands. **Bot owner only** | `.wait 3000` +`.scrm` | Removes a startup command with the provided command text. **Bot owner only** | `.scrm .stats` +`.scclr` | Removes all startup commands. **Bot owner only** | `.scclr` `.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 file **Bot owner only** | `.fwtoall` `.connectshard` | Try (re)connecting a shard with a certain shardid when it dies. No one knows will it work. Keep an eye on the console for errors. **Bot owner only** | `.connectshard 2` @@ -94,6 +96,15 @@ Commands and aliases | Description | Usage `.bye` | Toggles anouncements on the current channel when someone leaves the server. **Requires ManageServer server permission.** | `.bye` `.byemsg` | Sets a new leave announcement message. Type `%user%` if you want to show the name the user who left. Type `%id%` to show id. Using this command with no message will show the current bye message. You can use embed json from instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.byemsg %user% has left.` `.byedel` | Sets the time it takes (in seconds) for bye messages to be auto-deleted. Set it to `0` to disable automatic deletion. **Requires ManageServer server permission.** | `.byedel 0` or `.byedel 30` +`.warn` | Warns a user. **Requires BanMembers server permission.** | `.warn @b1nzy` +`.warnlog` | See a list of warnings of a certain user. **Requires BanMembers server permission.** | `.warnlog @b1nzy` +`.warnclear` `.warnc` | Clears all warnings from a certain user. **Requires BanMembers server permission.** | `.warnclear @PoorDude` +`.warnpunish` `.warnp` | Sets a punishment for a certain number of warnings. Provide no punishment to remove. **Requires BanMembers server permission.** | `.warnpunish 5 Ban` or `.warnpunish 3` +`.warnpunishlist` `.warnpl` | Lists punishments for warnings. | `.warnpunishlist` +`.ban` `.b` | Bans a user by ID or name with an optional message. **Requires BanMembers server permission.** | `.b "@some Guy" Your behaviour is toxic.` +`.unban` | Unbans a user with the provided user#discrim or id. **Requires BanMembers server permission.** | `.unban kwoth#1234` or `.unban 123123123` +`.softban` `.sb` | Bans and then unbans a user by ID or name with an optional message. **Requires KickMembers server permission.** **Requires ManageMessages server permission.** | `.sb "@some Guy" Your behaviour is toxic.` +`.kick` `.k` | Kicks a mentioned user. **Requires KickMembers server permission.** | `.k "@some Guy" Your behaviour is toxic.` `.vcrole` | Sets or resets a role which will be given to users who join the voice channel you're in when you run this command. Provide no role name to disable. You must be in a voice channel to run this command. **Requires ManageRoles server permission.** **Requires ManageChannels server permission.** | `.vcrole SomeRole` or `.vcrole` `.vcrolelist` | Shows a list of currently set voice channel roles. | `.vcrolelist` `.voice+text` `.v+t` | Creates a text channel for each voice channel only users in that voice channel can see. If you are server owner, keep in mind you will see them all the time regardless. **Requires ManageRoles server permission.** **Requires ManageChannels server permission.** | `.v+t` From 3a5aed213b3580521e2a0a9f9bb5e6299ffcf622 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 1 Apr 2017 13:47:05 +0200 Subject: [PATCH 11/98] startup commands will no longer be treated as if theyr'e run in DMs --- .../Commands/RatelimitCommand.cs | 27 +++++++++++++++++++ .../Administration/Commands/SelfCommands.cs | 11 ++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs index 2a4e111f..6d1e3f13 100644 --- a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs @@ -1,7 +1,10 @@ using Discord; using Discord.Commands; +using Microsoft.EntityFrameworkCore; using NadekoBot.Attributes; using NadekoBot.Extensions; +using NadekoBot.Services; +using NadekoBot.Services.Database; using NLog; using System; using System.Collections.Concurrent; @@ -118,6 +121,30 @@ namespace NadekoBot.Modules.Administration .ConfigureAwait(false); } } + + //[NadekoCommand, Usage, Description, Aliases] + //[RequireContext(ContextType.Guild)] + //[RequireUserPermission(GuildPermission.ManageMessages)] + //public async Task SlowmodeWhitelist(IUser user) + //{ + // Ratelimiter throwaway; + // if (RatelimitingChannels.TryRemove(Context.Channel.Id, out throwaway)) + // { + // throwaway.cancelSource.Cancel(); + // await ReplyConfirmLocalized("slowmode_disabled").ConfigureAwait(false); + // } + //} + + //[NadekoCommand, Usage, Description, Aliases] + //[RequireContext(ContextType.Guild)] + //[RequireUserPermission(GuildPermission.ManageMessages)] + //public async Task SlowmodeWhitelist(IRole role) + //{ + // using (var uow = DbHandler.UnitOfWork()) + // { + // uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.SlowmodeWhitelists)). + // } + //} } } } \ No newline at end of file diff --git a/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs index 3af86611..09924682 100644 --- a/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs @@ -36,11 +36,9 @@ namespace NadekoBot.Modules.Administration var _ = Task.Run(async () => { -#if !GLOBAL_NADEKO - await Task.Delay(2000); -#else - await Task.Delay(10000); -#endif + while(!NadekoBot.Ready) + await Task.Delay(1000); + foreach (var cmd in NadekoBot.BotConfig.StartupCommands) { if (cmd.GuildId != null) @@ -52,7 +50,8 @@ namespace NadekoBot.Modules.Administration try { - var msg = await channel.SendMessageAsync(cmd.CommandText).ConfigureAwait(false); + IUserMessage msg = await channel.SendMessageAsync(cmd.CommandText).ConfigureAwait(false); + msg = (IUserMessage)await channel.GetMessageAsync(msg.Id).ConfigureAwait(false); await NadekoBot.CommandHandler.TryRunCommand(guild, channel, msg).ConfigureAwait(false); //msg.DeleteAfter(5); } From 2b65518649b6b338cfde0d9d6468fae50ec5f585 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 1 Apr 2017 21:40:13 +0200 Subject: [PATCH 12/98] Slowmode whitelists done, need testing --- ...70401161600_slowmode-whitelist.Designer.cs | 1435 +++++++++++++++++ .../20170401161600_slowmode-whitelist.cs | 73 + .../NadekoSqliteContextModelSnapshot.cs | 50 + .../Commands/RatelimitCommand.cs | 112 +- .../Utility/Commands/PatreonCommands.cs | 113 +- .../Resources/CommandStrings.Designer.cs | 54 + src/NadekoBot/Resources/CommandStrings.resx | 18 + .../Resources/ResponseStrings.Designer.cs | 117 ++ src/NadekoBot/Resources/ResponseStrings.resx | 39 + .../Services/Database/Models/GuildConfig.cs | 46 + .../Services/Database/Models/RewardedUser.cs | 11 + 11 files changed, 2020 insertions(+), 48 deletions(-) create mode 100644 src/NadekoBot/Migrations/20170401161600_slowmode-whitelist.Designer.cs create mode 100644 src/NadekoBot/Migrations/20170401161600_slowmode-whitelist.cs create mode 100644 src/NadekoBot/Services/Database/Models/RewardedUser.cs diff --git a/src/NadekoBot/Migrations/20170401161600_slowmode-whitelist.Designer.cs b/src/NadekoBot/Migrations/20170401161600_slowmode-whitelist.Designer.cs new file mode 100644 index 00000000..7409d096 --- /dev/null +++ b/src/NadekoBot/Migrations/20170401161600_slowmode-whitelist.Designer.cs @@ -0,0 +1,1435 @@ +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("20170401161600_slowmode-whitelist")] + partial class slowmodewhitelist + { + 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.SlowmodeIgnoredRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("RoleId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("SlowmodeIgnoredRole"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("SlowmodeIgnoredUser"); + }); + + 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.SlowmodeIgnoredRole", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("SlowmodeIgnoredRoles") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("SlowmodeIgnoredUsers") + .HasForeignKey("GuildConfigId"); + }); + + 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/20170401161600_slowmode-whitelist.cs b/src/NadekoBot/Migrations/20170401161600_slowmode-whitelist.cs new file mode 100644 index 00000000..fc2be484 --- /dev/null +++ b/src/NadekoBot/Migrations/20170401161600_slowmode-whitelist.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace NadekoBot.Migrations +{ + public partial class slowmodewhitelist : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "SlowmodeIgnoredRole", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + DateAdded = table.Column(nullable: true), + GuildConfigId = table.Column(nullable: true), + RoleId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_SlowmodeIgnoredRole", x => x.Id); + table.ForeignKey( + name: "FK_SlowmodeIgnoredRole_GuildConfigs_GuildConfigId", + column: x => x.GuildConfigId, + principalTable: "GuildConfigs", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "SlowmodeIgnoredUser", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + DateAdded = table.Column(nullable: true), + GuildConfigId = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_SlowmodeIgnoredUser", x => x.Id); + table.ForeignKey( + name: "FK_SlowmodeIgnoredUser_GuildConfigs_GuildConfigId", + column: x => x.GuildConfigId, + principalTable: "GuildConfigs", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_SlowmodeIgnoredRole_GuildConfigId", + table: "SlowmodeIgnoredRole", + column: "GuildConfigId"); + + migrationBuilder.CreateIndex( + name: "IX_SlowmodeIgnoredUser_GuildConfigId", + table: "SlowmodeIgnoredUser", + column: "GuildConfigId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "SlowmodeIgnoredRole"); + + migrationBuilder.DropTable( + name: "SlowmodeIgnoredUser"); + } + } +} diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index 83771957..3f6df376 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -950,6 +950,42 @@ namespace NadekoBot.Migrations b.ToTable("SelfAssignableRoles"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("RoleId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("SlowmodeIgnoredRole"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("SlowmodeIgnoredUser"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.StartupCommand", b => { b.Property("Id") @@ -1320,6 +1356,20 @@ namespace NadekoBot.Migrations .HasForeignKey("BotConfigId"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("SlowmodeIgnoredRoles") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("SlowmodeIgnoredUsers") + .HasForeignKey("GuildConfigId"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.StartupCommand", b => { b.HasOne("NadekoBot.Services.Database.Models.BotConfig") diff --git a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs index 6d1e3f13..0c0f91be 100644 --- a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs @@ -1,13 +1,17 @@ using Discord; using Discord.Commands; +using Discord.WebSocket; using Microsoft.EntityFrameworkCore; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Services; using NadekoBot.Services.Database; +using NadekoBot.Services.Database.Models; using NLog; using System; using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -23,6 +27,9 @@ namespace NadekoBot.Modules.Administration public class Ratelimiter { + public HashSet IgnoreUsers { get; set; } = new HashSet(); + public HashSet IgnoreRoles { get; set; } = new HashSet(); + public class RatelimitedUser { public ulong UserId { get; set; } @@ -38,10 +45,14 @@ namespace NadekoBot.Modules.Administration public ConcurrentDictionary Users { get; set; } = new ConcurrentDictionary(); - public bool CheckUserRatelimit(ulong id) + public bool CheckUserRatelimit(ulong id, SocketGuildUser optUser) { + if (IgnoreUsers.Contains(id) || + (optUser != null && optUser.RoleIds.Any(x => IgnoreRoles.Contains(x)))) + return false; + var usr = Users.GetOrAdd(id, (key) => new RatelimitedUser() { UserId = id }); - if (usr.MessageCount == MaxMessages) + if (usr.MessageCount >= MaxMessages) { return true; } @@ -67,8 +78,8 @@ namespace NadekoBot.Modules.Administration { try { - var usrMsg = umsg as IUserMessage; - var channel = usrMsg?.Channel as ITextChannel; + var usrMsg = umsg as SocketUserMessage; + var channel = usrMsg?.Channel as SocketTextChannel; if (channel == null || usrMsg.IsAuthor()) return; @@ -76,7 +87,7 @@ namespace NadekoBot.Modules.Administration if (!RatelimitingChannels.TryGetValue(channel.Id, out limiter)) return; - if (limiter.CheckUserRatelimit(usrMsg.Author.Id)) + if (limiter.CheckUserRatelimit(usrMsg.Author.Id, usrMsg.Author as SocketGuildUser)) await usrMsg.DeleteAsync(); } catch (Exception ex) { _log.Warn(ex); } @@ -122,29 +133,76 @@ namespace NadekoBot.Modules.Administration } } - //[NadekoCommand, Usage, Description, Aliases] - //[RequireContext(ContextType.Guild)] - //[RequireUserPermission(GuildPermission.ManageMessages)] - //public async Task SlowmodeWhitelist(IUser user) - //{ - // Ratelimiter throwaway; - // if (RatelimitingChannels.TryRemove(Context.Channel.Id, out throwaway)) - // { - // throwaway.cancelSource.Cancel(); - // await ReplyConfirmLocalized("slowmode_disabled").ConfigureAwait(false); - // } - //} + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.ManageMessages)] + [Priority(1)] + public async Task SlowmodeWhitelist(IUser user) + { + var siu = new SlowmodeIgnoredUser + { + UserId = user.Id + }; - //[NadekoCommand, Usage, Description, Aliases] - //[RequireContext(ContextType.Guild)] - //[RequireUserPermission(GuildPermission.ManageMessages)] - //public async Task SlowmodeWhitelist(IRole role) - //{ - // using (var uow = DbHandler.UnitOfWork()) - // { - // uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.SlowmodeWhitelists)). - // } - //} + HashSet usrs; + bool removed; + using (var uow = DbHandler.UnitOfWork()) + { + usrs = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.SlowmodeIgnoredUsers)) + .SlowmodeIgnoredUsers; + + if (!(removed = usrs.Remove(siu))) + usrs.Add(siu); + + await uow.CompleteAsync().ConfigureAwait(false); + } + + Ratelimiter rl; + if (RatelimitingChannels.TryGetValue(Context.Guild.Id, out rl)) + { + rl.IgnoreUsers = new HashSet(usrs.Select(x => x.UserId)); + } + if(removed) + await ReplyConfirmLocalized("slowmodewl_user_stop", Format.Bold(user.ToString())).ConfigureAwait(false); + else + await ReplyConfirmLocalized("slowmodewl_user_start", Format.Bold(user.ToString())).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.ManageMessages)] + [Priority(0)] + public async Task SlowmodeWhitelist(IRole role) + { + var sir = new SlowmodeIgnoredRole + { + RoleId = role.Id + }; + + HashSet roles; + bool removed; + using (var uow = DbHandler.UnitOfWork()) + { + roles = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.SlowmodeIgnoredRoles)) + .SlowmodeIgnoredRoles; + + if (!(removed = roles.Remove(sir))) + roles.Add(sir); + + await uow.CompleteAsync().ConfigureAwait(false); + } + + Ratelimiter rl; + if (RatelimitingChannels.TryGetValue(Context.Guild.Id, out rl)) + { + rl.IgnoreRoles = new HashSet(roles.Select(x => x.RoleId)); + } + + if (removed) + await ReplyConfirmLocalized("slowmodewl_role_stop", Format.Bold(role.ToString())).ConfigureAwait(false); + else + await ReplyConfirmLocalized("slowmodewl_role_start", Format.Bold(role.ToString())).ConfigureAwait(false); + } } } } \ No newline at end of file diff --git a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs index c8908abe..76dd9ee0 100644 --- a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs @@ -9,6 +9,9 @@ //using System.Threading; //using System; //using System.Collections.Immutable; +//using NadekoBot.Services; +//using NadekoBot.Services.Database.Models; +//using NadekoBot.Extensions; //namespace NadekoBot.Modules.Utility //{ @@ -17,20 +20,45 @@ // [Group] // public class PatreonCommands : NadekoSubmodule // { +// private static readonly PatreonThingy patreon; + +// static PatreonCommands() +// { +// patreon = PatreonThingy.Instance; +// } // [NadekoCommand, Usage, Description, Aliases] // public async Task ClaimPatreonRewards() // { -// var patreon = PatreonThingy.Instance; - -// var pledges = (await patreon.GetPledges().ConfigureAwait(false)) -// .OrderByDescending(x => x.Reward.attributes.amount_cents); - -// if (pledges == null) +// if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) +// return; +// if (DateTime.UtcNow.Day < 5) // { -// await ReplyErrorLocalized("pledges_loading").ConfigureAwait(false); +// await ReplyErrorLocalized("claimpatreon_too_early").ConfigureAwait(false); +// } +// int amount = 0; +// try +// { +// amount = await patreon.ClaimReward(Context.User.Id).ConfigureAwait(false); +// } +// catch (Exception ex) +// { +// _log.Warn(ex); +// } + +// if (amount > 0) +// { +// await ReplyConfirmLocalized("claimpatreon_success", amount).ConfigureAwait(false); // return; // } +// await Context.Channel.EmbedAsync(new Discord.EmbedBuilder().WithOkColor() +// .WithDescription(GetText("claimpatreon_fail")) +// .AddField(efb => efb.WithName("").WithValue("")) +// .AddField(efb => efb.WithName("").WithValue("")) +// .AddField(efb => efb.WithName("").WithValue(""))) +// .ConfigureAwait(false); + +// await ReplyErrorLocalized("claimpatreon_fail").ConfigureAwait(false); // } // } @@ -41,21 +69,16 @@ // private readonly SemaphoreSlim getPledgesLocker = new SemaphoreSlim(1, 1); -// private ImmutableArray pledges; +// public ImmutableArray Pledges { get; private set; } -// static PatreonThingy() { } +// private readonly Timer update; +// private readonly SemaphoreSlim claimLockJustInCase = new SemaphoreSlim(1, 1); -// public async Task> GetPledges() +// private PatreonThingy() // { -// try -// { -// await LoadPledges().ConfigureAwait(false); -// return pledges; -// } -// catch (OperationCanceledException) -// { -// return pledges; -// } +// if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) +// return; +// update = new Timer(async (_) => await LoadPledges(), null, TimeSpan.Zero, TimeSpan.FromHours(3)); // } // public async Task LoadPledges() @@ -89,7 +112,7 @@ // .Select(x => JsonConvert.DeserializeObject(x.ToString()))); // } while (!string.IsNullOrWhiteSpace(data.Links.next)); // } -// pledges = rewards.Join(users, (r) => r.relationships?.patron?.data?.id, (u) => u.id, (x, y) => new PatreonUserAndReward() +// Pledges = rewards.Join(users, (r) => r.relationships?.patron?.data?.id, (u) => u.id, (x, y) => new PatreonUserAndReward() // { // User = y, // Reward = x, @@ -102,7 +125,55 @@ // await Task.Delay(TimeSpan.FromMinutes(5)).ConfigureAwait(false); // getPledgesLocker.Release(); // }); - + +// } +// } + +// public async Task ClaimReward(ulong userId) +// { +// await claimLockJustInCase.WaitAsync(); +// try +// { +// var data = Pledges.FirstOrDefault(x => x.User.id == userId.ToString()); + +// if (data == null) +// return 0; + +// var amount = data.Reward.attributes.amount_cents; + +// using (var uow = DbHandler.UnitOfWork()) +// { +// var users = uow._context.Set(); +// var usr = users.FirstOrDefault(x => x.UserId == userId); + +// if (usr == null) +// { +// users.Add(new RewardedUser() +// { +// UserId = userId, +// LastReward = DateTime.UtcNow, +// AmountRewardedThisMonth = amount, +// }); +// await uow.CompleteAsync().ConfigureAwait(false); +// return amount; +// } + +// if (usr.AmountRewardedThisMonth < amount) +// { +// var toAward = amount - usr.AmountRewardedThisMonth; + +// usr.LastReward = DateTime.UtcNow; +// usr.AmountRewardedThisMonth = amount; + +// await uow.CompleteAsync().ConfigureAwait(false); +// return toAward; +// } +// } +// return 0; +// } +// finally +// { +// claimLockJustInCase.Release(); // } // } // } diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index 20c12253..ef7c365a 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -1706,6 +1706,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to claimpatreonrewards. + /// + public static string claimpatreonrewards_cmd { + get { + return ResourceManager.GetString("claimpatreonrewards_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to If you're subscribed to bot owner's patreon you can user this command to claim your rewards - assuming bot owner did setup has their patreon key.. + /// + public static string claimpatreonrewards_desc { + get { + return ResourceManager.GetString("claimpatreonrewards_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}claimpatreonrewards`. + /// + public static string claimpatreonrewards_usage { + get { + return ResourceManager.GetString("claimpatreonrewards_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to cleanup. /// @@ -7673,6 +7700,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to slowmodewl. + /// + public static string slowmodewhitelist_cmd { + get { + return ResourceManager.GetString("slowmodewhitelist_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ignores a role or a user from the slowmode feature.. + /// + public static string slowmodewhitelist_desc { + get { + return ResourceManager.GetString("slowmodewhitelist_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}slowmodewl SomeRole` or `{0}slowmodewl AdminDude`. + /// + public static string slowmodewhitelist_usage { + get { + return ResourceManager.GetString("slowmodewhitelist_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to softban sb. /// diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 5d1d0539..64236de1 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3321,4 +3321,22 @@ `{0}warnpunish 5 Ban` or `{0}warnpunish 3` + + claimpatreonrewards + + + If you're subscribed to bot owner's patreon you can user this command to claim your rewards - assuming bot owner did setup has their patreon key. + + + `{0}claimpatreonrewards` + + + slowmodewl + + + Ignores a role or a user from the slowmode feature. + + + `{0}slowmodewl SomeRole` or `{0}slowmodewl AdminDude` + \ No newline at end of file diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index 3d91002f..5befa0b0 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -1512,6 +1512,42 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Slowmode will now ignore role {0}. + /// + public static string administration_slowmodewl_role_start { + get { + return ResourceManager.GetString("administration_slowmodewl_role_start", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Slowmode will no longer ignore role {0}. + /// + public static string administration_slowmodewl_role_stop { + get { + return ResourceManager.GetString("administration_slowmodewl_role_stop", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Slowmode will now ignore user {0}. + /// + public static string administration_slowmodewl_user_start { + get { + return ResourceManager.GetString("administration_slowmodewl_user_start", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Slowmode will no longer ignore user {0}. + /// + public static string administration_slowmodewl_user_stop { + get { + return ResourceManager.GetString("administration_slowmodewl_user_stop", resourceCulture); + } + } + /// /// Looks up a localized string similar to soft-banned. /// @@ -5989,6 +6025,87 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Failed claiming rewards due to one of the following reasons:. + /// + public static string utility_claimpatreon_fail { + get { + return ResourceManager.GetString("utility_claimpatreon_fail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Maybe you have already received your reward for this month. You can receive rewards only once a month unless you increase your pledge.. + /// + public static string utility_claimpatreon_fail_already { + get { + return ResourceManager.GetString("utility_claimpatreon_fail_already", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Already rewarded. + /// + public static string utility_claimpatreon_fail_already_title { + get { + return ResourceManager.GetString("utility_claimpatreon_fail_already_title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to In order to be eligible for the reward, you must support the project on patreon. Use {0} command to get the link.. + /// + public static string utility_claimpatreon_fail_sup { + get { + return ResourceManager.GetString("utility_claimpatreon_fail_sup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Not supporting. + /// + public static string utility_claimpatreon_fail_sup_title { + get { + return ResourceManager.GetString("utility_claimpatreon_fail_sup_title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You have to wait a few hours after making your pledge, if you didn't, waiut a bit and then try again later.. + /// + public static string utility_claimpatreon_fail_wait { + get { + return ResourceManager.GetString("utility_claimpatreon_fail_wait", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wait some time. + /// + public static string utility_claimpatreon_fail_wait_title { + get { + return ResourceManager.GetString("utility_claimpatreon_fail_wait_title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You've received {0}. Thanks for supporting the project!. + /// + public static string utility_claimpatreon_success { + get { + return ResourceManager.GetString("utility_claimpatreon_success", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rewards can be claimed on or after 5th of each month.. + /// + public static string utility_claimpatreon_too_early { + get { + return ResourceManager.GetString("utility_claimpatreon_too_early", resourceCulture); + } + } + /// /// Looks up a localized string similar to Commands ran. /// diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index c71eea89..0a523218 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2357,4 +2357,43 @@ Owner ID: {2} I will apply {0} punishment to users with {1} warnings. + + Slowmode will now ignore role {0} + + + Slowmode will no longer ignore role {0} + + + Slowmode will now ignore user {0} + + + Slowmode will no longer ignore user {0} + + + Failed claiming rewards due to one of the following reasons: + + + Maybe you have already received your reward for this month. You can receive rewards only once a month unless you increase your pledge. + + + Already rewarded + + + In order to be eligible for the reward, you must support the project on patreon. Use {0} command to get the link. + + + Not supporting + + + You have to wait a few hours after making your pledge, if you didn't, waiut a bit and then try again later. + + + Wait some time + + + You've received {0}. Thanks for supporting the project! + + + Rewards can be claimed on or after 5th of each month. + \ No newline at end of file diff --git a/src/NadekoBot/Services/Database/Models/GuildConfig.cs b/src/NadekoBot/Services/Database/Models/GuildConfig.cs index 4fe497c1..aaf7addf 100644 --- a/src/NadekoBot/Services/Database/Models/GuildConfig.cs +++ b/src/NadekoBot/Services/Database/Models/GuildConfig.cs @@ -73,10 +73,56 @@ namespace NadekoBot.Services.Database.Models public HashSet CommandAliases { get; set; } = new HashSet(); public List WarnPunishments { get; set; } = new List(); public bool WarningsInitialized { get; set; } + public HashSet SlowmodeIgnoredUsers { get; set; } + public HashSet SlowmodeIgnoredRoles { get; set; } //public List ProtectionIgnoredChannels { get; set; } = new List(); } + public class SlowmodeIgnoredUser : DbEntity + { + public ulong UserId { get; set; } + + // override object.Equals + public override bool Equals(object obj) + { + if (obj == null || GetType() != obj.GetType()) + { + return false; + } + + return ((SlowmodeIgnoredUser)obj).UserId == UserId; + } + + // override object.GetHashCode + public override int GetHashCode() + { + return UserId.GetHashCode(); + } + } + + public class SlowmodeIgnoredRole : DbEntity + { + public ulong RoleId { get; set; } + + // override object.Equals + public override bool Equals(object obj) + { + if (obj == null || GetType() != obj.GetType()) + { + return false; + } + + return ((SlowmodeIgnoredRole)obj).RoleId == RoleId; + } + + // override object.GetHashCode + public override int GetHashCode() + { + return RoleId.GetHashCode(); + } + } + public class WarningPunishment : DbEntity { public int Count { get; set; } diff --git a/src/NadekoBot/Services/Database/Models/RewardedUser.cs b/src/NadekoBot/Services/Database/Models/RewardedUser.cs new file mode 100644 index 00000000..e71843b1 --- /dev/null +++ b/src/NadekoBot/Services/Database/Models/RewardedUser.cs @@ -0,0 +1,11 @@ +//using System; + +//namespace NadekoBot.Services.Database.Models +//{ +// public class RewardedUser +// { +// public ulong UserId { get; set; } +// public int AmountRewardedThisMonth { get; set; } +// public DateTime LastReward { get; set; } +// } +//} From 7e23877fd8784082329c488a9c2daa1cb677bef3 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 1 Apr 2017 21:51:25 +0200 Subject: [PATCH 13/98] .clparew (Claim patreon rewards) added, needs testing --- .../Utility/Commands/PatreonCommands.cs | 324 +++++++++--------- .../Resources/CommandStrings.Designer.cs | 4 +- src/NadekoBot/Resources/CommandStrings.resx | 4 +- .../Resources/ResponseStrings.Designer.cs | 36 +- src/NadekoBot/Resources/ResponseStrings.resx | 18 +- .../Services/Database/Models/RewardedUser.cs | 20 +- 6 files changed, 204 insertions(+), 202 deletions(-) diff --git a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs index 76dd9ee0..6415dd8f 100644 --- a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs @@ -1,181 +1,183 @@ -//using System.Collections.Generic; -//using System.Linq; -//using System.Net.Http; -//using System.Threading.Tasks; -//using Discord.Commands; -//using NadekoBot.Attributes; -//using NadekoBot.Modules.Utility.Models; -//using Newtonsoft.Json; -//using System.Threading; -//using System; -//using System.Collections.Immutable; -//using NadekoBot.Services; -//using NadekoBot.Services.Database.Models; -//using NadekoBot.Extensions; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Discord.Commands; +using NadekoBot.Attributes; +using NadekoBot.Modules.Utility.Models; +using Newtonsoft.Json; +using System.Threading; +using System; +using System.Collections.Immutable; +using NadekoBot.Services; +using NadekoBot.Services.Database.Models; +using NadekoBot.Extensions; -//namespace NadekoBot.Modules.Utility -//{ -// public partial class Utility -// { -// [Group] -// public class PatreonCommands : NadekoSubmodule -// { -// private static readonly PatreonThingy patreon; +namespace NadekoBot.Modules.Utility +{ + public partial class Utility + { + [Group] + public class PatreonCommands : NadekoSubmodule + { + private static readonly PatreonThingy patreon; -// static PatreonCommands() -// { -// patreon = PatreonThingy.Instance; -// } -// [NadekoCommand, Usage, Description, Aliases] -// public async Task ClaimPatreonRewards() -// { -// if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) -// return; -// if (DateTime.UtcNow.Day < 5) -// { -// await ReplyErrorLocalized("claimpatreon_too_early").ConfigureAwait(false); -// } -// int amount = 0; -// try -// { -// amount = await patreon.ClaimReward(Context.User.Id).ConfigureAwait(false); -// } -// catch (Exception ex) -// { -// _log.Warn(ex); -// } + static PatreonCommands() + { + patreon = PatreonThingy.Instance; + } + [NadekoCommand, Usage, Description, Aliases] + public async Task ClaimPatreonRewards() + { + if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) + return; + if (DateTime.UtcNow.Day < 5) + { + await ReplyErrorLocalized("clpa_too_early").ConfigureAwait(false); + } + int amount = 0; + try + { + amount = await patreon.ClaimReward(Context.User.Id).ConfigureAwait(false); + } + catch (Exception ex) + { + _log.Warn(ex); + } -// if (amount > 0) -// { -// await ReplyConfirmLocalized("claimpatreon_success", amount).ConfigureAwait(false); -// return; -// } + if (amount > 0) + { + await ReplyConfirmLocalized("clpa_success", amount + NadekoBot.BotConfig.CurrencySign).ConfigureAwait(false); + return; + } -// await Context.Channel.EmbedAsync(new Discord.EmbedBuilder().WithOkColor() -// .WithDescription(GetText("claimpatreon_fail")) -// .AddField(efb => efb.WithName("").WithValue("")) -// .AddField(efb => efb.WithName("").WithValue("")) -// .AddField(efb => efb.WithName("").WithValue(""))) -// .ConfigureAwait(false); + await Context.Channel.EmbedAsync(new Discord.EmbedBuilder().WithOkColor() + .WithDescription(GetText("clpa_fail")) + .AddField(efb => efb.WithName(GetText("clpa_fail_already_title")).WithValue(GetText("clpa_fail_already"))) + .AddField(efb => efb.WithName(GetText("clpa_fail_wait_title")).WithValue(GetText("clpa_fail_wait"))) + .AddField(efb => efb.WithName(GetText("clpa_fail_sup_title")).WithValue(GetText("clpa_fail_sup")))) + .ConfigureAwait(false); + } + } -// await ReplyErrorLocalized("claimpatreon_fail").ConfigureAwait(false); -// } -// } + public class PatreonThingy + { + public static PatreonThingy _instance = new PatreonThingy(); + public static PatreonThingy Instance => _instance; -// public class PatreonThingy -// { -// public static PatreonThingy _instance = new PatreonThingy(); -// public static PatreonThingy Instance => _instance; + private readonly SemaphoreSlim getPledgesLocker = new SemaphoreSlim(1, 1); -// private readonly SemaphoreSlim getPledgesLocker = new SemaphoreSlim(1, 1); + public ImmutableArray Pledges { get; private set; } -// public ImmutableArray Pledges { get; private set; } + private readonly Timer update; + private readonly SemaphoreSlim claimLockJustInCase = new SemaphoreSlim(1, 1); -// private readonly Timer update; -// private readonly SemaphoreSlim claimLockJustInCase = new SemaphoreSlim(1, 1); + private PatreonThingy() + { + if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) + return; + update = new Timer(async (_) => await LoadPledges(), null, TimeSpan.Zero, TimeSpan.FromHours(3)); + } -// private PatreonThingy() -// { -// if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) -// return; -// update = new Timer(async (_) => await LoadPledges(), null, TimeSpan.Zero, TimeSpan.FromHours(3)); -// } + public async Task LoadPledges() + { + await getPledgesLocker.WaitAsync(1000).ConfigureAwait(false); + try + { + var rewards = new List(); + var users = new List(); + using (var http = new HttpClient()) + { + http.DefaultRequestHeaders.Clear(); + http.DefaultRequestHeaders.Add("Authorization", "Bearer " + NadekoBot.Credentials.PatreonAccessToken); + var data = new PatreonData() + { + Links = new PatreonDataLinks() + { + next = "https://api.patreon.com/oauth2/api/campaigns/334038/pledges" + } + }; + do + { + var res = await http.GetStringAsync(data.Links.next) + .ConfigureAwait(false); + data = JsonConvert.DeserializeObject(res); + var pledgers = data.Data.Where(x => x["type"].ToString() == "pledge"); + rewards.AddRange(pledgers.Select(x => JsonConvert.DeserializeObject(x.ToString())) + .Where(x => x.attributes.declined_since == null)); + users.AddRange(data.Included + .Where(x => x["type"].ToString() == "user") + .Select(x => JsonConvert.DeserializeObject(x.ToString()))); + } while (!string.IsNullOrWhiteSpace(data.Links.next)); + } + Pledges = rewards.Join(users, (r) => r.relationships?.patron?.data?.id, (u) => u.id, (x, y) => new PatreonUserAndReward() + { + User = y, + Reward = x, + }).ToImmutableArray(); + } + finally + { + var _ = Task.Run(async () => + { + await Task.Delay(TimeSpan.FromMinutes(5)).ConfigureAwait(false); + getPledgesLocker.Release(); + }); + } + } -// public async Task LoadPledges() -// { -// await getPledgesLocker.WaitAsync(1000).ConfigureAwait(false); -// try -// { -// var rewards = new List(); -// var users = new List(); -// using (var http = new HttpClient()) -// { -// http.DefaultRequestHeaders.Clear(); -// http.DefaultRequestHeaders.Add("Authorization", "Bearer " + NadekoBot.Credentials.PatreonAccessToken); -// var data = new PatreonData() -// { -// Links = new PatreonDataLinks() -// { -// next = "https://api.patreon.com/oauth2/api/campaigns/334038/pledges" -// } -// }; -// do -// { -// var res = await http.GetStringAsync(data.Links.next) -// .ConfigureAwait(false); -// data = JsonConvert.DeserializeObject(res); -// var pledgers = data.Data.Where(x => x["type"].ToString() == "pledge"); -// rewards.AddRange(pledgers.Select(x => JsonConvert.DeserializeObject(x.ToString())) -// .Where(x => x.attributes.declined_since == null)); -// users.AddRange(data.Included -// .Where(x => x["type"].ToString() == "user") -// .Select(x => JsonConvert.DeserializeObject(x.ToString()))); -// } while (!string.IsNullOrWhiteSpace(data.Links.next)); -// } -// Pledges = rewards.Join(users, (r) => r.relationships?.patron?.data?.id, (u) => u.id, (x, y) => new PatreonUserAndReward() -// { -// User = y, -// Reward = x, -// }).ToImmutableArray(); -// } -// finally -// { -// var _ = Task.Run(async () => -// { -// await Task.Delay(TimeSpan.FromMinutes(5)).ConfigureAwait(false); -// getPledgesLocker.Release(); -// }); + public async Task ClaimReward(ulong userId) + { + await claimLockJustInCase.WaitAsync(); + try + { + var data = Pledges.FirstOrDefault(x => x.User.id == userId.ToString()); -// } -// } + if (data == null) + return 0; -// public async Task ClaimReward(ulong userId) -// { -// await claimLockJustInCase.WaitAsync(); -// try -// { -// var data = Pledges.FirstOrDefault(x => x.User.id == userId.ToString()); + var amount = data.Reward.attributes.amount_cents; -// if (data == null) -// return 0; + using (var uow = DbHandler.UnitOfWork()) + { + var users = uow._context.Set(); + var usr = users.FirstOrDefault(x => x.UserId == userId); -// var amount = data.Reward.attributes.amount_cents; + if (usr == null) + { + users.Add(new RewardedUser() + { + UserId = userId, + LastReward = DateTime.UtcNow, + AmountRewardedThisMonth = amount, + }); -// using (var uow = DbHandler.UnitOfWork()) -// { -// var users = uow._context.Set(); -// var usr = users.FirstOrDefault(x => x.UserId == userId); + await CurrencyHandler.AddCurrencyAsync(usr.UserId, "Patreon reward", amount, uow).ConfigureAwait(false); -// if (usr == null) -// { -// users.Add(new RewardedUser() -// { -// UserId = userId, -// LastReward = DateTime.UtcNow, -// AmountRewardedThisMonth = amount, -// }); -// await uow.CompleteAsync().ConfigureAwait(false); -// return amount; -// } + await uow.CompleteAsync().ConfigureAwait(false); + return amount; + } -// if (usr.AmountRewardedThisMonth < amount) -// { -// var toAward = amount - usr.AmountRewardedThisMonth; + if (usr.AmountRewardedThisMonth < amount) + { + var toAward = amount - usr.AmountRewardedThisMonth; -// usr.LastReward = DateTime.UtcNow; -// usr.AmountRewardedThisMonth = amount; + usr.LastReward = DateTime.UtcNow; + usr.AmountRewardedThisMonth = amount; -// await uow.CompleteAsync().ConfigureAwait(false); -// return toAward; -// } -// } -// return 0; -// } -// finally -// { -// claimLockJustInCase.Release(); -// } -// } -// } -// } -//} + await CurrencyHandler.AddCurrencyAsync(usr.UserId, "Patreon reward", toAward, uow).ConfigureAwait(false); + + await uow.CompleteAsync().ConfigureAwait(false); + return toAward; + } + } + return 0; + } + finally + { + claimLockJustInCase.Release(); + } + } + } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index ef7c365a..76dac5be 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -1707,7 +1707,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to claimpatreonrewards. + /// Looks up a localized string similar to clparew. /// public static string claimpatreonrewards_cmd { get { @@ -1716,7 +1716,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to If you're subscribed to bot owner's patreon you can user this command to claim your rewards - assuming bot owner did setup has their patreon key.. + /// Looks up a localized string similar to Claim patreon rewards. If you're subscribed to bot owner's patreon you can user this command to claim your rewards - assuming bot owner did setup has their patreon key.. /// public static string claimpatreonrewards_desc { get { diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 64236de1..f3662ef3 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3322,10 +3322,10 @@ `{0}warnpunish 5 Ban` or `{0}warnpunish 3` - claimpatreonrewards + clparew - If you're subscribed to bot owner's patreon you can user this command to claim your rewards - assuming bot owner did setup has their patreon key. + Claim patreon rewards. If you're subscribed to bot owner's patreon you can user this command to claim your rewards - assuming bot owner did setup has their patreon key. `{0}claimpatreonrewards` diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index 5befa0b0..48394268 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -6028,81 +6028,81 @@ namespace NadekoBot.Resources { /// /// Looks up a localized string similar to Failed claiming rewards due to one of the following reasons:. /// - public static string utility_claimpatreon_fail { + public static string utility_clpa_fail { get { - return ResourceManager.GetString("utility_claimpatreon_fail", resourceCulture); + return ResourceManager.GetString("utility_clpa_fail", resourceCulture); } } /// /// Looks up a localized string similar to Maybe you have already received your reward for this month. You can receive rewards only once a month unless you increase your pledge.. /// - public static string utility_claimpatreon_fail_already { + public static string utility_clpa_fail_already { get { - return ResourceManager.GetString("utility_claimpatreon_fail_already", resourceCulture); + return ResourceManager.GetString("utility_clpa_fail_already", resourceCulture); } } /// /// Looks up a localized string similar to Already rewarded. /// - public static string utility_claimpatreon_fail_already_title { + public static string utility_clpa_fail_already_title { get { - return ResourceManager.GetString("utility_claimpatreon_fail_already_title", resourceCulture); + return ResourceManager.GetString("utility_clpa_fail_already_title", resourceCulture); } } /// /// Looks up a localized string similar to In order to be eligible for the reward, you must support the project on patreon. Use {0} command to get the link.. /// - public static string utility_claimpatreon_fail_sup { + public static string utility_clpa_fail_sup { get { - return ResourceManager.GetString("utility_claimpatreon_fail_sup", resourceCulture); + return ResourceManager.GetString("utility_clpa_fail_sup", resourceCulture); } } /// /// Looks up a localized string similar to Not supporting. /// - public static string utility_claimpatreon_fail_sup_title { + public static string utility_clpa_fail_sup_title { get { - return ResourceManager.GetString("utility_claimpatreon_fail_sup_title", resourceCulture); + return ResourceManager.GetString("utility_clpa_fail_sup_title", resourceCulture); } } /// /// Looks up a localized string similar to You have to wait a few hours after making your pledge, if you didn't, waiut a bit and then try again later.. /// - public static string utility_claimpatreon_fail_wait { + public static string utility_clpa_fail_wait { get { - return ResourceManager.GetString("utility_claimpatreon_fail_wait", resourceCulture); + return ResourceManager.GetString("utility_clpa_fail_wait", resourceCulture); } } /// /// Looks up a localized string similar to Wait some time. /// - public static string utility_claimpatreon_fail_wait_title { + public static string utility_clpa_fail_wait_title { get { - return ResourceManager.GetString("utility_claimpatreon_fail_wait_title", resourceCulture); + return ResourceManager.GetString("utility_clpa_fail_wait_title", resourceCulture); } } /// /// Looks up a localized string similar to You've received {0}. Thanks for supporting the project!. /// - public static string utility_claimpatreon_success { + public static string utility_clpa_success { get { - return ResourceManager.GetString("utility_claimpatreon_success", resourceCulture); + return ResourceManager.GetString("utility_clpa_success", resourceCulture); } } /// /// Looks up a localized string similar to Rewards can be claimed on or after 5th of each month.. /// - public static string utility_claimpatreon_too_early { + public static string utility_clpa_too_early { get { - return ResourceManager.GetString("utility_claimpatreon_too_early", resourceCulture); + return ResourceManager.GetString("utility_clpa_too_early", resourceCulture); } } diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 0a523218..105efa2b 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2369,31 +2369,31 @@ Owner ID: {2} Slowmode will no longer ignore user {0} - + Failed claiming rewards due to one of the following reasons: - + Maybe you have already received your reward for this month. You can receive rewards only once a month unless you increase your pledge. - + Already rewarded - + In order to be eligible for the reward, you must support the project on patreon. Use {0} command to get the link. - + Not supporting - + You have to wait a few hours after making your pledge, if you didn't, waiut a bit and then try again later. - + Wait some time - + You've received {0}. Thanks for supporting the project! - + Rewards can be claimed on or after 5th of each month. \ No newline at end of file diff --git a/src/NadekoBot/Services/Database/Models/RewardedUser.cs b/src/NadekoBot/Services/Database/Models/RewardedUser.cs index e71843b1..535f1354 100644 --- a/src/NadekoBot/Services/Database/Models/RewardedUser.cs +++ b/src/NadekoBot/Services/Database/Models/RewardedUser.cs @@ -1,11 +1,11 @@ -//using System; +using System; -//namespace NadekoBot.Services.Database.Models -//{ -// public class RewardedUser -// { -// public ulong UserId { get; set; } -// public int AmountRewardedThisMonth { get; set; } -// public DateTime LastReward { get; set; } -// } -//} +namespace NadekoBot.Services.Database.Models +{ + public class RewardedUser + { + public ulong UserId { get; set; } + public int AmountRewardedThisMonth { get; set; } + public DateTime LastReward { get; set; } + } +} From 3cec4f14d0ecb035e7e60b8825d9280d8b440016 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sun, 2 Apr 2017 00:01:02 +0200 Subject: [PATCH 14/98] .clparew finished --- ...20170401205753_patreon-rewards.Designer.cs | 1456 +++++++++++++++++ .../20170401205753_patreon-rewards.cs | 40 + .../NadekoSqliteContextModelSnapshot.cs | 21 + .../Utility/Commands/PatreonCommands.cs | 41 +- .../Resources/ResponseStrings.Designer.cs | 24 +- src/NadekoBot/Resources/ResponseStrings.resx | 12 +- .../Database/Models/PatreonRewards.cs | 15 - .../Services/Database/Models/RewardedUser.cs | 2 +- .../Services/Database/NadekoContext.cs | 7 + 9 files changed, 1583 insertions(+), 35 deletions(-) create mode 100644 src/NadekoBot/Migrations/20170401205753_patreon-rewards.Designer.cs create mode 100644 src/NadekoBot/Migrations/20170401205753_patreon-rewards.cs delete mode 100644 src/NadekoBot/Services/Database/Models/PatreonRewards.cs diff --git a/src/NadekoBot/Migrations/20170401205753_patreon-rewards.Designer.cs b/src/NadekoBot/Migrations/20170401205753_patreon-rewards.Designer.cs new file mode 100644 index 00000000..e693300d --- /dev/null +++ b/src/NadekoBot/Migrations/20170401205753_patreon-rewards.Designer.cs @@ -0,0 +1,1456 @@ +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("20170401205753_patreon-rewards")] + partial class patreonrewards + { + 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.RewardedUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AmountRewardedThisMonth"); + + b.Property("DateAdded"); + + b.Property("LastReward"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("RewardedUsers"); + }); + + 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.SlowmodeIgnoredRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("RoleId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("SlowmodeIgnoredRole"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("SlowmodeIgnoredUser"); + }); + + 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.SlowmodeIgnoredRole", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("SlowmodeIgnoredRoles") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("SlowmodeIgnoredUsers") + .HasForeignKey("GuildConfigId"); + }); + + 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/20170401205753_patreon-rewards.cs b/src/NadekoBot/Migrations/20170401205753_patreon-rewards.cs new file mode 100644 index 00000000..83057ff5 --- /dev/null +++ b/src/NadekoBot/Migrations/20170401205753_patreon-rewards.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace NadekoBot.Migrations +{ + public partial class patreonrewards : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "RewardedUsers", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + AmountRewardedThisMonth = table.Column(nullable: false), + DateAdded = table.Column(nullable: true), + LastReward = table.Column(nullable: false), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RewardedUsers", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_RewardedUsers_UserId", + table: "RewardedUsers", + column: "UserId", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "RewardedUsers"); + } + } +} diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index 3f6df376..303783e4 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -931,6 +931,27 @@ namespace NadekoBot.Migrations b.ToTable("Reminders"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.RewardedUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AmountRewardedThisMonth"); + + b.Property("DateAdded"); + + b.Property("LastReward"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("RewardedUsers"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b => { b.Property("Id") diff --git a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs index 6415dd8f..e9b78014 100644 --- a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs @@ -12,6 +12,7 @@ using System.Collections.Immutable; using NadekoBot.Services; using NadekoBot.Services.Database.Models; using NadekoBot.Extensions; +using Discord; namespace NadekoBot.Modules.Utility { @@ -31,10 +32,11 @@ namespace NadekoBot.Modules.Utility { if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) return; - if (DateTime.UtcNow.Day < 5) - { - await ReplyErrorLocalized("clpa_too_early").ConfigureAwait(false); - } + //if (DateTime.UtcNow.Day < 5) + //{ + // await ReplyErrorLocalized("clpa_too_early").ConfigureAwait(false); + // return; + //} int amount = 0; try { @@ -50,12 +52,13 @@ namespace NadekoBot.Modules.Utility await ReplyConfirmLocalized("clpa_success", amount + NadekoBot.BotConfig.CurrencySign).ConfigureAwait(false); return; } - - await Context.Channel.EmbedAsync(new Discord.EmbedBuilder().WithOkColor() + var helpcmd = Format.Code(NadekoBot.ModulePrefixes[typeof(Help.Help).Name] + "donate"); + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() .WithDescription(GetText("clpa_fail")) .AddField(efb => efb.WithName(GetText("clpa_fail_already_title")).WithValue(GetText("clpa_fail_already"))) .AddField(efb => efb.WithName(GetText("clpa_fail_wait_title")).WithValue(GetText("clpa_fail_wait"))) - .AddField(efb => efb.WithName(GetText("clpa_fail_sup_title")).WithValue(GetText("clpa_fail_sup")))) + .AddField(efb => efb.WithName(GetText("clpa_fail_conn_title")).WithValue(GetText("clpa_fail_conn"))) + .AddField(efb => efb.WithName(GetText("clpa_fail_sup_title")).WithValue(GetText("clpa_fail_sup", helpcmd)))) .ConfigureAwait(false); } } @@ -129,9 +132,10 @@ namespace NadekoBot.Modules.Utility public async Task ClaimReward(ulong userId) { await claimLockJustInCase.WaitAsync(); + var now = DateTime.UtcNow; try { - var data = Pledges.FirstOrDefault(x => x.User.id == userId.ToString()); + var data = Pledges.FirstOrDefault(x => x.User.attributes?.social_connections?.discord?.user_id == userId.ToString()); if (data == null) return 0; @@ -148,24 +152,35 @@ namespace NadekoBot.Modules.Utility users.Add(new RewardedUser() { UserId = userId, - LastReward = DateTime.UtcNow, + LastReward = now, AmountRewardedThisMonth = amount, }); - await CurrencyHandler.AddCurrencyAsync(usr.UserId, "Patreon reward", amount, uow).ConfigureAwait(false); + await CurrencyHandler.AddCurrencyAsync(userId, "Patreon reward - new", amount, uow).ConfigureAwait(false); await uow.CompleteAsync().ConfigureAwait(false); return amount; } - if (usr.AmountRewardedThisMonth < amount) + if (usr.LastReward.Month != now.Month) + { + usr.LastReward = now; + usr.AmountRewardedThisMonth = amount; + + await CurrencyHandler.AddCurrencyAsync(userId, "Patreon reward - recurring", amount, uow).ConfigureAwait(false); + + await uow.CompleteAsync().ConfigureAwait(false); + return amount; + } + + if ( usr.AmountRewardedThisMonth < amount) { var toAward = amount - usr.AmountRewardedThisMonth; - usr.LastReward = DateTime.UtcNow; + usr.LastReward = now; usr.AmountRewardedThisMonth = amount; - await CurrencyHandler.AddCurrencyAsync(usr.UserId, "Patreon reward", toAward, uow).ConfigureAwait(false); + await CurrencyHandler.AddCurrencyAsync(usr.UserId, "Patreon reward - update", toAward, uow).ConfigureAwait(false); await uow.CompleteAsync().ConfigureAwait(false); return toAward; diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index 48394268..445e025b 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -6035,7 +6035,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to Maybe you have already received your reward for this month. You can receive rewards only once a month unless you increase your pledge.. + /// Looks up a localized string similar to Maybe you've already received your reward for this month. You can receive rewards only once a month unless you increase your pledge.. /// public static string utility_clpa_fail_already { get { @@ -6053,7 +6053,25 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to In order to be eligible for the reward, you must support the project on patreon. Use {0} command to get the link.. + /// Looks up a localized string similar to Your discord account might not be connected to Patreon.. If you are unsure what that means, or don't know how to connect it - you have to go to [Patreon account settings page](https://patreon.com/settings/account) and click 'Connect to discord' button.. + /// + public static string utility_clpa_fail_conn { + get { + return ResourceManager.GetString("utility_clpa_fail_conn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Discord account not connected. + /// + public static string utility_clpa_fail_conn_title { + get { + return ResourceManager.GetString("utility_clpa_fail_conn_title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to In order to be eligible for the reward, you must support the project on patreon. You can use {0} command to get the link.. /// public static string utility_clpa_fail_sup { get { @@ -6071,7 +6089,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to You have to wait a few hours after making your pledge, if you didn't, waiut a bit and then try again later.. + /// Looks up a localized string similar to You have to wait a few hours after making your pledge, if you didn't, try again later.. /// public static string utility_clpa_fail_wait { get { diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 105efa2b..4d605da8 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2373,19 +2373,25 @@ Owner ID: {2} Failed claiming rewards due to one of the following reasons: - Maybe you have already received your reward for this month. You can receive rewards only once a month unless you increase your pledge. + Maybe you've already received your reward for this month. You can receive rewards only once a month unless you increase your pledge. Already rewarded + + Your discord account might not be connected to Patreon.. If you are unsure what that means, or don't know how to connect it - you have to go to [Patreon account settings page](https://patreon.com/settings/account) and click 'Connect to discord' button. + + + Discord account not connected + - In order to be eligible for the reward, you must support the project on patreon. Use {0} command to get the link. + In order to be eligible for the reward, you must support the project on patreon. You can use {0} command to get the link. Not supporting - You have to wait a few hours after making your pledge, if you didn't, waiut a bit and then try again later. + You have to wait a few hours after making your pledge, if you didn't, try again later. Wait some time diff --git a/src/NadekoBot/Services/Database/Models/PatreonRewards.cs b/src/NadekoBot/Services/Database/Models/PatreonRewards.cs deleted file mode 100644 index 0e1532b3..00000000 --- a/src/NadekoBot/Services/Database/Models/PatreonRewards.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace NadekoBot.Services.Database.Models -{ - public class PatreonRewards : DbEntity - { - public ulong UserId { get; set; } - public ulong PledgeCents { get; set; } - public ulong Awarded { get; set; } - } -} diff --git a/src/NadekoBot/Services/Database/Models/RewardedUser.cs b/src/NadekoBot/Services/Database/Models/RewardedUser.cs index 535f1354..f7db8dc4 100644 --- a/src/NadekoBot/Services/Database/Models/RewardedUser.cs +++ b/src/NadekoBot/Services/Database/Models/RewardedUser.cs @@ -2,7 +2,7 @@ namespace NadekoBot.Services.Database.Models { - public class RewardedUser + public class RewardedUser : DbEntity { public ulong UserId { get; set; } public int AmountRewardedThisMonth { get; set; } diff --git a/src/NadekoBot/Services/Database/NadekoContext.cs b/src/NadekoBot/Services/Database/NadekoContext.cs index a82cfde8..9c084867 100644 --- a/src/NadekoBot/Services/Database/NadekoContext.cs +++ b/src/NadekoBot/Services/Database/NadekoContext.cs @@ -51,6 +51,7 @@ namespace NadekoBot.Services.Database public DbSet EightBallResponses { get; set; } public DbSet RaceAnimals { get; set; } public DbSet ModulePrefixes { get; set; } + public DbSet RewardedUsers { get; set; } public NadekoContext() : base() { @@ -277,6 +278,12 @@ namespace NadekoBot.Services.Database #region Warnings var warn = modelBuilder.Entity(); #endregion + + #region PatreonRewards + var pr = modelBuilder.Entity(); + pr.HasIndex(x => x.UserId) + .IsUnique(); + #endregion } } } From c512f6360b0fe32d312fde5f28b89addfae5ea7b Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sun, 2 Apr 2017 00:25:26 +0200 Subject: [PATCH 15/98] .slowmodewl implemented and now works properly --- .../Commands/RatelimitCommand.cs | 45 ++++++++++--------- .../Resources/ResponseStrings.Designer.cs | 10 ++--- src/NadekoBot/Resources/ResponseStrings.resx | 10 ++--- .../Impl/GuildConfigRepository.cs | 2 + 4 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs index 0c0f91be..57dd4c89 100644 --- a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs @@ -5,7 +5,6 @@ using Microsoft.EntityFrameworkCore; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Services; -using NadekoBot.Services.Database; using NadekoBot.Services.Database.Models; using NLog; using System; @@ -20,16 +19,16 @@ namespace NadekoBot.Modules.Administration public partial class Administration { [Group] - public class RatelimitCommand : NadekoSubmodule + public class RatelimitCommands : NadekoSubmodule { public static ConcurrentDictionary RatelimitingChannels = new ConcurrentDictionary(); + public static ConcurrentDictionary> IgnoredRoles = new ConcurrentDictionary>(); + public static ConcurrentDictionary> IgnoredUsers = new ConcurrentDictionary>(); + private new static readonly Logger _log; public class Ratelimiter { - public HashSet IgnoreUsers { get; set; } = new HashSet(); - public HashSet IgnoreRoles { get; set; } = new HashSet(); - public class RatelimitedUser { public ulong UserId { get; set; } @@ -45,10 +44,13 @@ namespace NadekoBot.Modules.Administration public ConcurrentDictionary Users { get; set; } = new ConcurrentDictionary(); - public bool CheckUserRatelimit(ulong id, SocketGuildUser optUser) + public bool CheckUserRatelimit(ulong id, ulong guildId, SocketGuildUser optUser) { - if (IgnoreUsers.Contains(id) || - (optUser != null && optUser.RoleIds.Any(x => IgnoreRoles.Contains(x)))) + HashSet ignoreUsers; + HashSet ignoreRoles; + + if ((IgnoredUsers.TryGetValue(guildId, out ignoreUsers) && ignoreUsers.Contains(id)) || + (optUser != null && IgnoredRoles.TryGetValue(guildId, out ignoreRoles) && optUser.RoleIds.Any(x => ignoreRoles.Contains(x)))) return false; var usr = Users.GetOrAdd(id, (key) => new RatelimitedUser() { UserId = id }); @@ -70,10 +72,20 @@ namespace NadekoBot.Modules.Administration } } - static RatelimitCommand() + static RatelimitCommands() { _log = LogManager.GetCurrentClassLogger(); + IgnoredRoles = new ConcurrentDictionary>( + NadekoBot.AllGuildConfigs + .ToDictionary(x => x.GuildId, + x => new HashSet(x.SlowmodeIgnoredRoles.Select(y => y.RoleId)))); + + IgnoredUsers = new ConcurrentDictionary>( + NadekoBot.AllGuildConfigs + .ToDictionary(x => x.GuildId, + x => new HashSet(x.SlowmodeIgnoredUsers.Select(y => y.UserId)))); + NadekoBot.Client.MessageReceived += async (umsg) => { try @@ -87,7 +99,7 @@ namespace NadekoBot.Modules.Administration if (!RatelimitingChannels.TryGetValue(channel.Id, out limiter)) return; - if (limiter.CheckUserRatelimit(usrMsg.Author.Id, usrMsg.Author as SocketGuildUser)) + if (limiter.CheckUserRatelimit(usrMsg.Author.Id, channel.Guild.Id, usrMsg.Author as SocketGuildUser)) await usrMsg.DeleteAsync(); } catch (Exception ex) { _log.Warn(ex); } @@ -157,11 +169,8 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync().ConfigureAwait(false); } - Ratelimiter rl; - if (RatelimitingChannels.TryGetValue(Context.Guild.Id, out rl)) - { - rl.IgnoreUsers = new HashSet(usrs.Select(x => x.UserId)); - } + IgnoredUsers.AddOrUpdate(Context.Guild.Id, new HashSet(usrs.Select(x => x.UserId)), (key, old) => new HashSet(usrs.Select(x => x.UserId))); + if(removed) await ReplyConfirmLocalized("slowmodewl_user_stop", Format.Bold(user.ToString())).ConfigureAwait(false); else @@ -192,11 +201,7 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync().ConfigureAwait(false); } - Ratelimiter rl; - if (RatelimitingChannels.TryGetValue(Context.Guild.Id, out rl)) - { - rl.IgnoreRoles = new HashSet(roles.Select(x => x.RoleId)); - } + IgnoredRoles.AddOrUpdate(Context.Guild.Id, new HashSet(roles.Select(x => x.RoleId)), (key, old) => new HashSet(roles.Select(x => x.RoleId))); if (removed) await ReplyConfirmLocalized("slowmodewl_role_stop", Format.Bold(role.ToString())).ConfigureAwait(false); diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index 445e025b..e13d8513 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -1513,7 +1513,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to Slowmode will now ignore role {0}. + /// Looks up a localized string similar to Slowmode will now ignore {0} role.. /// public static string administration_slowmodewl_role_start { get { @@ -1522,7 +1522,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to Slowmode will no longer ignore role {0}. + /// Looks up a localized string similar to Slowmode will no longer ignore {0} role.. /// public static string administration_slowmodewl_role_stop { get { @@ -1531,7 +1531,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to Slowmode will now ignore user {0}. + /// Looks up a localized string similar to Slowmode will now ignore user {0}.. /// public static string administration_slowmodewl_user_start { get { @@ -1540,7 +1540,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to Slowmode will no longer ignore user {0}. + /// Looks up a localized string similar to Slowmode will no longer ignore user {0}.. /// public static string administration_slowmodewl_user_stop { get { @@ -6107,7 +6107,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to You've received {0}. Thanks for supporting the project!. + /// Looks up a localized string similar to You've received {0} Thanks for supporting the project!. /// public static string utility_clpa_success { get { diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 4d605da8..83d701f3 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2358,16 +2358,16 @@ Owner ID: {2} I will apply {0} punishment to users with {1} warnings. - Slowmode will now ignore role {0} + Slowmode will now ignore {0} role. - Slowmode will no longer ignore role {0} + Slowmode will no longer ignore {0} role. - Slowmode will now ignore user {0} + Slowmode will now ignore user {0}. - Slowmode will no longer ignore user {0} + Slowmode will no longer ignore user {0}. Failed claiming rewards due to one of the following reasons: @@ -2397,7 +2397,7 @@ Owner ID: {2} Wait some time - You've received {0}. Thanks for supporting the project! + You've received {0} Thanks for supporting the project! Rewards can be claimed on or after 5th of each month. diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs index 01a44677..ebe41406 100644 --- a/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs @@ -38,6 +38,8 @@ namespace NadekoBot.Services.Database.Repositories.Impl .Include(gc => gc.CommandCooldowns) .Include(gc => gc.GuildRepeaters) .Include(gc => gc.AntiRaidSetting) + .Include(gc => gc.SlowmodeIgnoredRoles) + .Include(gc => gc.SlowmodeIgnoredUsers) .Include(gc => gc.AntiSpamSetting) .ThenInclude(x => x.IgnoredChannels) .ToList(); From 3364f110a47f3e78b7d77c13a690ba45c4f9a5e9 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sun, 2 Apr 2017 00:26:44 +0200 Subject: [PATCH 16/98] Startup commands will now run with 400ms delay between each other --- src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs index 09924682..dcb36766 100644 --- a/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs @@ -57,6 +57,7 @@ namespace NadekoBot.Modules.Administration } catch { } } + await Task.Delay(400).ConfigureAwait(false); } }); } From dfdfab44f7e28069944470c898544f3847c6813d Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sun, 2 Apr 2017 02:33:43 +0200 Subject: [PATCH 17/98] Woops, forgot to uncomment day check --- .../Modules/Utility/Commands/PatreonCommands.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs index e9b78014..303774f4 100644 --- a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs @@ -32,11 +32,11 @@ namespace NadekoBot.Modules.Utility { if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) return; - //if (DateTime.UtcNow.Day < 5) - //{ - // await ReplyErrorLocalized("clpa_too_early").ConfigureAwait(false); - // return; - //} + if (DateTime.UtcNow.Day < 5) + { + await ReplyErrorLocalized("clpa_too_early").ConfigureAwait(false); + return; + } int amount = 0; try { From e3a1d17d8e863eaa2fae1b9eac7a0984a37ba17a Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sun, 2 Apr 2017 12:45:35 +0200 Subject: [PATCH 18/98] $lb can't take negative page numbers anymore xD --- src/NadekoBot/Modules/Gambling/Gambling.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/NadekoBot/Modules/Gambling/Gambling.cs b/src/NadekoBot/Modules/Gambling/Gambling.cs index 760f8156..83db6048 100644 --- a/src/NadekoBot/Modules/Gambling/Gambling.cs +++ b/src/NadekoBot/Modules/Gambling/Gambling.cs @@ -246,6 +246,9 @@ namespace NadekoBot.Modules.Gambling [NadekoCommand, Usage, Description, Aliases] public async Task Leaderboard(int page = 1) { + if (page < 1) + return; + List richest; using (var uow = DbHandler.UnitOfWork()) { From 9afab5ad4c7afcb954b54bd30b9ae62f5bc4bb12 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Sun, 2 Apr 2017 18:26:27 +0200 Subject: [PATCH 19/98] Update ResponseStrings.en-US.resx (POEditor.com) --- .../Resources/ResponseStrings.en-US.resx | 126 +++++++++++++++++- 1 file changed, 125 insertions(+), 1 deletion(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.en-US.resx b/src/NadekoBot/Resources/ResponseStrings.en-US.resx index ccff686e..753f8135 100644 --- a/src/NadekoBot/Resources/ResponseStrings.en-US.resx +++ b/src/NadekoBot/Resources/ResponseStrings.en-US.resx @@ -740,7 +740,7 @@ Reason: {1} Slow mode initiated - soft-banned (kicked) + soft-banned PLURAL @@ -2278,5 +2278,129 @@ Owner ID: {2} Competitive playtime + + Channel + + + Command Text + + + Kicked + PLURAL + + + Moderator + + + page {0} + + + 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. + + + User not found. + + + User {0} has been warned. + + + User {0} has been warned and {1} punishment has been applied. + + + Warned on {0} server + + + On {0} at {1} by {2} + + + All warnings have been cleared for {0}. + + + No warning on this page. + + + Warnlog for {0} + + + No punishments set. + + + cleared by {0} + + + Warning punishment list + + + Having {0} warnings will no longer trigger a punishment. + + + I will apply {0} punishment to users with {1} warnings. + + + Slowmode will now ignore {0} role. + + + Slowmode will no longer ignore {0} role. + + + Slowmode will now ignore user {0}. + + + Slowmode will no longer ignore user {0}. + + + Failed claiming rewards due to one of the following reasons: + + + Maybe you've already received your reward for this month. You can receive rewards only once a month unless you increase your pledge. + + + Already rewarded + + + Your discord account might not be connected to Patreon. If you are unsure what that means, or don't know how to connect it - you have to go to [Patreon account settings page](https://patreon.com/settings/account) and click 'Connect to discord' button. + + + Discord account not connected + + + In order to be eligible for the reward, you must support the project on patreon. You can use {0} command to get the link. + + + Not supporting + + + You have to wait a few hours after making your pledge, if you didn't, try again later. + + + Wait some time + + + You've received {0} Thanks for supporting the project! + + + Rewards can be claimed on or after 5th of each month. + \ No newline at end of file From d256d520e4b12c5c89d83502d7f5e10b186d241e Mon Sep 17 00:00:00 2001 From: Shikhir Arora Date: Sun, 2 Apr 2017 15:43:02 -0400 Subject: [PATCH 20/98] Add quote ID search --- .../Modules/Utility/Commands/QuoteCommands.cs | 48 ++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs b/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs index ea4bc674..37fdbf07 100644 --- a/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs @@ -1,4 +1,4 @@ -using Discord; +using Discord; using Discord.Commands; using NadekoBot.Attributes; using NadekoBot.Extensions; @@ -100,7 +100,43 @@ namespace NadekoBot.Modules.Utility await Context.Channel.SendMessageAsync($"`#{keywordquote.Id}` 💬 " + keyword.ToLowerInvariant() + ": " + keywordquote.Text.SanitizeMentions()); } - + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task QuoteId(int id) + { + if (id < 0 || id > Int32.MaxValue) + return; + + using (var uow = DbHandler.UnitOfWork()) + { + var qfromid = uow.Quotes.Get(id); + CREmbed crembed; + + if (qfromid == null) + { + await Context.Channel.SendErrorAsync(GetText("quotes_notfound")); + } + else if (CREmbed.TryParse(qfromid.Text, out crembed)) + { + try + { + await Context.Channel.EmbedAsync(crembed.ToEmbed(), crembed.PlainText ?? "") + .ConfigureAwait(false); + } + catch (Exception ex) + { + _log.Warn("Sending CREmbed failed"); + _log.Warn(ex); + } + return; + } + + else { await Context.Channel.SendMessageAsync($"`#{qfromid.Id}` 🗯️ " + qfromid.Keyword.ToLowerInvariant() + ": " + + qfromid.Text.SanitizeMentions()); } + } + } + [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] public async Task AddQuote(string keyword, [Remainder] string text) @@ -130,8 +166,8 @@ namespace NadekoBot.Modules.Utility public async Task DeleteQuote(int id) { var isAdmin = ((IGuildUser) Context.Message.Author).GuildPermissions.Administrator; - - var sucess = false; + + var success = false; string response; using (var uow = DbHandler.UnitOfWork()) { @@ -145,11 +181,11 @@ namespace NadekoBot.Modules.Utility { uow.Quotes.Remove(q); await uow.CompleteAsync().ConfigureAwait(false); - sucess = true; + success = true; response = GetText("quote_deleted", id); } } - if (sucess) + if (success) await Context.Channel.SendConfirmAsync(response); else await Context.Channel.SendErrorAsync(response); From 80c1c141b754fc5c3fa6f4e8a367e7e32b1abf42 Mon Sep 17 00:00:00 2001 From: Shikhir Arora Date: Sun, 2 Apr 2017 15:44:15 -0400 Subject: [PATCH 21/98] Update CommandStrings.resx --- src/NadekoBot/Resources/CommandStrings.resx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index f3662ef3..cbdfc5b3 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -1151,6 +1151,15 @@ `{0}qsearch keyword text` + + + quoteid qid + + + Displays the quote with the specified ID number. Quote ID numbers can be found by typing `.liqu [num]` where `[num]` is a number of a page which contains 15 quotes. + + + `{0}qid 123456` deletequote delq @@ -3339,4 +3348,4 @@ `{0}slowmodewl SomeRole` or `{0}slowmodewl AdminDude` - \ No newline at end of file + From 44e8939a5beefdcc289a0aede312340bb7288e4a Mon Sep 17 00:00:00 2001 From: Shikhir Arora Date: Sun, 2 Apr 2017 15:46:30 -0400 Subject: [PATCH 22/98] Update CommandStrings.Designer.cs --- .../Resources/CommandStrings.Designer.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index 76dac5be..437ef468 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -5729,6 +5729,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar quoteid qid. + /// + public static string quoteid_cmd { + get { + return ResourceManager.GetString("quoteid_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Displays the quote with the specified ID number. Quote ID numbers can be found by typing `.liqu [num]` where `[num]` is a number of a page which contains 15 quotes.. + /// + public static string quoteid_desc { + get { + return ResourceManager.GetString("quoteid_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}qid 123456`. + /// + public static string quoteid_usage { + get { + return ResourceManager.GetString("quoteid_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to race. /// From 510a46698592605ffb8a2a7f65c98fa433a4a4e5 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sun, 2 Apr 2017 21:47:35 +0200 Subject: [PATCH 23/98] Aliased commands now do take extra parameters while aliased --- .../Resources/ResponseStrings.Designer.cs | 2 +- src/NadekoBot/Resources/ResponseStrings.resx | 2 +- src/NadekoBot/Services/CommandHandler.cs | 19 ++++++++++++++++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index e13d8513..ce51f8f4 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -6053,7 +6053,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to Your discord account might not be connected to Patreon.. If you are unsure what that means, or don't know how to connect it - you have to go to [Patreon account settings page](https://patreon.com/settings/account) and click 'Connect to discord' button.. + /// Looks up a localized string similar to Your discord account might not be connected to Patreon. If you are unsure what that means, or don't know how to connect it - you have to go to [Patreon account settings page](https://patreon.com/settings/account) and click 'Connect to discord' button.. /// public static string utility_clpa_fail_conn { get { diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 83d701f3..42a22f42 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2379,7 +2379,7 @@ Owner ID: {2} Already rewarded - Your discord account might not be connected to Patreon.. If you are unsure what that means, or don't know how to connect it - you have to go to [Patreon account settings page](https://patreon.com/settings/account) and click 'Connect to discord' button. + Your discord account might not be connected to Patreon. If you are unsure what that means, or don't know how to connect it - you have to go to [Patreon account settings page](https://patreon.com/settings/account) and click 'Connect to discord' button. Discord account not connected diff --git a/src/NadekoBot/Services/CommandHandler.cs b/src/NadekoBot/Services/CommandHandler.cs index 31f30932..f47e45d5 100644 --- a/src/NadekoBot/Services/CommandHandler.cs +++ b/src/NadekoBot/Services/CommandHandler.cs @@ -342,10 +342,22 @@ namespace NadekoBot.Services ConcurrentDictionary maps; if (Modules.Utility.Utility.CommandMapCommands.AliasMaps.TryGetValue(guild.Id, out maps)) { - string newMessageContent; - if (maps.TryGetValue(messageContent.Trim().ToLowerInvariant(), out newMessageContent)) + + var keys = maps.Keys + .OrderByDescending(x => x.Length); + + var lowerMessageContent = messageContent.ToLowerInvariant(); + foreach (var k in keys) { - _log.Info(@"--Mapping Command-- + string newMessageContent; + if (lowerMessageContent.StartsWith(k + " ")) + newMessageContent = maps[k] + messageContent.Substring(k.Length, messageContent.Length - k.Length); + else if (lowerMessageContent == k) + newMessageContent = maps[k]; + else + continue; + + _log.Info(@"--Mapping Command-- GuildId: {0} Trigger: {1} Mapping: {2}", guild.Id, messageContent, newMessageContent); @@ -353,6 +365,7 @@ namespace NadekoBot.Services messageContent = newMessageContent; try { await usrMsg.Channel.SendConfirmAsync($"{oldMessageContent} => {newMessageContent}").ConfigureAwait(false); } catch { } + break; } } } From a4d78dfc0d45b49c798428521a4e358467030dc3 Mon Sep 17 00:00:00 2001 From: Shikhir Arora Date: Sun, 2 Apr 2017 15:48:17 -0400 Subject: [PATCH 24/98] Update ResponseStrings.resx --- src/NadekoBot/Resources/ResponseStrings.resx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 83d701f3..a8b2d0bb 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2083,6 +2083,9 @@ Owner ID: {2} No quotes on this page. + + No quotes found matching the quote ID specified. + No quotes found which you can remove. @@ -2402,4 +2405,4 @@ Owner ID: {2} Rewards can be claimed on or after 5th of each month. - \ No newline at end of file + From 34b4884ec41186b52b6f4164e29f4c624b67c4b3 Mon Sep 17 00:00:00 2001 From: Shikhir Arora Date: Sun, 2 Apr 2017 15:49:43 -0400 Subject: [PATCH 25/98] Update ResponseStrings.Designer.cs --- src/NadekoBot/Resources/ResponseStrings.Designer.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index e13d8513..1aa7c15e 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -6506,6 +6506,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to No quotes found matching the quote ID specified.. + /// + public static string utility_quotes_notfound { + get { + return ResourceManager.GetString("utility_quotes_notfound", resourceCulture); + } + } + /// /// Looks up a localized string similar to No quotes found which you can remove.. /// From 43d8f1997a1b95bd55fb9bca03ab7cc2e620a366 Mon Sep 17 00:00:00 2001 From: Shikhir Arora Date: Sun, 2 Apr 2017 15:57:56 -0400 Subject: [PATCH 26/98] Update QuoteCommands.cs --- src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs b/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs index 37fdbf07..b8819255 100644 --- a/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs @@ -105,7 +105,7 @@ namespace NadekoBot.Modules.Utility [RequireContext(ContextType.Guild)] public async Task QuoteId(int id) { - if (id < 0 || id > Int32.MaxValue) + if (id < 0) return; using (var uow = DbHandler.UnitOfWork()) From d0380b0cbfc2ce45b5f4b0dcc07e32e198b3603e Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 3 Apr 2017 12:43:59 +0200 Subject: [PATCH 27/98] .ping command added --- src/NadekoBot/Modules/Utility/Utility.cs | 12 ++++++++++++ src/NadekoBot/Resources/CommandStrings.resx | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/src/NadekoBot/Modules/Utility/Utility.cs b/src/NadekoBot/Modules/Utility/Utility.cs index ee92b771..1ac77e73 100644 --- a/src/NadekoBot/Modules/Utility/Utility.cs +++ b/src/NadekoBot/Modules/Utility/Utility.cs @@ -16,6 +16,7 @@ using System.Collections.Generic; using Newtonsoft.Json; using Discord.WebSocket; using NadekoBot.Services; +using System.Diagnostics; namespace NadekoBot.Modules.Utility { @@ -494,5 +495,16 @@ namespace NadekoBot.Modules.Utility await Context.User.SendFileAsync( await JsonConvert.SerializeObject(grouping, Formatting.Indented).ToStream().ConfigureAwait(false), title, title).ConfigureAwait(false); } + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task Ping() + { + var sw = Stopwatch.StartNew(); + var msg = await Context.Channel.SendMessageAsync("🏓").ConfigureAwait(false); + sw.Stop(); + msg.DeleteAfter(0); + + await Context.Channel.SendConfirmAsync($"{Format.Bold(Context.User.ToString())} 🏓 {(int)sw.Elapsed.TotalMilliseconds}ms").ConfigureAwait(false); + } } } \ No newline at end of file diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index f3662ef3..83d9659b 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3330,6 +3330,15 @@ `{0}claimpatreonrewards` + + ping + + + Ping the bot to see if there are latency issues. + + + `{0}ping` + slowmodewl From 6817b1ba0746ab2a281710fd2fdfe45af358de9f Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 3 Apr 2017 14:30:31 +0200 Subject: [PATCH 28/98] .rar, .sr, .renr and .rr will now work only on roles lower than your highest role --- .../Modules/Administration/Administration.cs | 18 +++++++++++-- .../Resources/CommandStrings.Designer.cs | 27 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/NadekoBot/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs index 905243ba..4eec4ebd 100644 --- a/src/NadekoBot/Modules/Administration/Administration.cs +++ b/src/NadekoBot/Modules/Administration/Administration.cs @@ -11,7 +11,6 @@ using Discord.WebSocket; using NadekoBot.Services.Database.Models; using static NadekoBot.Modules.Permissions.Permissions; using System.Collections.Concurrent; -using Microsoft.EntityFrameworkCore; using NLog; namespace NadekoBot.Modules.Administration @@ -99,6 +98,10 @@ namespace NadekoBot.Modules.Administration [RequireBotPermission(GuildPermission.ManageRoles)] public async Task Setrole(IGuildUser usr, [Remainder] IRole role) { + var guser = (IGuildUser)Context.User; + var maxRole = guser.GetRoles().Max(x => x.Position); + if (maxRole < role.Position || maxRole <= usr.GetRoles().Max(x => x.Position)) + return; try { await usr.AddRolesAsync(role).ConfigureAwait(false); @@ -118,6 +121,9 @@ namespace NadekoBot.Modules.Administration [RequireBotPermission(GuildPermission.ManageRoles)] public async Task Removerole(IGuildUser usr, [Remainder] IRole role) { + var guser = (IGuildUser)Context.User; + if (Context.User.Id != guser.Guild.OwnerId && guser.GetRoles().Max(x => x.Position) <= usr.GetRoles().Max(x => x.Position)) + return; try { await usr.RemoveRolesAsync(role).ConfigureAwait(false); @@ -135,6 +141,9 @@ namespace NadekoBot.Modules.Administration [RequireBotPermission(GuildPermission.ManageRoles)] public async Task RenameRole(IRole roleToEdit, string newname) { + var guser = (IGuildUser)Context.User; + if (Context.User.Id != guser.Guild.OwnerId && guser.GetRoles().Max(x => x.Position) <= roleToEdit.Position) + return; try { if (roleToEdit.Position > (await Context.Guild.GetCurrentUserAsync().ConfigureAwait(false)).GetRoles().Max(r => r.Position)) @@ -157,9 +166,14 @@ namespace NadekoBot.Modules.Administration [RequireBotPermission(GuildPermission.ManageRoles)] public async Task RemoveAllRoles([Remainder] IGuildUser user) { + var guser = (IGuildUser)Context.User; + + var userRoles = user.GetRoles(); + if (guser.Id != Context.Guild.OwnerId && (user.Id == Context.Guild.OwnerId || guser.GetRoles().Max(x => x.Position) <= userRoles.Max(x => x.Position))) + return; try { - await user.RemoveRolesAsync(user.GetRoles()).ConfigureAwait(false); + await user.RemoveRolesAsync(userRoles).ConfigureAwait(false); await ReplyConfirmLocalized("rar", Format.Bold(user.ToString())).ConfigureAwait(false); } catch diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index 76dac5be..865609b2 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -5378,6 +5378,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to ping. + /// + public static string ping_cmd { + get { + return ResourceManager.GetString("ping_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ping the bot to see if there are latency issues.. + /// + public static string ping_desc { + get { + return ResourceManager.GetString("ping_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}ping`. + /// + public static string ping_usage { + get { + return ResourceManager.GetString("ping_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to place. /// From 3e1b5d7e572a064c2ea4712de868eb9f172fa40c Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 3 Apr 2017 23:18:18 +0200 Subject: [PATCH 29/98] some small fixes, .time added, closes #989 --- .../Modules/Administration/Administration.cs | 3 +- .../Commands/AutoAssignRoleCommands.cs | 6 +++ .../Commands/SelfAssignedRolesCommand.cs | 8 ++++ .../Searches/Commands/Models/TimeModels.cs | 42 +++++++++++++++++++ src/NadekoBot/Modules/Searches/Searches.cs | 21 ++++++++++ .../Resources/CommandStrings.Designer.cs | 29 ++++++++++++- src/NadekoBot/Resources/CommandStrings.resx | 13 +++++- .../Resources/ResponseStrings.Designer.cs | 20 ++++----- src/NadekoBot/Resources/ResponseStrings.resx | 9 ++-- src/NadekoBot/_Extensions/Extensions.cs | 2 +- 10 files changed, 134 insertions(+), 19 deletions(-) create mode 100644 src/NadekoBot/Modules/Searches/Commands/Models/TimeModels.cs diff --git a/src/NadekoBot/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs index 4eec4ebd..6ecefe10 100644 --- a/src/NadekoBot/Modules/Administration/Administration.cs +++ b/src/NadekoBot/Modules/Administration/Administration.cs @@ -169,7 +169,8 @@ namespace NadekoBot.Modules.Administration var guser = (IGuildUser)Context.User; var userRoles = user.GetRoles(); - if (guser.Id != Context.Guild.OwnerId && (user.Id == Context.Guild.OwnerId || guser.GetRoles().Max(x => x.Position) <= userRoles.Max(x => x.Position))) + if (guser.Id != Context.Guild.OwnerId && + (user.Id == Context.Guild.OwnerId || guser.GetRoles().Max(x => x.Position) <= userRoles.Max(x => x.Position))) return; try { diff --git a/src/NadekoBot/Modules/Administration/Commands/AutoAssignRoleCommands.cs b/src/NadekoBot/Modules/Administration/Commands/AutoAssignRoleCommands.cs index 98a8844f..13a3422a 100644 --- a/src/NadekoBot/Modules/Administration/Commands/AutoAssignRoleCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/AutoAssignRoleCommands.cs @@ -1,6 +1,7 @@ using Discord; using Discord.Commands; using NadekoBot.Attributes; +using NadekoBot.Extensions; using NadekoBot.Services; using NLog; using System; @@ -48,6 +49,11 @@ namespace NadekoBot.Modules.Administration [RequireUserPermission(GuildPermission.ManageRoles)] public async Task AutoAssignRole([Remainder] IRole role = null) { + var guser = (IGuildUser)Context.User; + if (role != null) + if (Context.User.Id != guser.Guild.OwnerId && guser.GetRoles().Max(x => x.Position) <= role.Position) + return; + using (var uow = DbHandler.UnitOfWork()) { var conf = uow.GuildConfigs.For(Context.Guild.Id, set => set); diff --git a/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs index 6ac60f21..e13a278f 100644 --- a/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs @@ -43,6 +43,10 @@ namespace NadekoBot.Modules.Administration { IEnumerable roles; + var guser = (IGuildUser)Context.User; + if (Context.User.Id != guser.Guild.OwnerId && guser.GetRoles().Max(x => x.Position) <= role.Position) + return; + string msg; var error = false; using (var uow = DbHandler.UnitOfWork()) @@ -75,6 +79,10 @@ namespace NadekoBot.Modules.Administration [RequireUserPermission(GuildPermission.ManageRoles)] public async Task Rsar([Remainder] IRole role) { + var guser = (IGuildUser)Context.User; + if (Context.User.Id != guser.Guild.OwnerId && guser.GetRoles().Max(x => x.Position) <= role.Position) + return; + bool success; using (var uow = DbHandler.UnitOfWork()) { diff --git a/src/NadekoBot/Modules/Searches/Commands/Models/TimeModels.cs b/src/NadekoBot/Modules/Searches/Commands/Models/TimeModels.cs new file mode 100644 index 00000000..e997b78c --- /dev/null +++ b/src/NadekoBot/Modules/Searches/Commands/Models/TimeModels.cs @@ -0,0 +1,42 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.Modules.Searches.Commands.Models +{ + public class TimeZoneResult + { + public double DstOffset { get; set; } + public double RawOffset { get; set; } + + //public string TimeZoneId { get; set; } + public string TimeZoneName { get; set; } + } + + public class GeolocationResult + { + + public class GeolocationModel + { + public class GeometryModel + { + public class LocationModel + { + public float Lat { get; set; } + public float Lng { get; set; } + } + + public LocationModel Location { get; set; } + } + + [JsonProperty("formatted_address")] + public string FormattedAddress { get; set; } + public GeometryModel Geometry { get; set; } + } + + public GeolocationModel[] results; + } +} diff --git a/src/NadekoBot/Modules/Searches/Searches.cs b/src/NadekoBot/Modules/Searches/Searches.cs index 472a17d5..3e6aa1bc 100644 --- a/src/NadekoBot/Modules/Searches/Searches.cs +++ b/src/NadekoBot/Modules/Searches/Searches.cs @@ -56,6 +56,27 @@ namespace NadekoBot.Modules.Searches await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); } + [NadekoCommand, Usage, Description, Aliases] + public async Task Time([Remainder] string arg) + { + if (string.IsNullOrWhiteSpace(arg) || string.IsNullOrWhiteSpace(NadekoBot.Credentials.GoogleApiKey)) + return; + + using (var http = new HttpClient()) + { + var res = await http.GetStringAsync($"https://maps.googleapis.com/maps/api/geocode/json?address={arg}&key={NadekoBot.Credentials.GoogleApiKey}").ConfigureAwait(false); + var obj = JsonConvert.DeserializeObject(res); + + var currentSeconds = DateTime.UtcNow.UnixTimestamp(); + var timeRes = await http.GetStringAsync($"https://maps.googleapis.com/maps/api/timezone/json?location={obj.results[0].Geometry.Location.Lat},{obj.results[0].Geometry.Location.Lng}×tamp={currentSeconds}&key={NadekoBot.Credentials.GoogleApiKey}").ConfigureAwait(false); + var timeObj = JsonConvert.DeserializeObject(timeRes); + + var time = DateTime.UtcNow.AddSeconds(timeObj.DstOffset + timeObj.RawOffset); + + await ReplyConfirmLocalized("time", Format.Bold(obj.results[0].FormattedAddress), Format.Code(time.ToString("HH:mm")), timeObj.TimeZoneName).ConfigureAwait(false); + } + } + [NadekoCommand, Usage, Description, Aliases] public async Task Youtube([Remainder] string query = null) { diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index c3e4c03b..c8f3ed92 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -5757,7 +5757,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar quoteid qid. + /// Looks up a localized string similar to quoteid qid. /// public static string quoteid_cmd { get { @@ -8267,6 +8267,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to time. + /// + public static string time_cmd { + get { + return ResourceManager.GetString("time_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Shows the current time and timezone in the specified location.. + /// + public static string time_desc { + get { + return ResourceManager.GetString("time_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}time London, UK`. + /// + public static string time_usage { + get { + return ResourceManager.GetString("time_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to timezone. /// diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index ec1f2125..1d5479ab 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -1152,7 +1152,7 @@ `{0}qsearch keyword text` - + quoteid qid @@ -3357,4 +3357,13 @@ `{0}slowmodewl SomeRole` or `{0}slowmodewl AdminDude` - + + time + + + Shows the current time and timezone in the specified location. + + + `{0}time London, UK` + + \ No newline at end of file diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index 9561c996..f4171166 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -5773,6 +5773,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Time in {0} is {1} - {2}. + /// + public static string searches_time { + get { + return ResourceManager.GetString("searches_time", resourceCulture); + } + } + /// /// Looks up a localized string similar to Title:. /// @@ -6498,7 +6507,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to No quotes on this page.. + /// Looks up a localized string similar to No quotes found matching the quote ID specified.. /// public static string utility_quotes_page_none { get { @@ -6506,15 +6515,6 @@ namespace NadekoBot.Resources { } } - /// - /// Looks up a localized string similar to No quotes found matching the quote ID specified.. - /// - public static string utility_quotes_notfound { - get { - return ResourceManager.GetString("utility_quotes_notfound", resourceCulture); - } - } - /// /// Looks up a localized string similar to No quotes found which you can remove.. /// diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 31b11e93..2a1d1e7f 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2082,10 +2082,7 @@ Owner ID: {2} Page {0} of quotes - No quotes on this page. - No quotes found matching the quote ID specified. - No quotes found which you can remove. @@ -2405,4 +2402,8 @@ Owner ID: {2} Rewards can be claimed on or after 5th of each month. - + + Time in {0} is {1} - {2} + Time in London, UK is 15:30 - Time Zone Name + + \ No newline at end of file diff --git a/src/NadekoBot/_Extensions/Extensions.cs b/src/NadekoBot/_Extensions/Extensions.cs index b880944c..52d8ab3a 100644 --- a/src/NadekoBot/_Extensions/Extensions.cs +++ b/src/NadekoBot/_Extensions/Extensions.cs @@ -193,7 +193,7 @@ namespace NadekoBot.Extensions public static string SanitizeMentions(this string str) => str.Replace("@everyone", "@everyοne").Replace("@here", "@һere"); - public static double UnixTimestamp(this DateTime dt) => dt.ToUniversalTime().Subtract(new DateTime(1970, 1, 1)).TotalSeconds; + public static double UnixTimestamp(this DateTime dt) => dt.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds; public static async Task SendMessageAsync(this IUser user, string message, bool isTTS = false) => await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendMessageAsync(message, isTTS).ConfigureAwait(false); From bbda4c7a3bb35e68330ab8da50e7277df906c87e Mon Sep 17 00:00:00 2001 From: Kwoth Date: Tue, 4 Apr 2017 01:50:27 +0200 Subject: [PATCH 30/98] disabling >cleverbot with permissions will also disable talking with chatterbot --- .../Games/Commands/CleverBotCommands.cs | 28 ++++++---- .../Modules/Permissions/Permissions.cs | 18 ++++++ src/NadekoBot/Services/CommandHandler.cs | 55 +++++++++---------- 3 files changed, 63 insertions(+), 38 deletions(-) diff --git a/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs b/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs index fd426be3..fcaecc98 100644 --- a/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs @@ -40,16 +40,19 @@ namespace NadekoBot.Modules.Games _log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s"); } - public static async Task TryAsk(IUserMessage msg) + public static string PrepareMessage(IUserMessage msg, out ChatterBotSession cleverbot) { var channel = msg.Channel as ITextChannel; + cleverbot = null; if (channel == null) - return false; + return null; - Lazy cleverbot; - if (!CleverbotGuilds.TryGetValue(channel.Guild.Id, out cleverbot)) - return false; + Lazy lazyCleverbot; + if (!CleverbotGuilds.TryGetValue(channel.Guild.Id, out lazyCleverbot)) + return null; + + cleverbot = lazyCleverbot.Value; var nadekoId = NadekoBot.Client.CurrentUser.Id; var normalMention = $"<@{nadekoId}> "; @@ -65,19 +68,24 @@ namespace NadekoBot.Modules.Games } else { - return false; + return null; } - await msg.Channel.TriggerTypingAsync().ConfigureAwait(false); + return message; + } - var response = await cleverbot.Value.Think(message).ConfigureAwait(false); + public static async Task TryAsk(ChatterBotSession cleverbot, ITextChannel channel, string message) + { + await channel.TriggerTypingAsync().ConfigureAwait(false); + + var response = await cleverbot.Think(message).ConfigureAwait(false); try { - await msg.Channel.SendConfirmAsync(response.SanitizeMentions()).ConfigureAwait(false); + await channel.SendConfirmAsync(response.SanitizeMentions()).ConfigureAwait(false); } catch { - await msg.Channel.SendConfirmAsync(response.SanitizeMentions()).ConfigureAwait(false); // try twice :\ + await channel.SendConfirmAsync(response.SanitizeMentions()).ConfigureAwait(false); // try twice :\ } return true; } diff --git a/src/NadekoBot/Modules/Permissions/Permissions.cs b/src/NadekoBot/Modules/Permissions/Permissions.cs index ec0e1016..a942fd7e 100644 --- a/src/NadekoBot/Modules/Permissions/Permissions.cs +++ b/src/NadekoBot/Modules/Permissions/Permissions.cs @@ -62,6 +62,24 @@ namespace NadekoBot.Modules.Permissions log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s"); } + public static PermissionCache GetCache(ulong guildId) + { + PermissionCache pc; + if (!Permissions.Cache.TryGetValue(guildId, out pc)) + { + using (var uow = DbHandler.UnitOfWork()) + { + var config = uow.GuildConfigs.For(guildId, + set => set.Include(x => x.Permissions)); + Permissions.UpdateCache(config); + } + Permissions.Cache.TryGetValue(guildId, out pc); + if (pc == null) + throw new Exception("Cache is null."); + } + return pc; + } + private static void TryMigratePermissions() { var log = LogManager.GetCurrentClassLogger(); diff --git a/src/NadekoBot/Services/CommandHandler.cs b/src/NadekoBot/Services/CommandHandler.cs index f47e45d5..5c4fa19c 100644 --- a/src/NadekoBot/Services/CommandHandler.cs +++ b/src/NadekoBot/Services/CommandHandler.cs @@ -18,6 +18,7 @@ using System.Collections.Concurrent; using System.Threading; using Microsoft.EntityFrameworkCore; using NadekoBot.DataStructures; +using Services.CleverBotApi; namespace NadekoBot.Services { @@ -109,13 +110,33 @@ namespace NadekoBot.Services return Task.CompletedTask; } - private async Task TryRunCleverbot(IUserMessage usrMsg, IGuild guild) + private async Task TryRunCleverbot(IUserMessage usrMsg, SocketGuild guild) { if (guild == null) return false; try { - var cleverbotExecuted = await Games.CleverBotCommands.TryAsk(usrMsg).ConfigureAwait(false); + Games.ChatterBotSession cbs; + var message = Games.CleverBotCommands.PrepareMessage(usrMsg, out cbs); + if(message == null || cbs == null) + return false; + + PermissionCache pc = Permissions.GetCache(guild.Id); + int index; + if ( + !pc.Permissions.CheckPermissions(usrMsg, + NadekoBot.ModulePrefixes[typeof(Games).Name] + "cleverbot", + typeof(Games).Name, + 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 true; + } + + var cleverbotExecuted = await Games.CleverBotCommands.TryAsk(cbs, (ITextChannel)usrMsg.Channel, message).ConfigureAwait(false); if (cleverbotExecuted) { _log.Info($@"CleverBot Executed @@ -278,6 +299,7 @@ namespace NadekoBot.Services return; var exec1 = Environment.TickCount - execTime; + var cleverBotRan = await Task.Run(() => TryRunCleverbot(usrMsg, guild)).ConfigureAwait(false); if (cleverBotRan) @@ -294,19 +316,8 @@ namespace NadekoBot.Services { 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."); - } + PermissionCache pc = Permissions.GetCache(guild.Id); + int index; if ( !pc.Permissions.CheckPermissions(usrMsg, cr.Trigger, "ActualCustomReactions", @@ -457,21 +468,9 @@ namespace NadekoBot.Services var cmd = commands[i].Command; var resetCommand = cmd.Name == "resetperms"; var module = cmd.Module.GetTopLevelModule(); - PermissionCache pc; if (context.Guild != null) { - //todo move to permissions module? - if (!Permissions.Cache.TryGetValue(context.Guild.Id, out pc)) - { - using (var uow = DbHandler.UnitOfWork()) - { - var config = uow.GuildConfigs.GcWithPermissionsv2For(context.Guild.Id); - Permissions.UpdateCache(config); - } - Permissions.Cache.TryGetValue(context.Guild.Id, out pc); - if(pc == null) - throw new Exception("Cache is null."); - } + PermissionCache pc = Permissions.GetCache(context.Guild.Id); int index; if (!resetCommand && !pc.Permissions.CheckPermissions(context.Message, cmd.Aliases.First(), module.Name, out index)) { From af744cb3d74138bbe4128c2aba87127e74451693 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Tue, 4 Apr 2017 01:52:51 +0200 Subject: [PATCH 31/98] Removed old cleverbot stuff --- .../Games/Commands/CleverBotCommands.cs | 3 - .../Services/CleverBotApi/ChatterBot.cs | 25 --- .../CleverBotApi/ChatterBotFactory.cs | 51 ------ .../CleverBotApi/ChatterBotSession.cs | 28 ---- .../CleverBotApi/ChatterBotThought.cs | 26 --- .../Services/CleverBotApi/ChatterBotType.cs | 27 ---- .../Services/CleverBotApi/Cleverbot.cs | 116 -------------- .../Services/CleverBotApi/Pandorabots.cs | 68 -------- src/NadekoBot/Services/CleverBotApi/Utils.cs | 148 ------------------ src/NadekoBot/Services/CommandHandler.cs | 2 - 10 files changed, 494 deletions(-) delete mode 100644 src/NadekoBot/Services/CleverBotApi/ChatterBot.cs delete mode 100644 src/NadekoBot/Services/CleverBotApi/ChatterBotFactory.cs delete mode 100644 src/NadekoBot/Services/CleverBotApi/ChatterBotSession.cs delete mode 100644 src/NadekoBot/Services/CleverBotApi/ChatterBotThought.cs delete mode 100644 src/NadekoBot/Services/CleverBotApi/ChatterBotType.cs delete mode 100644 src/NadekoBot/Services/CleverBotApi/Cleverbot.cs delete mode 100644 src/NadekoBot/Services/CleverBotApi/Pandorabots.cs delete mode 100644 src/NadekoBot/Services/CleverBotApi/Utils.cs diff --git a/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs b/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs index fcaecc98..8abb47d5 100644 --- a/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs @@ -1,11 +1,9 @@ using Discord; using Discord.Commands; -using Discord.WebSocket; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Services; using NLog; -//using Services.CleverBotApi; using System; using System.Collections.Concurrent; using System.Diagnostics; @@ -13,7 +11,6 @@ using System.Linq; using System.Net.Http; using System.Threading.Tasks; using Newtonsoft.Json; -using Services.CleverBotApi; namespace NadekoBot.Modules.Games { diff --git a/src/NadekoBot/Services/CleverBotApi/ChatterBot.cs b/src/NadekoBot/Services/CleverBotApi/ChatterBot.cs deleted file mode 100644 index 746b44aa..00000000 --- a/src/NadekoBot/Services/CleverBotApi/ChatterBot.cs +++ /dev/null @@ -1,25 +0,0 @@ - /* - ChatterBotAPI - Copyright (C) 2011 pierredavidbelanger@gmail.com - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -namespace Services.CleverBotApi -{ - public interface ChatterBot - { - ChatterBotSession CreateSession(); - } -} \ No newline at end of file diff --git a/src/NadekoBot/Services/CleverBotApi/ChatterBotFactory.cs b/src/NadekoBot/Services/CleverBotApi/ChatterBotFactory.cs deleted file mode 100644 index e183c249..00000000 --- a/src/NadekoBot/Services/CleverBotApi/ChatterBotFactory.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; - -/* - ChatterBotAPI - Copyright (C) 2011 pierredavidbelanger@gmail.com - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -namespace Services.CleverBotApi -{ - public class ChatterBotFactory - { - public static ChatterBot Create(ChatterBotType type) - { - return Create(type, null); - } - - public static ChatterBot Create(ChatterBotType type, object arg) - { -#if GLOBAL_NADEKO - var url = "http://www.cleverbot.com/webservicemin?uc=777&botapi=nadekobot"; -#else - var url = "http://www.cleverbot.com/webservicemin?uc=777&botapi=chatterbotapi"; -#endif - - switch (type) - { - case ChatterBotType.CLEVERBOT: - return new Cleverbot("http://www.cleverbot.com/", url, 26); - case ChatterBotType.JABBERWACKY: - return new Cleverbot("http://jabberwacky.com", "http://jabberwacky.com/webservicemin", 20); - case ChatterBotType.PANDORABOTS: - if (arg == null) throw new ArgumentException("PANDORABOTS needs a botid arg", nameof(arg)); - return new Pandorabots(arg.ToString()); - } - return null; - } - } -} \ No newline at end of file diff --git a/src/NadekoBot/Services/CleverBotApi/ChatterBotSession.cs b/src/NadekoBot/Services/CleverBotApi/ChatterBotSession.cs deleted file mode 100644 index 0f063571..00000000 --- a/src/NadekoBot/Services/CleverBotApi/ChatterBotSession.cs +++ /dev/null @@ -1,28 +0,0 @@ -/* - ChatterBotAPI - Copyright (C) 2011 pierredavidbelanger@gmail.com - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -using System.Threading.Tasks; - -namespace Services.CleverBotApi -{ - public interface ChatterBotSession - { - Task Think(ChatterBotThought thought); - Task Think(string text); - } -} \ No newline at end of file diff --git a/src/NadekoBot/Services/CleverBotApi/ChatterBotThought.cs b/src/NadekoBot/Services/CleverBotApi/ChatterBotThought.cs deleted file mode 100644 index 1a385642..00000000 --- a/src/NadekoBot/Services/CleverBotApi/ChatterBotThought.cs +++ /dev/null @@ -1,26 +0,0 @@ -/* - ChatterBotAPI - Copyright (C) 2011 pierredavidbelanger@gmail.com - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -namespace Services.CleverBotApi -{ - public class ChatterBotThought - { - public string[] Emotions { get; set; } - public string Text { get; set; } - } -} \ No newline at end of file diff --git a/src/NadekoBot/Services/CleverBotApi/ChatterBotType.cs b/src/NadekoBot/Services/CleverBotApi/ChatterBotType.cs deleted file mode 100644 index e4e8fab8..00000000 --- a/src/NadekoBot/Services/CleverBotApi/ChatterBotType.cs +++ /dev/null @@ -1,27 +0,0 @@ -/* - ChatterBotAPI - Copyright (C) 2011 pierredavidbelanger@gmail.com - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -namespace Services.CleverBotApi -{ - public enum ChatterBotType - { - CLEVERBOT, - JABBERWACKY, - PANDORABOTS - } -} \ No newline at end of file diff --git a/src/NadekoBot/Services/CleverBotApi/Cleverbot.cs b/src/NadekoBot/Services/CleverBotApi/Cleverbot.cs deleted file mode 100644 index 45109863..00000000 --- a/src/NadekoBot/Services/CleverBotApi/Cleverbot.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System.Collections.Generic; -using System.Net; -using System.Threading.Tasks; - -/* - ChatterBotAPI - Copyright (C) 2011 pierredavidbelanger@gmail.com - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -namespace Services.CleverBotApi -{ - public class Cleverbot : ChatterBot - { - private readonly int endIndex; - private readonly string baseUrl; - private readonly string url; - - public Cleverbot(string baseUrl, string url, int endIndex) - { - this.baseUrl = baseUrl; - this.url = url; - this.endIndex = endIndex; - } - - public ChatterBotSession CreateSession() - { - return new CleverbotSession(baseUrl, url, endIndex); - } - } - - public class CleverbotSession : ChatterBotSession - { - private readonly int endIndex; - private readonly string url; - private readonly IDictionary vars; - private readonly CookieCollection cookies; - - public CleverbotSession(string baseUrl, string url, int endIndex) - { - this.url = url; - this.endIndex = endIndex; - vars = new Dictionary(); - //vars["start"] = "y"; - vars["stimulus"] = ""; - vars["islearning"] = "1"; - vars["icognoid"] = "wsf"; - //vars["fno"] = "0"; - //vars["sub"] = "Say"; - //vars["cleanslate"] = "false"; - cookies = Utils.GetCookies(baseUrl); - } - - public async Task Think(ChatterBotThought thought) - { - vars["stimulus"] = thought.Text; - - var formData = Utils.ParametersToWWWFormURLEncoded(vars); - var formDataToDigest = formData.Substring(9, endIndex); - var formDataDigest = Utils.MD5(formDataToDigest); - vars["icognocheck"] = formDataDigest; - - var response = await Utils.Post(url, vars, cookies).ConfigureAwait(false); - - var responseValues = response.Split('\r'); - - //vars[""] = Utils.StringAtIndex(responseValues, 0); ?? - vars["sessionid"] = Utils.StringAtIndex(responseValues, 1); - vars["logurl"] = Utils.StringAtIndex(responseValues, 2); - vars["vText8"] = Utils.StringAtIndex(responseValues, 3); - vars["vText7"] = Utils.StringAtIndex(responseValues, 4); - vars["vText6"] = Utils.StringAtIndex(responseValues, 5); - vars["vText5"] = Utils.StringAtIndex(responseValues, 6); - vars["vText4"] = Utils.StringAtIndex(responseValues, 7); - vars["vText3"] = Utils.StringAtIndex(responseValues, 8); - vars["vText2"] = Utils.StringAtIndex(responseValues, 9); - vars["prevref"] = Utils.StringAtIndex(responseValues, 10); - //vars[""] = Utils.StringAtIndex(responseValues, 11); ?? -// vars["emotionalhistory"] = Utils.StringAtIndex(responseValues, 12); -// vars["ttsLocMP3"] = Utils.StringAtIndex(responseValues, 13); -// vars["ttsLocTXT"] = Utils.StringAtIndex(responseValues, 14); -// vars["ttsLocTXT3"] = Utils.StringAtIndex(responseValues, 15); -// vars["ttsText"] = Utils.StringAtIndex(responseValues, 16); -// vars["lineRef"] = Utils.StringAtIndex(responseValues, 17); -// vars["lineURL"] = Utils.StringAtIndex(responseValues, 18); -// vars["linePOST"] = Utils.StringAtIndex(responseValues, 19); -// vars["lineChoices"] = Utils.StringAtIndex(responseValues, 20); -// vars["lineChoicesAbbrev"] = Utils.StringAtIndex(responseValues, 21); -// vars["typingData"] = Utils.StringAtIndex(responseValues, 22); -// vars["divert"] = Utils.StringAtIndex(responseValues, 23); - - var responseThought = new ChatterBotThought(); - - responseThought.Text = Utils.StringAtIndex(responseValues, 0); - - return responseThought; - } - - public async Task Think(string text) - { - return (await Think(new ChatterBotThought {Text = text}).ConfigureAwait(false)).Text; - } - } -} \ No newline at end of file diff --git a/src/NadekoBot/Services/CleverBotApi/Pandorabots.cs b/src/NadekoBot/Services/CleverBotApi/Pandorabots.cs deleted file mode 100644 index 0d1d8246..00000000 --- a/src/NadekoBot/Services/CleverBotApi/Pandorabots.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -/* - ChatterBotAPI - Copyright (C) 2011 pierredavidbelanger@gmail.com - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -namespace Services.CleverBotApi -{ - public class Pandorabots : ChatterBot - { - private readonly string botid; - - public Pandorabots(string botid) - { - this.botid = botid; - } - - public ChatterBotSession CreateSession() - { - return new PandorabotsSession(botid); - } - } - - public class PandorabotsSession : ChatterBotSession - { - private readonly IDictionary vars; - - public PandorabotsSession(string botid) - { - vars = new Dictionary(); - vars["botid"] = botid; - vars["custid"] = Guid.NewGuid().ToString(); - } - - public async Task Think(ChatterBotThought thought) - { - vars["input"] = thought.Text; - - var response = await Utils.Post("http://www.pandorabots.com/pandora/talk-xml", vars, null).ConfigureAwait(false); - - var responseThought = new ChatterBotThought(); - responseThought.Text = Utils.XPathSearch(response, "//result/that/text()"); - - return responseThought; - } - - public async Task Think(string text) - { - return (await Think(new ChatterBotThought {Text = text}).ConfigureAwait(false)).Text; - } - } -} \ No newline at end of file diff --git a/src/NadekoBot/Services/CleverBotApi/Utils.cs b/src/NadekoBot/Services/CleverBotApi/Utils.cs deleted file mode 100644 index 8954afc6..00000000 --- a/src/NadekoBot/Services/CleverBotApi/Utils.cs +++ /dev/null @@ -1,148 +0,0 @@ -using NadekoBot.Extensions; -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using System.Xml.XPath; - -/* - ChatterBotAPI - Copyright (C) 2011 pierredavidbelanger@gmail.com - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -namespace Services.CleverBotApi -{ - public static class Utils - { - public static string ParametersToWWWFormURLEncoded(IDictionary parameters) - { - string wwwFormUrlEncoded = null; - foreach (var parameterKey in parameters.Keys) - { - var parameterValue = parameters[parameterKey]; - var parameter = string.Format("{0}={1}", System.Uri.EscapeDataString(parameterKey), System.Uri.EscapeDataString(parameterValue)); - if (wwwFormUrlEncoded == null) - { - wwwFormUrlEncoded = parameter; - } - else - { - wwwFormUrlEncoded = string.Format("{0}&{1}", wwwFormUrlEncoded, parameter); - } - } - return wwwFormUrlEncoded; - } - - public static string MD5(string input) - { - // step 1, calculate MD5 hash from input - var md5 = System.Security.Cryptography.MD5.Create(); - var inputBytes = Encoding.ASCII.GetBytes(input); - var hash = md5.ComputeHash(inputBytes); - - // step 2, convert byte array to hex string - var sb = new StringBuilder(); - for (var i = 0; i < hash.Length; i++) - { - sb.Append(hash[i].ToString("X2")); - } - return sb.ToString(); - - } - - public static CookieCollection GetCookies(string url) - { - CookieContainer container = new CookieContainer(); - - HttpResponseMessage res; - using (var handler = new HttpClientHandler() { CookieContainer = container }) - using (var http = new HttpClient(handler)) - { - http.AddFakeHeaders(); - http.DefaultRequestHeaders.Add("ContentType", "text/html"); - res = http.GetAsync(url).GetAwaiter().GetResult(); - } - var response = res.Content.ReadAsStringAsync().GetAwaiter().GetResult(); - - return container.GetCookies(res.RequestMessage.RequestUri); - } - - public static async Task Post(string url, IDictionary parameters, CookieCollection cookies) - { - var postData = ParametersToWWWFormURLEncoded(parameters); - var postDataBytes = Encoding.ASCII.GetBytes(postData); - - var request = (HttpWebRequest)WebRequest.Create(url); - - if (cookies != null) - { - var container = new CookieContainer(); - container.Add(new Uri(url), cookies); - request.CookieContainer = container; - } - - - request.Method = "POST"; - request.ContentType = "application/x-www-form-urlencoded"; - - using (var outputStream = await request.GetRequestStreamAsync()) - { - outputStream.Write(postDataBytes, 0, postDataBytes.Length); - outputStream.Flush(); - - var response = (HttpWebResponse)await request.GetResponseAsync(); - using (var responseStreamReader = new StreamReader(response.GetResponseStream())) - { - return responseStreamReader.ReadToEnd().Trim(); - } - } - - //HttpClientHandler handler; - //var uri = new Uri(url); - //if (cookies == null) - // handler = new HttpClientHandler(); - //else - //{ - // var cookieContainer = new CookieContainer(); - // cookieContainer.Add(uri, cookies); - // handler = new HttpClientHandler() { CookieContainer = cookieContainer }; - //} - //using (handler) - //using (var http = new HttpClient(handler)) - //{ - // var res = await http.PostAsync(url, new FormUrlEncodedContent(parameters)).ConfigureAwait(false); - // return await res.Content.ReadAsStringAsync().ConfigureAwait(false); - //} - } - - - public static string XPathSearch(string input, string expression) - { - var document = new XPathDocument(new MemoryStream(Encoding.ASCII.GetBytes(input))); - var navigator = document.CreateNavigator(); - return navigator.SelectSingleNode(expression).Value.Trim(); - } - - public static string StringAtIndex(string[] strings, int index) - { - if (index >= strings.Length) return ""; - return strings[index]; - } - } -} \ No newline at end of file diff --git a/src/NadekoBot/Services/CommandHandler.cs b/src/NadekoBot/Services/CommandHandler.cs index 5c4fa19c..8cd840e0 100644 --- a/src/NadekoBot/Services/CommandHandler.cs +++ b/src/NadekoBot/Services/CommandHandler.cs @@ -16,9 +16,7 @@ using NadekoBot.Modules.CustomReactions; using NadekoBot.Modules.Games; using System.Collections.Concurrent; using System.Threading; -using Microsoft.EntityFrameworkCore; using NadekoBot.DataStructures; -using Services.CleverBotApi; namespace NadekoBot.Services { From d07ec11fa371d327b1b1ca3a07d561a34bb7ae10 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Tue, 4 Apr 2017 15:51:19 +0200 Subject: [PATCH 32/98] Fixed .clparew usage string --- src/NadekoBot/Resources/CommandStrings.Designer.cs | 2 +- src/NadekoBot/Resources/CommandStrings.resx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index c8f3ed92..d021e161 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -1725,7 +1725,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to `{0}claimpatreonrewards`. + /// Looks up a localized string similar to `{0}clparew`. /// public static string claimpatreonrewards_usage { get { diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 1d5479ab..1a943af1 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3337,7 +3337,7 @@ Claim patreon rewards. If you're subscribed to bot owner's patreon you can user this command to claim your rewards - assuming bot owner did setup has their patreon key. - `{0}claimpatreonrewards` + `{0}clparew` ping From 349f76af851882048f4e971a302afd8da1b69236 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Tue, 4 Apr 2017 19:48:33 +0200 Subject: [PATCH 33/98] Fixed permission listing when user(s) in permissions left the server --- src/NadekoBot/Modules/Permissions/PermissionExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NadekoBot/Modules/Permissions/PermissionExtensions.cs b/src/NadekoBot/Modules/Permissions/PermissionExtensions.cs index db0fdfd6..f48dcd16 100644 --- a/src/NadekoBot/Modules/Permissions/PermissionExtensions.cs +++ b/src/NadekoBot/Modules/Permissions/PermissionExtensions.cs @@ -106,7 +106,7 @@ namespace NadekoBot.Modules.Permissions switch (perm.PrimaryTarget) { case PrimaryPermissionType.User: - com += guild?.GetUser(perm.PrimaryTargetId).ToString() ?? $"<@{perm.PrimaryTargetId}>"; + com += guild?.GetUser(perm.PrimaryTargetId)?.ToString() ?? $"<@{perm.PrimaryTargetId}>"; break; case PrimaryPermissionType.Channel: com += $"<#{perm.PrimaryTargetId}>"; From e3463e1e7066ad1c40ce2ed8e9dc0eb32d355a39 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:05 +0200 Subject: [PATCH 34/98] Update ResponseStrings.zh-CN.resx (POEditor.com) --- .../Resources/ResponseStrings.zh-CN.resx | 127 +++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.zh-CN.resx b/src/NadekoBot/Resources/ResponseStrings.zh-CN.resx index e756cf57..ae22319e 100644 --- a/src/NadekoBot/Resources/ResponseStrings.zh-CN.resx +++ b/src/NadekoBot/Resources/ResponseStrings.zh-CN.resx @@ -759,7 +759,8 @@ 软禁(踢出) - PLURAL + PLURAL +Fuzzy {0}将忽略此通道。 @@ -2383,5 +2384,129 @@ Fuzzy 竞争比赛游戏时间。 + + + + + + + + + PLURAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 8a860fe978766543bdba82be14900585fc4e51a2 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:07 +0200 Subject: [PATCH 35/98] Update ResponseStrings.zh-TW.resx (POEditor.com) --- .../Resources/ResponseStrings.zh-TW.resx | 134 +++++++++++++++++- 1 file changed, 129 insertions(+), 5 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.zh-TW.resx b/src/NadekoBot/Resources/ResponseStrings.zh-TW.resx index 7f3ca400..3af06d17 100644 --- a/src/NadekoBot/Resources/ResponseStrings.zh-TW.resx +++ b/src/NadekoBot/Resources/ResponseStrings.zh-TW.resx @@ -317,7 +317,7 @@ 原因:{1} - 用戶已封鎖 + 成員已封鎖 PLURAL @@ -530,7 +530,7 @@ {0} 已從 {1} 移動至 {2} - #{0} 中删除了讯息 + #{0} 中删除了訊息 #{0} 中更新了訊息 @@ -904,7 +904,7 @@ 花幣大放送開始了! - 送了 {1} 給 {0} + 送了 {0} 給 {1} X has gifted 15 flowers to Y @@ -933,7 +933,7 @@ 卡堆中没有更多的牌。 - 得獎用戶 + 得獎成員 您骰了 {0}。 @@ -1473,7 +1473,7 @@ Paypal <{1}> 我將在此頻道輸出播放、暫停、結束和移除歌曲的訊息。 - 跳至 ‘{0}:{1}’ + 跳至 `{0}:{1}` 隨機播放 @@ -2284,5 +2284,129 @@ Paypal <{1}> 競技時數 + + 頻道 + + + 指令 + + + 踢除 + PLURAL + + + 群管 + + + 第 {0} 頁 + + + 理由 + + + 已新增新的啟動執行命令。 + + + 啟動執行命令已移除。 + + + 找不到啟動執行命令。 + + + 伺服器 + + + 此頁沒有啟動執行命令。 + + + 已清除所有啟動執行命令。 + + + 成員 {0} 已解除封鎖。 + + + 找不到成員。 + + + 已警告成員 {0} 。 + + + 成員 {0} 因警告多次故以 {0} 作為懲罰。 + + + 在 {0} 伺服器上警告 + + + 於 {0} {1},由 {2} + + + 已清除成員 {0} 上的所有警告。 + + + 此頁沒有警告。 + + + {0} 的警告紀錄 + + + 沒有設定懲處罰則。 + + + 由 {0} 清除 + + + 警告懲處清單 + + + 擁有 {0} 支警告不再觸發懲處。 + + + 我將會用 {0} 懲處擁有 {0} 支警告的成員。 + + + Slowmode 將不再套用於 {0} 身分組。 + + + Slowmode 將套用於 {0} 身分組。 + + + Slowmode 將不再套用於 {0} 成員。 + + + Slowmode 將套用於 {0} 成員。 + + + 因下列因素而無法領獎: + + + 您一個月只能領一次獎勵,除非您的贊助金額有提升。 + + + 獎勵已發送 + + + 您的Discord帳號可能未與Patreon帳戶連結。若您不確定,或不知道如何連結的話,請至您的[Patreon帳戶設定](https://patreon.com/settings/account)並點選'連節至Discord'按鈕。 + + + 尚未連接Discord帳號 + + + 您必須要與Patreon連結您的Discord帳戶才符合領獎資格。您可以使用 {0} 指令來取得連結。 + + + 無法支援 + + + 贊助完畢後需要等待數小時等資訊入系統,還請稍後再嘗試。 + + + 請稍等 + + + 您因贊助了此專案而獲得了{0}! + + + 獎勵可於每月5日之後領取。 + \ No newline at end of file From 494aae95a5dfe8af138d8a5aa1296e60a99cba74 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:10 +0200 Subject: [PATCH 36/98] Update ResponseStrings.nl-NL.resx (POEditor.com) --- .../Resources/ResponseStrings.nl-NL.resx | 156 +++++++++++++++--- 1 file changed, 134 insertions(+), 22 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.nl-NL.resx b/src/NadekoBot/Resources/ResponseStrings.nl-NL.resx index 3f7ad541..2662c00a 100644 --- a/src/NadekoBot/Resources/ResponseStrings.nl-NL.resx +++ b/src/NadekoBot/Resources/ResponseStrings.nl-NL.resx @@ -140,7 +140,6 @@ De aanvraag van @{0} voor een oorlog tegen {1} is niet meer geldig. - Fuzzy Vijand @@ -153,11 +152,9 @@ Ongeldig oorlogsformaat. - Fuzzy - Lijst van voorlopende oorlogen. - Fuzzy + Lijst van actieve oorlogen Niet veroverd. @@ -169,8 +166,7 @@ @{0} Je doet niet mee aan die oorlog, of die basis is al vernietigd. - Geen voorlopende oorlogen. - Fuzzy + Geen actieve oorlogen Grootte. @@ -209,8 +205,7 @@ Nieuwe Speciale Reacties - Geen speciale reacties gevonden. - Fuzzy + Geen aangepaste reacties gevonden. Geen speciale reacties gevonden met dat ID. @@ -476,7 +471,6 @@ Reden: {1} Lijst van talen {0} - Fuzzy Je server's landinstelling is nu {0} - {1} @@ -533,12 +527,10 @@ Reden: {1} {0} verplaats van {1} naar {2} - Bericht in #{0} verwijdert - Fuzzy + Bericht in #{0} verwijderd Bericht in #{0} bijgewerkt - Fuzzy gemute @@ -749,7 +741,8 @@ Reden: {1} soft-verbannen (gekickt) - PLURAL + PLURAL +Fuzzy {0} zal dit kanaal negeren. @@ -1395,7 +1388,6 @@ Vergeet niet je discord naam en id in het bericht te zetten. Nu aan het spelen - Fuzzy Geen actieve muziek speler. @@ -1731,12 +1723,10 @@ Vergeet niet je discord naam en id in het bericht te zetten. Voorbeeld - Mislukt in het vinden van die chinese tekenfilm - Fuzzy + Kon die animu niet vinden. - Mislukt in het vinden van die - Fuzzy + Kon die mango niet vinden. Genres @@ -2012,8 +2002,7 @@ Vergeet niet je discord naam en id in het bericht te zetten. Index buiten bereik. - Hier is de lijst met gebruikers in die rollen: - Fuzzy + Lijst van gebruikers met rol {0} Om misbruik te voorkomen ben je niet gemachtigd om dit commando te gebruiken op rollen met veel gebruikers. @@ -2102,8 +2091,7 @@ Eigenaar ID: {2} Citaat toegevoegd - Een willekeurig citaat verwijderd - Fuzzy + Citaat #{0} verwijderd. Regio @@ -2293,5 +2281,129 @@ Eigenaar ID: {2} Competitieve speeltijd + + Kanaal + + + Tekst commando + + + Geschopt + PLURAL + + + Toezichthouder + + + Pagina {0} + + + Reden + + + Nieuw startup commando toegevoegd. + + + Startup commando succesvol toegevoegd. + + + Startup commando niet gevonden. + + + Server + + + Geen startup commando's op deze pagina. + + + Verwijder alle startup commando's. + + + Gebruiker {0} is unbanned. + + + Gebruiker niet gevonden. + + + Gebruiker {0} is gewaarschuwd. + + + Gebruiker {0} is gewaarschuwd en {1) straf is uitgevoerd. + + + Gewaarschuwd op {0} server + + + op {0} tussen {1} bij (2} + + + Alle waarschuwingen zijn verwijdert van {0}. + + + Geen waarschuwingen op deze pagina. + + + Waarschuwings logboek van {0} + + + Geen straffen geconfigureerd. + + + Verwijdert door {0} + + + waarschuwing straffen lijst + + + Bij {0} waarschuwingen treed niet langer meer een straf. + + + Ik pas {0} straf toe aan de gebruikers met {1} waarschuwingen. + + + Slowmotion modus word genegeerd voor {0} rol. + + + Slowmotion wordt niet langer genegeerd door {0} rol. + + + Slowmotion modus wordt genegeerd door gebruiker {0}. + + + Slowmotion modus wordt niet langer genegeerd door genegeerde gebruiker {0}. + + + Mislukt om beloningen te claimen door een van de volgende redenen: + + + Misschien heb je al je beloningen gekregen deze maand. Je krijgt beloningen maar een keer per maand tenzij je je + + + Al beloond + + + Jouw discord account is nog niet verbonden met Patreon. Als je onzeker bent wat dit betekend, of niet weet hoe je dit moet doen - ga dan naar [Patreon account settings page](https://patreon.com/settings/account) en click dan op 'Verbind met discord'. + + + Discord account nog niet verbonden + + + Om in aanmerking te komen voor de beloning, moet je eerst een donatie doen voor het project bij patreon. Je kunt (0} commando gebruiken om de link te krijgen. + + + Niet ondersteund + + + Je moet een aantal uren wachten na het plaatsen van je donatie, als je het nog niet hebt gedaan, probeer later dan opnieuw. + + + Wacht nog even + + + Je ontvangt {0} Hartelijk bedankt voor het steunen van het project! + + + Beloningen kunnen worden geclaimd op of na elke 5de van de maand. + \ No newline at end of file From 91880e6ca28dfd984985bea2b712287c11b075f8 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:12 +0200 Subject: [PATCH 37/98] Update ResponseStrings.en-US.resx (POEditor.com) From 28753b6a22a614d47ed22e017533b25c66b9384e Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:15 +0200 Subject: [PATCH 38/98] Update ResponseStrings.fr-FR.resx (POEditor.com) --- .../Resources/ResponseStrings.fr-FR.resx | 133 +++++++++++++++++- 1 file changed, 129 insertions(+), 4 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.fr-FR.resx b/src/NadekoBot/Resources/ResponseStrings.fr-FR.resx index 3c3279ff..c2ad5917 100644 --- a/src/NadekoBot/Resources/ResponseStrings.fr-FR.resx +++ b/src/NadekoBot/Resources/ResponseStrings.fr-FR.resx @@ -748,7 +748,8 @@ Raison: {1} expulsés (kick) - PLURAL + PLURAL +Fuzzy {0} ignorera ce Salon. @@ -757,7 +758,7 @@ Raison: {1} {0} n'ignorera plus ce Salon. - Si un utilisateur poste {0} le même message à la suite, je le {1}. + Si un utilisateur poste {0} fois le même message à la suite, je le {1}. __SalonsIgnorés__: {2} @@ -1432,7 +1433,7 @@ La nouvelle valeur de {0} est {1} ! Aucune liste de lecture ne correspond a cet ID. - File d'attente de la liste complétée. + Liste de lecture ajoutée à la file d'attente. Liste de lecture sauvegardée @@ -2291,7 +2292,7 @@ ID du propriétaire: {2} {0} sera maintenant l'alias de {1}. - Liste des alias. + Liste des alias {0} n'a plus d'alias. @@ -2302,5 +2303,129 @@ ID du propriétaire: {2} Temps en jeu compétitif. + + Salon + + + Texte de la commande. + + + Expulsés + PLURAL + + + Modérateur + + + Page {0} + + + Raison + + + Nouvelle commande au démarrage ajoutée + + + Commande au démarrage retirée. + + + Commande au démarrage introuvable. + + + Serveur + + + Aucune commande de démarrage sur cette page. + + + Toutes les commandes au démarrage ont été retirées. + + + L'utilisateur {0} a été débanni. + + + Utilisateur introuvable. + + + L'utilisateur {0} a été averti. + + + L'utilisateur {0} a été averti et {1} punition a été appliquée. + + + Averti sur le serveur {0} + + + Le {0} à {1} par {2} + + + Toutes les avertissements ont étés effacés pour {0}. + + + Pas d'avertissement sur cette page. + + + Log d'avertissement pour {0} + + + Pas de punition définie. + + + Effacé par {0} + + + Liste des avertissements de punitions. + + + Avoir {0} avertissements ne déclenche plus de punition. + + + J'appliquerai seulement la punition {0} aux utilisateurs ayant {1} avertissements. + + + Le mode lent ignorera le rôle {0}. + + + Le mode lent n'ignorera plus le rôle {0}. + + + Le mode lent ignorera l'utilisateur {0}. + + + Le mode lent n'ignorera plus l'utilisateur {0}. + + + Échec de la réclamation des récompenses à cause d'une des raisons suivantes: + + + Vous avez peut-être déjà reçu votre récompense mensuelle. Vous ne pouvez recevoir qu'une récompense mensuelle sauf si vous augmentez votre engagement. + + + Déjà récompensé. + + + Votre compte Discord n'est peut-être pas connecté à Patreon. Si vous n'êtes pas sur de ce que ça veut dire, ou ne savez pas comment le connecter, vous devez aller à la [Page de configurations du compte Patreon](https://patreon.com/settings/account) et cliquer sur 'Connect to discord'. + + + Le compte Discord n'est pas connecté + + + Pour être éligible à la récompense, vous devez supporter le projet sur Patreon. Vous pouvez utiliser la commande {0} afin d'avoir le lien. + + + Ne supporte pas. + + + Vous devez attendre quelques heures après avoir fait votre engagement, si ce n'est pas le cas, réessayez plus tard. + + + Attendez quelque temps + + + Vous avez reçu {0}. Merci de supporter le projet! + + + Les récompenses peuvent être réclamés le 5e du mois ou après. + \ No newline at end of file From 6114df7e12793d01e7197a7bbd0b5fbece9dbfd6 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:18 +0200 Subject: [PATCH 39/98] Update ResponseStrings.de-DE.resx (POEditor.com) --- .../Resources/ResponseStrings.de-DE.resx | 129 +++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.de-DE.resx b/src/NadekoBot/Resources/ResponseStrings.de-DE.resx index c568448d..81cde44a 100644 --- a/src/NadekoBot/Resources/ResponseStrings.de-DE.resx +++ b/src/NadekoBot/Resources/ResponseStrings.de-DE.resx @@ -760,7 +760,8 @@ Grund: {1} soft-banned (gekickt) - PLURAL + PLURAL +Fuzzy {0} wird diesen Kanal ignorieren. @@ -2387,5 +2388,131 @@ ID des Besitzers: {2} Kompetetive Spielzeit + + Kanal + + + Befehls Text + + + Kicked + PLURAL + + + Moderator + + + Seite {0} + + + Grund + + + Neuer Startbefehl hinzugefügt. + Fuzzy + + + Startbefehl wurde erfolgreich entfernt. + + + Startbefehl konnte nicht gefunden werden + + + Server + + + Keine Startbefehle auf dieser Seite + + + Alle Startbefehle wurden entfernt. + + + Benutzer {0} wurde entbannt. + + + Benutzer nicht gefunden. + + + Benutzer {0} wurde gewarnt. + + + Benutzer {0} wurde gewarnt und Strafe {1} wurde ausgeführt. + + + Gewarnt auf dem Server {0} + + + Am {0} um {1} von {2} + + + Alle Warnungen wurden bereinigt für {0}. + + + Keine Warnungen auf dieser Seite. + + + + + + Keine Bestrafungen gesetzt. + + + Bereinigt bei {0} + + + Warnungs Straf Liste + + + {0} Warnungen werden nicht mehr eine Bestrafung auslösen. + + + Ich werde die Bestrafung {0} an Benutzern mit {1} Warnungen ausführen. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Keine Unterstützung + + + Sie müssen ein paar Stunden warten nachdem sie ihre Unterstützung zusagenl, falls Sie das nicht getan haben, versuchen Sie es später erneut. + Fuzzy + + + + + + + + + + \ No newline at end of file From 3b446508c7cf81e05f45afdfef660978733c396c Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:20 +0200 Subject: [PATCH 40/98] Update ResponseStrings.he-IL.resx (POEditor.com) --- .../Resources/ResponseStrings.he-IL.resx | 149 ++++++++++++++++-- 1 file changed, 137 insertions(+), 12 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.he-IL.resx b/src/NadekoBot/Resources/ResponseStrings.he-IL.resx index 7f42401e..cf49c09f 100644 --- a/src/NadekoBot/Resources/ResponseStrings.he-IL.resx +++ b/src/NadekoBot/Resources/ResponseStrings.he-IL.resx @@ -130,13 +130,13 @@ הבסיס #{0} **הושמד** במלחמה נגד {1} - + {0} **שיחרר** את בסיס #{0} במלחמה נגד {2} - + {0} תפס את בסיס #{1} במלחמה נגד {2} - + @{0} אתה כבר תפסת את בסיס #{1}. אינך יכול לתפוס אחד חדש @@ -214,7 +214,7 @@ תגובה - + נתוני תגובות מותאמות @@ -226,7 +226,7 @@ - + אוטוהנטאי הפסיק לא נמצאו תוצאות. @@ -299,10 +299,10 @@ את\ה התעלפת אז את\ה לא יכול לזוז. - + **נתינת תפקיד אוטומטי** כאשר משתמש מתווסף **הופסקה** כעת. - + **נתינת תפקיד אוטומטי** כאשר משתמש מתווסף **התחילה** כעת. קבצים מצורפים @@ -412,10 +412,10 @@ אני אפסיק להעביר את ההודאות הפרטיות מעכשיו. - + מחיקה אוטומטית של הודאות ברכה הופסקה. - + הודאות הודאה פרטית נוכחית: {0} @@ -442,10 +442,10 @@ - + הודאות ברכה בוטלו. - + הודאות ברכה הופעלו עבור ערוץ זה. אתה לא יכול להשתמש בפקודה זו על משתמשים עם תפקיד שווה או גבוהה ממך בדירוג. @@ -740,7 +740,8 @@ הסרה קלה (גורש) - PLURAL + PLURAL +Fuzzy {0} יתעלם מערוץ זה. @@ -2272,5 +2273,129 @@ + + + + + + + + + PLURAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From ce26d181607f97c94e80a9edf4f7b0b045a45241 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:23 +0200 Subject: [PATCH 41/98] Update ResponseStrings.it-IT.resx (POEditor.com) --- .../Resources/ResponseStrings.it-IT.resx | 687 +++++++++++------- 1 file changed, 420 insertions(+), 267 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.it-IT.resx b/src/NadekoBot/Resources/ResponseStrings.it-IT.resx index 5a922057..5247c7a6 100644 --- a/src/NadekoBot/Resources/ResponseStrings.it-IT.resx +++ b/src/NadekoBot/Resources/ResponseStrings.it-IT.resx @@ -118,28 +118,28 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Quella base è già rivendicata o distrutta. + Quella base è già stata rivendicata o distrutta. Quella base è già distrutta. - Quella base non è rivendicata. + Quella base non è stata rivendicata. - **DISTRUTTO** base #{0} in una guerra contro {1} + **DISTRUTTA** base #{0} in una guerra contro {1} - {0} ha **NON RIVENDICATO** base #{1} in una guerra contro {2} + {0} ha **NON RIVENDICATO** la base #{1} in una guerra contro {2} {0} ha rivendicato la base #{1} in una guerra contro {2} - @{0} Hai già rivendicato la base #{1} + @{0} Hai già rivendicato la base #{1}. Non puoi rivendicarne un'altra. - La rivendicazione di @{0} in una guerra contro {1} + La rivendicazione di @{0} in una guerra contro {1} è scaduta. Nemico @@ -157,13 +157,13 @@ Lista delle guerre in corso - non rivendicato + non rivendicata - Non stai partecipando a questa guerra + Non stai partecipando a quella guerra - @{0} Tu non stai partecipando in questa guerra, o questa base è già distrutta. + @{0} Non stai partecipando in quella guerra oppure quella base è già distrutta. Nessuna guerra in corso. @@ -178,22 +178,22 @@ Guerra contro {0} creata. - Guerra contro {0} finita. + Guerra contro {0} conclusa. Questa guerra non esiste. - Guerra contro {0} iniziata! + Guerra contro {0} avviata! - Tutte le reazioni personalizzate approvate. + Tutte le reazioni personalizzate sono state approvate. Reazione personalizzata cancellata - Permessi insufficienti. Richiede l'essere proprietario del bot per le reazioni personalizzate globali, e l'amministratore del server per le reazioni personalizzate. + Permessi insufficienti. Bisogna essere proprietario del Bot per personalizzare le reazioni globali e l'amministratore del server per le personalizzare le reazioni del server. Lista di tutte le reazioni personalizzate @@ -232,39 +232,39 @@ Nessun risultato trovato. - {0} è già svenuto. + {0} è già esausto. {0} ha già gli HP al massimo. - il tuo tipo è già {0} + Il tuo tipo è già {0} - Ha usato {0}{1} su {2}{3} per {4} danni. + ha usato {0}{1} su {2}{3} per {4} danni. Kwoth used punch:type_icon: on Sanity:type_icon: for 50 damage. - Non puoi attaccare senza ritorsione! + Non puoi attaccare di nuovo senza subire una rappresaglia! Fuzzy Non puoi attaccare te stesso. - {0} è svenuto! + {0} è esausto! - curato {0} con un {1} + ha curato {0} con un {1} - {0} ha {1} HP rimasto + {0} ha {1} HP rimasti. Non puoi usare {0}. Scrivi `{1}ml` per vedere la lista delle mosse che puoi usare. - Listamosse per tipo {0} + Lista delle mosse per il tipo {0} Non è efficace. @@ -273,22 +273,22 @@ Non hai abbastanza {0} - Hai resuscitato {0} con un {1} + ha resuscitato {0} con un {1} Hai resuscitato te stesso con un {0} - Il tuo tipo è stato cambiato in {0} per un {1} + Il tuo tipo è cambiato in {0} per un {1} - E' lievemente efficace. + È lievemente efficace. - E' superefficace! + È superefficace! - Hai usato troppe mosse in una volta, non puoi muoverti! + Hai usato troppe mosse di fila, quindi ora non puoi muoverti! Tipo di {0} è {1} @@ -300,20 +300,20 @@ Sei svenuto, non sei più in grado di muoverti! - **Auto assegna ruolo** sull'utente ora entrato è ora **disattivato** + **Assegna ruolo automaticamente** ai nuovi utenti è stato **disattivato**. - **Auto assegna ruolo** sull'utente ora entrato è ora **attivato** + **Assegna ruolo automaticamente** ai nuovi utenti è stato **attivato**. Allegato - Avatar Cambiato + Avatar cambiato Sei stato bannato dal {0} server. -Ragione: {1} +Motivo: {1} bannati @@ -323,13 +323,13 @@ Ragione: {1} Utente bannato - Nome bot cambiato in {0} + Nome del bot cambiato in {0} Stato del bot cambiato in {0} - L'eliminazione automatica dei messaggi di arrivederci è stata disabilitata. + la cancellazione automatica dei messaggi di arrivederci è stata disabilitata. I messaggi di arrivederci verranno eliminati dopo {0} secondi. @@ -347,13 +347,13 @@ Ragione: {1} Annunci di arrivederci disattivati. - Annunci di arrivederci attivati in questo canale + Annunci di arrivederci attivati in questo canale. Nome del canale cambiato - Vecchio Nome + Vecchio nome Argomento del canale cambiato @@ -377,7 +377,7 @@ Ragione: {1} Assordato con successo. - Server Eliminato {0} + Server eliminato {0} Fermata con successo l'eliminazione automatica dei comandi di invocazione. @@ -392,25 +392,25 @@ Ragione: {1} Canale vocale {0} eliminato. - MP da + Messaggio diretto da parte di - Aggiunto con successo un nuovo donatore. Totale ammontare donato da questo utente: {0} 👑 + Aggiunto con successo un nuovo donatore. Totale dell'ammonto donato dall'utente: {0} 👑 - Grazie alle persone nella lista qui sotto per aver fatto avverare questo progetto! + Grazie alle persone nella lista qui sotto per aver fatto di questo progetto una realtà! - Inoltrerò MP a tutti i proprietari. + Contatterò in privato tutti i proprietari. - Inoltrerò MP solo al primo proprietario. + Contatterò in privato solo il primo proprietario. - Inoltrerò MP da ora in poi. + Inoltrerò messaggi diretti d'ora in avanti. - Fermerò l'inoltrare degli MP da ora in poi. + Smetterò di inoltrare messaggi diretti d'ora in avanti. L'eliminazione automatica dei messaggi di benvenuto è stata disabilitata @@ -419,43 +419,43 @@ Ragione: {1} I messaggi di benvenuto verranno eliminati dopo {0} secondi. - Attuali MP di benvenuto ricevuti: {0} + Messaggi diretti di benvenuto ricevuti finora: {0} - Abilità MP di benvenuto scrivendoli {0} + Per abilitare i messaggi diretti di benvenuto scrivi {0} - Nuovo MP di bevenuto impostato. + Nuovo messaggio diretto di benvenuto impostato. - MP annunci di bevenenuto disattivato. + Messaggi diretti di benvenuto disabilitati. - MP annunci di bevenuto attivati. + Messaggi diretti di benvenuto abilitati. - + Messaggio di benvenuto attuale: {0} - + Per abilitare i messaggi di benvenuto scrivi {0} Nuovo messaggio di benvenuto impostato. - Annunci di bevenuto disabilitati + Messaggi di benvenuto disabilitati. - Annunci di benvenuto abilitatati in questo canale + Messaggi di benvenuto abilitatati in questo canale. - Non puoi usare questo comando su utenti con un ruolo più alto o uguale al tuo nella gerarchia dei ruoli. + Non puoi usare questo comando su utenti con un ruolo superiore o pari al tuo. Immagine caricata dopo {0} secondi! - + Formato di input invalido. Parametri Invalidi @@ -471,28 +471,28 @@ Ragione: {1} Utente cacciato - Lista dei linguaggi + Lista delle lingue - + La lingua del tuo server è ora {0} - {1} - + La lingua di base del bot è ora {0} - {1} - il linguaggio dei Bot è impostato a {0} - {1} + La lingua del Bot è impostata a {0} - {1} - + Impostazione della lingua del server fallita. Riguarda la guida di questo comando. - Il linguaggio di questo server è impostato a {0} - {1} + La lingua di questo server è impostata a {0} - {1} {0} ha lasciato {1} - Hai lasciato il server {0} + Ha lasciato il server {0} Inserire {0} evento in questo canale. @@ -504,7 +504,7 @@ Fuzzy Fuzzy - Entrata disattivata + Registrazione disattivata Fuzzy @@ -512,42 +512,45 @@ Fuzzy Fuzzy - + La registrazione ignorerá {0} + Fuzzy - + La registrazione non ignorerá {0} + Fuzzy - + Fermata la registrazione dell'evento {0} + Fuzzy {0} ha chiesto una menzione nei seguenti ruoli - Messaggio da {0} `[Proprietario Bot]`: + Messaggio da {0} `[Proprietario del bot]`: Messaggio inviato. - {0} spostato in {1} da {2} + {0} spostato da {1} a {2} Messaggio eliminato in #{0} - + Messaggio aggiornato in #{0} - Gli utenti sono stati mutati + Mutati PLURAL (users have been muted) - Utente mutato + Mutato singular "User muted." - Probabilmente non ho i permessi necessari per questo + Probabilmente non ho i permessi necessari per farlo. Nuovo ruolo di muto impostato. @@ -568,10 +571,10 @@ Fuzzy Soprannome cambiato - Non riesco a trovare questo server + Non riesco a trovare quel server - + Non è stato trovato nessun frammento con quel ID. Messaggio precedente @@ -583,10 +586,10 @@ Fuzzy Discussione precedente - Errore. Probabilmente non ho i permessi sufficienti. + Errore. Probabilmente non dispongo dei permessi necessari. - I permessi per questo server sono resettati + I permessi di questo server sono stati reimpostati. Protezioni attive @@ -598,7 +601,7 @@ Fuzzy {0} Attivato - Errore. Hai bisogno dei permessi di gestione dei ruoli + Errore. Ho bisogno dei permessi di gestione dei ruoli Nessuna protezione attiva. @@ -607,55 +610,57 @@ Fuzzy Gli utenti in ingresso devono essere tra {0} e {1}. - Se {0} o più utenti entrano entro {1} secondi, io li {0} loro. + Se {0} o più utenti entrano entro {1} secondi, li {0}. Il tempo deve essere tra {0} e {1} secondi. - Rimossi con successo tutti i ruoli dall'utente {0} + L'utente {0} è stato sollevato da tutti i suoi ruoli. - Fallito a rimuovere i ruoli. Non ho abbastanza permessi. + Impossibile rimuovere i ruoli. Non dispongo dei permessi necessari. - il colore di {0} è stato cambiato. + il colore del ruolo {0} è stato cambiato. - Questo ruolo non esiste. + Quel ruolo non esiste. - I parametri specificati sono invalidi + I parametri specificati sono invalidi. Si è verificato un errore dovuto a un colore invalido o a permessi insufficienti. - Rimosso con successo ruolo {0} dall'utente {1} + L'utente {1} è stato sollevato dal ruolo di {0} - Fallito a rimuovere ruolo. Non ho abbastanza permessi. + Impossibile rimuovere il ruolo. Non dispongo dei permessi necessari. - Ruolo rinominato + Ruolo rinominato. - Rinomina del ruolo fallita. Non ho abbastanza permessi. + Impossibile rinominare il ruolo. Non dispongo dei permessi necessari. - Non puoi modificare i ruoli più alti del tuo + Non puoi modificare i ruoli più alti del tuo. Rimosso il messaggio di gioco: {0} + Fuzzy - Ruolo {0} è stato aggiunto alla lista. + Il ruolo {0} è stato aggiunto alla lista. - {0} non trovato.Ripulito. + {0} non trovato. Pulizia avvenuta. + Fuzzy - il ruolo {0} è già nella lista + il ruolo {0} è già nella lista. Aggiunto. @@ -667,7 +672,7 @@ Fuzzy Stato di gioco rotativo attivato. - Qui c'è una lista delle condizioni di ruolo rotative: + Ecco una lista delle condizioni di ruolo rotative: {0} Fuzzy @@ -676,10 +681,11 @@ Fuzzy Fuzzy - Tu hai già {0} ruolo + Sei già un {0}. - Tu hai già {0} esclusivi ruoli auto-assegnati. + Hai già {0} esclusivi ruoli auto-assegnati. + Fuzzy I ruoli auto-assegnati sono ora riservati! @@ -691,31 +697,31 @@ Fuzzy Quel ruolo non è auto-assegnabile. - Tu non hai {0} ruolo. + Non sei un {0}. I ruoli auto-assegnati ora non sono più riservati! - Io non sono in grado di assegnarti questo ruolo. `Io non posso assegnare ruoli al proprietario o ad altri ruoli più alti del mio nella gerarchia dei ruoli.` + Non sono in grado di assegnarti quel ruolo. `Non posso assegnare ruoli al proprietario o ad altri utenti con un ruolo superiore al mio.` {0} è stato rimosso dalla lista dei ruoli auto-assegnabili. - Tu non hai più {0} ruolo. + Se non più un {0}. - Tu ora hai {0} ruolo. + Ora sei un {0}. - Aggiunto con successo ruolo {0} all'utente {1} + All'utente {1} è stato assegnato con successo il ruolo di {0}. - Fallito ad aggiungere il ruolo. Non ho i permessi sufficienti. + Impossibile assegnare ruolo. Non dispongo dei permessi necessari. - Nuova immagine impostata! + Nuovo avatar impostato! Nuovo nome del canale impostato. @@ -730,10 +736,12 @@ Fuzzy Nuova discussione del canale impostata. - + Frammento {0} ricollegato. + Fuzzy - + Frammento {0} si sta ricollegando. + Fuzzy Spegnimento @@ -743,13 +751,16 @@ Fuzzy Modalità lenta disattivata + Fuzzy Modalità lenta attivata + Fuzzy Ammonizione (Espulso) - PLURAL + PLURAL +Fuzzy {0} ignorerà questo canale. @@ -808,7 +819,7 @@ __Canaliignorati__: {2} Ruolo utente rimosso - {0} è ora {1} + {0} ora é {1} {0} è stato **smutato** dal canale di testo e vocale. @@ -841,13 +852,13 @@ __Canaliignorati__: {2} Voce + testo abilitati. - + Non ho i permessi **gestire ruoli* e/o **gestire canali*, quindi non posso utilizzare `voce+testo` sul server {0}. - + Stai attivando/disattivando questa opzione e **Io non ho i permessi di AMMINISTRATORE**. Questo potrebbe causare dei problemi, e dopo tu dovrai ripulire il canale di testo. - + Richiedo dei permessi **gestire ruoli** e **gestire canali** per abilitare per questa funzione. (preferibilmente il permesso Amministratore) Utente {0} dalla chat di testo @@ -859,7 +870,8 @@ __Canaliignorati__: {2} Utente {0} dalla chat vocale - + Sei statto cacciato da {0} server. +Motivo : {1} Utente sbannato @@ -896,7 +908,7 @@ __Canaliignorati__: {2} Indovinato! Hai vinto {0} - + Numero specificato non valido. Puoi lanciare da 1 a {0} monete. Aggiungi {0} a questo messaggio per ottenere {1} @@ -905,7 +917,8 @@ __Canaliignorati__: {2} Quest'evento è attivo per le prossime {0} ore - + Evento reazioni iniziato! + Fuzzy ha regalato {0} a {1} @@ -919,7 +932,7 @@ __Canaliignorati__: {2} Testa - + Classifica @@ -937,7 +950,7 @@ __Canaliignorati__: {2} Non ci sono più carte nel mazzo. - + Utente sorteggiato Hai rollato {0} @@ -965,10 +978,10 @@ __Canaliignorati__: {2} Dura {1} secondi. Non dirlo a nessuno. Shhh. - + L'evento SneakyGame è finito. {0} utenti hanno ricevuto la loro ricompensa. - + L'evento SneakyGameStatus è iniziato Croce @@ -978,28 +991,28 @@ Dura {1} secondi. Non dirlo a nessuno. Shhh. Fuzzy - + non sono stata in grado di prendere {0} da{1} perché l'utente non aveva abbastanza {2}! - + Torna al sommario Solo il proprietario del bot. - + Richiede il permesso del canale {0}. Puoi supportare il progetto sul patreon: <{0}> o paypal: <{0}> - + Comandi e alias - + Lista dei comandi rigenerata. - + Scrivi `{0}h NomeDelComando` per consultare la guida per il comando specificato. Ad esempio: `{0}h >8ball` Non riesco a trovare questo comando. Perfavore verifica che questo comando esiste prima di riprovare. @@ -1026,19 +1039,19 @@ Non dimenticarti di firmare con il tuo nome o id di discord. Lista dei moduli - + Scrivi `{0}cmds NomeModulo` per vedere la lista di tutti i comandi in quel modulo. Ad esempio: `{0}cmds giochi` Modulo inesistente. - + Richiede il permesso {0} del server. Tabella dei contenuti - + Uso Autohentai avviato. Ogni {0} secondi verrà postato qualcosa coi seguenti tag: @@ -1048,7 +1061,7 @@ Non dimenticarti di firmare con il tuo nome o id di discord. Tag - + Gara degli animali Impossibile iniziare perché non ci sono abbastanza partecipanti. @@ -1063,8 +1076,7 @@ Non dimenticarti di firmare con il tuo nome o id di discord. {0} è entrato come {1} e ha scommesso {2}! - Scrivi {0}eg per entrare nella gara. - Fuzzy + Scrivi {0}jr per partecipare alla gara. Inizia tra 20 secondi o quando la stanza è piena. @@ -1076,11 +1088,10 @@ Non dimenticarti di firmare con il tuo nome o id di discord. {0} come {1} Ha vinto la gara! - {0} come {2} Ha vinto la gara e {2}! + {0} come {1} Ha vinto la gara e {2}! Numero specificato invalido. Puoi tirare {0}-{1} dadi alla volta. - Fuzzy Ha rollato {0} @@ -1088,9 +1099,8 @@ Non dimenticarti di firmare con il tuo nome o id di discord. Fuzzy - Dado rollato: {0} - Dice Rolled: 5 -Fuzzy + Dadi tirati: {0} + Dice Rolled: 5 Fallito a iniziare la gara. Un'altra gara è probabilmente in corso. @@ -1123,7 +1133,7 @@ Fuzzy Classifica delle waifu - + La tua affinità è già stabilita a quella waifu oppure stai cercando di rimuovere la tua affinità mentre non ne hai una. ha cambiato la sua affinità da {0} a {1}. @@ -1244,17 +1254,17 @@ il nuovo valore di {0} è {1}! Cleverbot è stato abilitato in questo server. - + La generazione di valuta è stata disabilitata in questo canale. - + La generazione di valuta è stata abilitata in questo canale. - + {0} un {1} casuale è apparso! plural - + Un {0} è apparso! Impossibile caricare una domanda. @@ -1270,10 +1280,9 @@ il nuovo valore di {0} è {1}! Impossibile iniziare il gioco dell'impiccato. - Fuzzy - + Lista dei tipi di parole dell' "{0}impiccato": Classifica @@ -1332,7 +1341,9 @@ il nuovo valore di {0} è {1}! {0} ha vinto! - + Tris + The mean of ''matched three'' is that someone won at tic tac toe? +Fuzzy Nessuna mossa rimanente! @@ -1341,13 +1352,13 @@ il nuovo valore di {0} è {1}! Tempo scaduto! - + Tocca a {0} {0} vs {1} - + Cercando di mettere in coda {0} canzoni... Autoplay disabilitato. @@ -1359,19 +1370,20 @@ il nuovo valore di {0} è {1}! Volume di default impostato a {0}% - + Coda della directory completata. + Fuzzy - + gioco corretto Canzone finita - + Gioco corretto disabilitato. - + Gioco corretto abilitato. Dalla posizione @@ -1383,19 +1395,19 @@ il nuovo valore di {0} è {1}! Input non valido - + Il tempo massimo di gioco ora non ha più un limite. - + Il tempo massimo di gioco è stato impostato a {0} secondi. - + La coda massima della musica è stata impostata a illimitata - + La coda massima della musica è stata impostata a {0} brani. - + Bisogna essere in un canale vocale in questo server Nome @@ -1404,16 +1416,16 @@ il nuovo valore di {0} è {1}! In riproduzione - + Nessuna musica in riproduzione. Nessun risultato trovato. - + Riproduzione della musica messa in pausa. - + Coda degli utenti - Pagina {0}/{1} Canzone iniziata @@ -1422,7 +1434,7 @@ il nuovo valore di {0} è {1}! - + Pagina {0} della playlist salvata Playlist cancellata. @@ -1440,7 +1452,7 @@ il nuovo valore di {0} è {1}! Playlist salvata - + limite di {0} secondi Coda @@ -1449,41 +1461,41 @@ il nuovo valore di {0} è {1}! Canzone in coda - + Coda della musica ripulita - + La coda é piena a {0}/{0} Canzone rimossa context: "removed song #5" - + Ripetendo la canzone corrente - + Ripetendo la playlist Traccia ripetuta - + Riproduzione del brano attuale fermata. - + Riproduzione della musica ricominciata. - + Ripeti playlist disabilitato. - + Ripeti playlist abilitato. - + Ora mostrerò i brani in ascolto, finiti, messi in pausa e rimossi in questo canale. - + Saltato a '{0}:{1}' Canzoni mischiate @@ -1534,16 +1546,16 @@ il nuovo valore di {0} è {1}! L'utente {0} può usare TUTTI I MODULI. - + Aggiunto {0} con ID {1} alla lista nera - + Il comando {0} ha adesso {1} secondi di ricarica. - + Il comando {0} non ha più il tempo di ricarica e tutti i tempi di ricarica esistenti sono stati cancellati. - + Nessuna ricarica dei comandi stabilita. Costo dei comandi @@ -1570,22 +1582,22 @@ il nuovo valore di {0} è {1}! Parametro dei secondi non valido.(Deve essere un numero tra {0} e {1}) - + Filtro degli inviti disabilitato in questo canale. - + Filtro degli inviti abilitato su questo canale - + Filtro degli inviti disabilitato su questo canale - + Filtro degli inviti abilitato su questo server - + Spostato il permesso {0} da #{1} a #{2} - + Impossibile trovare il permesso nell'elenco #{0} Nessun costo impostato. @@ -1608,56 +1620,56 @@ il nuovo valore di {0} è {1}! Gli utenti ora devono avere il ruolo di {0} per modificare i permessi. - + Nessun permesso trovato in quell'elenco. - + rimosso il permesso #{0} - {1} - + Disabilitato l'uso di {0} {1} per il ruolo {2}. - + Abilitato l'uso di {0} {1} per il ruolo {2}. - + sec. Short of seconds. - + Disabilitato l'utilizzo di {0} {1} in questo server - + Abilitato l'utilizzo di {0} {1} in questo server - + Rimosso dalla lista nera {0} con l'ID {1} - + non modificabile - + Disabilitato l'uso di {0} {1} per l'utente {2}. - + Abilitato l'uso di {0} {1} per l'utente {2}. - + Non mostreró piú avvisi sui permessi - + Ora mostreró gli avvisi sui permessi. - + Filtro delle parole disabilitato in questo canale. - + Filtro delle parole abilitato in questo canale. - + Filtro delle parole disabilitato in questo server. - + Filtro delle parole abilitato in questo server. Abilità @@ -1672,8 +1684,7 @@ il nuovo valore di {0} è {1}! La tua traduzione automatica dei messaggi è stata rimossa. - La tua auto-traduzione linguaggio è stato impostata a {0}>{0} - Fuzzy + La tua traduzione automatica del linguaggio è stata impostata a {0}>{0} Avviata traduzione automatica dei messaggi in questo canale. @@ -1695,7 +1706,7 @@ il nuovo valore di {0} è {1}! Capitoli - + Fumetto # Competitive perse @@ -1704,7 +1715,7 @@ il nuovo valore di {0} è {1}! Competitive giocate - Rango delle competitive + Rango competitivo Fuzzy @@ -1753,7 +1764,8 @@ il nuovo valore di {0} è {1}! Altezza/Peso - + {0}m/{1}kg + Fuzzy Umidità @@ -1771,14 +1783,13 @@ il nuovo valore di {0} è {1}! Scherzo non caricato. - Latitudine/Lunghezza - Fuzzy + Latitudine/Longitudine Livello - + Lista delle tag {0}place Don't translate {0}place @@ -1788,10 +1799,10 @@ il nuovo valore di {0} è {1}! Oggetto magico non caricato. - + Profilo MAL di {0} - + Il possessore del bot non ha specificato MashapeApiKey, Non puoi usare questa funzione. Minimo/Massimo @@ -1803,23 +1814,23 @@ il nuovo valore di {0} è {1}! Nessun risultato trovato. - + In sospeso Url originale - Fuzzy - + Una chiave API di Osu! é richiesta. - + Recupero della firma di Osu! fallito. + Fuzzy - + Trovate oltre {0} immagini. Piazzandone casualmente {0} - + Utente non trovato! Perfavore controlla la regione e il Battletag prima di riprovare. In programma da guardare @@ -1840,10 +1851,10 @@ il nuovo valore di {0} è {1}! Qualità: - + Gioco veloce - + Vittoria veloce Voto @@ -1885,7 +1896,7 @@ il nuovo valore di {0} è {1}! Non stai seguendo nessuno streaming in questo server. - + Nessun tale stream Questo streaming probabilmente non esiste. @@ -1919,7 +1930,7 @@ il nuovo valore di {0} è {1}! Tipi - + Nessuna definizione trovata per la parola. Url @@ -1932,10 +1943,11 @@ il nuovo valore di {0} è {1}! Fuzzy - + Non sono riuscita a trovare quel termine nella wikia specificata. - + Inserisca una wikia, seguita dalla richiesta di ricerca. + Fuzzy Pagina non trovata. @@ -1947,10 +1959,10 @@ il nuovo valore di {0} è {1}! I campioni più bannati di {0} - + Non sono riuscita a yodificare la tua frase. - + Entrato @@ -1958,7 +1970,7 @@ il nuovo valore di {0} è {1}! `1.` - + Pagina attivitá #{0} {0} utenti in totale. @@ -1970,31 +1982,31 @@ il nuovo valore di {0} è {1}! ID del bot - + Lista di funzioni nel comando {0}calc - + {0} di questo canale è {1} Canale di discussione - + Comandi eseguiti - + {0} {1} è uguale a {2} {3} - + Unità che possono essere usate dal convertitore - + Non posso convertire {0} a {1}: unità non trovate. - + Impossibile convertire {0} in {1}: i tipi di unitá sono diversi - + Creato a @@ -2003,7 +2015,8 @@ il nuovo valore di {0} è {1}! - + Questo é il tuo token CSC + Fuzzy Emoji personalizzati @@ -2019,16 +2032,16 @@ il nuovo valore di {0} è {1}! ID - + Indice fuori dall'intervallo consentito. - + Lista degli utenti con il ruolo {0} - + Non sei autorizzato a usare questo comando con un ruolo comune per prevenirne l'abuso. - + Valore {0} invalido. Invalid months value/ Invalid hours value @@ -2043,10 +2056,10 @@ Membri: {1} ID del proprietario: {2} - + Nessun server trovato su quella pagina. - + Lista dei ripetitori Membri @@ -2076,7 +2089,7 @@ ID del proprietario: {2} Nessun ruolo in questa pagina. - + Nessun frammento in questa pagina. Nessun argomento impostato. @@ -2120,16 +2133,16 @@ ID del proprietario: {2} Registrato il - + Ricorderò {0} a {1} il {2} `({3:d.M.yyyy.} alle {4:HH:mm})` - + Formato data non valido. Controlla la lista dei comandi. - + Nuovo modello di promemoria stabilito. - + Ripetendo {0} ogni {1} giorno(s), {2} ore(s) e {3} minuti(s). Lista dei ripetitori @@ -2151,10 +2164,10 @@ ID del proprietario: {2} Ruoli - + Pagina #{0} di tutti i ruoli in questo server: - + Pagina #{0} dei ruoli di {1} Nessun colore è nel formato giusto. Usa `#00ff00` per esempio. @@ -2167,40 +2180,42 @@ ID del proprietario: {2} Fermata la rotazione dei colori per il {0} ruolo - + {0} di questo server è {1} Info del server - + Frammento - + Statistiche della Shard + Fuzzy - + **Nome:** {0} **Link:** {1} - + Nessuna emoji speciale trovata. - + Avviando {0} canzoni, {1} in coda. Canali di testo - + Qui c'è il link della tua stanza: - + Tempo di funzionamento + Fuzzy - + {0} di questo utente {1} è {2} Id of the user kwoth#1234 is 123123123123 @@ -2213,19 +2228,20 @@ ID del proprietario: {2} Sei già entrato in gara! - + Risultati del sondaggio corrente - + Nessun voto - + C'è già un sondaggio in corso in questo server. - + 📃 {0} ha creato un sondaggio che richiede la tua attenzione: - + '{0}. '{1} con {2} voti. + Fuzzy {0} ha votato. @@ -2244,10 +2260,10 @@ ID del proprietario: {2} {0} voti in totale. - + Prendili scrivendo `{0}prendi` - + Prendilo scrivendo `{0}prendi` Nessun utente trovato. @@ -2262,46 +2278,183 @@ ID del proprietario: {2} Non ci sono ruoli nei canali vocali. - + {0} è stato **mutato* dal canale di testo e vocale per {1} minuti. - + Gli utenti che entrano {0} canale vocale avranno {1} come ruolo. - + Gli utenti che entrano {0} canale vocale non avranno più un ruolo. - + Ruoli del canale vocale - + I messaggi che innescano la reazione personalizzata con id {0} non saranno automaticamente eliminati. - + I messaggi che innescano la reazione personalizzata con id {0} saranno automaticamente eliminati. - + Il messaggio di risposta per la reazione personalizzata con l'id {0} non sarà inviato come MP. - + I messaggi di risposta per la reazione personalizzata id {0} saranno ora mandati come MP. Nessun alias trovato - + Scrivere {0} sarà ora un alias di {1}. - + Lista degli alias - + Innescato {0} non ha più un Alias. + Fuzzy - + Innescato {0} non ha un alias. + Fuzzy - + Tempo di gioco competitivo + + + Canale + + + Testo del comando + + + Espulso + PLURAL + + + Moderatore + + + pagina {0} + + + Ragione + + + Nuovo comando all'avvio aggiunto. + Fuzzy + + + Comando all'avvio rimosso con successo. + Fuzzy + + + Comando all'avvio non trovato. + Fuzzy + + + Server + + + Nessun comando di avvio in questa pagina + Fuzzy + + + Ripuliti tutti i comandi all'avvio. + Fuzzy + + + All'utente {0} é stato rimosso il ban. + + + Utente non trovato. + + + L'utente {0} é stato avvisato. + + + L'utente {0} é stato avvisato e {1} punizioni sono state applicate. + + + Avvisato nel server {0} + + + Il {0} alle {1} da {2} + + + Tutti gli avvisi sono stati cancellati per {0}. + + + Nessun avviso in questa pagina. + + + Lista degli avvisi per {0} + + + Nessuna punizione stabilita. + + + ripulito da {0} + + + Lista degli avvisi. + + + Avere {0} avvisi non porterá piú a una punizione. + + + Applicheró la punizione {0} agli utenti con {1} avvisi. + + + La modalitá lenta ignorerá il ruolo {0}. + Fuzzy + + + La modalitá lenta non ignorerá piú il ruolo {0}. + Fuzzy + + + La modalitá lenta ignorerá l'utente {0}. + Fuzzy + + + La modalitá lenta non ignorerá piú l'utente {0}. + Fuzzy + + + Errore nella richiesta dei premi per le seguenti ragioni: + + + Magari hai giá ricevuto il tuo premio per questo mese, Puoi ricevere premi solo una volta al mese sempre se non aumenti la tua donazione mensile. + + + Giá premiato + + + Il tuo account discord potrebbe non essere connesso con Patreon. Se non sai cosa significa, o non sai come connetterlo - bisogna andare su [la pagina delle impostazioni dell'account Patreon] (https://patreon.com/settings/account) e cliccare su 'Connetti a discord' + + + L'account discord non é connesso + + + Per essere consono a ricevere premi, devi supportare il progetto su patreon. Puoi usare il comando {0} per ricevere il link. + + + Non sta donando + Fuzzy + + + Devi aspettae un po' di ore dopo aver fatto la tua donazione, se non lo hai fatto, prova di nuovo piú tardi + Fuzzy + + + Aspetta un po' di tempo + + + Hai ricevuto {0} ringraziamenti per il supporto del progetto! + + + I premi possono essere richiesti dal 5 di ogni mese \ No newline at end of file From 7fa355af7058583102af5a182c8c7a7a806ff6cd Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:26 +0200 Subject: [PATCH 42/98] Update ResponseStrings.ja-JP.resx (POEditor.com) --- .../Resources/ResponseStrings.ja-JP.resx | 267 +++++++++++++----- 1 file changed, 204 insertions(+), 63 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.ja-JP.resx b/src/NadekoBot/Resources/ResponseStrings.ja-JP.resx index 6e52fbe0..2b33b3f1 100644 --- a/src/NadekoBot/Resources/ResponseStrings.ja-JP.resx +++ b/src/NadekoBot/Resources/ResponseStrings.ja-JP.resx @@ -905,7 +905,8 @@ Fuzzy ソフトバン(キック) - PLURAL + PLURAL +Fuzzy {0}はこのチャンネルを無視します。 @@ -1388,97 +1389,113 @@ Paypal <{1}> {0}の新しい値は{1}です! - + waifuは安いです。実際の値がより低い場合でも、waifuを取得するには少なくとも{0}を支払う必要があります。 - + あなたはwaifuを主張するために{0}以上支払う必要があります! + - + そのwaifuはあなたのものではありません。 + - + あなたは自分自身を主張することはできません。 + - + あなたは最近離婚した。もう離婚するには{0}時間と{1}分待つ必要があります。 + - + 誰も + - + あなたはあなたを好きではない妖精と離婚しました。あなたは{0}戻ってきました。 + エイトボール - + Acrophobia + - + ゲームは提出なしで終了しました。 - + 投票は行われません。ゲームは勝者なしで終了しました。 + - + 頭字語は{0}でした。 - + Acrophobiaゲームは既にこのチャンネルで実行されています。 + - + ゲームが始まった。次の頭文字で{0}の文章を作成します。 - + 投稿には{0}秒かかります。 + - + {0}はその文を提出しました。 ({1}合計) + 数字を入力して投票 - + {0}は投票をしました! + - + 勝者は{1}点で{0}です。 + - + {0}は投稿した唯一のユーザーであるための勝者です! 質問 - + それはドローです!どちらも{0} - + {0}が勝った! {1}が{2}を打つ - + 投稿が閉じられました + - + 動物レースはすでに実行中です。 + - + 合計:{0}平均:{1} + カテゴリー - + このサーバーではCleverbotは使えません。 このサーバーではCleverbotが有効です。 - + このチャンネルでは現在の世代は使えなくなりました。 - + このチャンネルでは現在の世代は使えるようになりました。 @@ -1506,16 +1523,16 @@ Paypal <{1}> - + リーダーボード - + 十分な {0} を持っていません。 - + 結果はありません。 - + {0} をひろった。 Kwoth picked 5* @@ -1523,10 +1540,10 @@ Paypal <{1}> Kwoth planted 5* - + Trivia gameはすでにこのサーバーで動いています。 - + Trivia game @@ -1535,22 +1552,22 @@ Paypal <{1}> - + {0} は {1} ポイント持っています。 - + この質問のあと停止します。 - + 時間切れです。正解は {0} です。 - + あなた自身とはゲームできません。 - + TicTacToe ゲームはすでにこのサーバで動いています。 引き分け @@ -1562,7 +1579,7 @@ Paypal <{1}> {0} の勝ち! - + 三回戦 @@ -1577,7 +1594,7 @@ Paypal <{1}> - + キューに {0} 曲を適用しています。 オートプレイは無効です。 @@ -1592,26 +1609,26 @@ Paypal <{1}> ディレクトリのキューが完了しました。 - + フェアプレイ 曲が終わった Fuzzy - + フェアプレイは無効です。 - + フェアプレイは有効です。 - + ポジションから - + ID - + 不適切な入力。 最大再生時間は制限ありません。 @@ -1688,56 +1705,56 @@ Paypal <{1}> キュー( {0}/{0} ) はいっぱいです。 - + 削除された曲 context: "removed song #5" - + 繰り返し現在の曲 - + 繰り返しプレイリスト - + 繰り返しトラック - + 現在のトラックの繰り返しを中止しました。 - + 曲の再生を再開しました。 - + プレイリストの繰り返しは無効です。 - + プレイリストの繰り返しは有効です。 - + このチャンネルでは、再生、終了、一時停止、曲の削除ができます。 - + スキップしました。 {0}:{1} - + シャッフルした曲 - + 削除した曲 - + {0}時 {1}分 {2}秒 - + 位置に - + 無制限 - + 音量は0から100の間でなければなりません。 - + 音量を {0}% にセット @@ -2527,5 +2544,129 @@ Paypal <{1}> + + + + + + + + + PLURAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From eb4c3c68e7b208177e33fa27faf88a0ea0045fd1 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:28 +0200 Subject: [PATCH 43/98] Update ResponseStrings.ko-KR.resx (POEditor.com) --- .../Resources/ResponseStrings.ko-KR.resx | 855 ++++++++++-------- 1 file changed, 498 insertions(+), 357 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.ko-KR.resx b/src/NadekoBot/Resources/ResponseStrings.ko-KR.resx index 223b9397..239484e4 100644 --- a/src/NadekoBot/Resources/ResponseStrings.ko-KR.resx +++ b/src/NadekoBot/Resources/ResponseStrings.ko-KR.resx @@ -119,7 +119,6 @@ 기지가 이미 요청되었거나 파괴되었습니다. - Fuzzy 기지가 이미 파괴되었습니다. @@ -129,11 +128,9 @@ {1} 와의 전쟁에서 #{0} 번 기지가 **파괴**되었습니다. - Fuzzy {2} 와의 전쟁에서 {0} 가 #{1} 번 기지를 **요청**하지 못했습니다. - Fuzzy {2} 와의 전쟁에서 #{1} 번 기지를 {0} 가 요청하였습니다. @@ -143,11 +140,9 @@ {1} 와의 전쟁에서 @{0} 의 요청이 만료되었습니다. - Fuzzy - Fuzzy {0} 와의 전쟁에 대한 정보 @@ -175,7 +170,6 @@ 크기 - Fuzzy {0} 에 대한 전쟁이 이미 시작되었습니다. @@ -205,7 +199,7 @@ 모든 커스텀 리액션 목록 - 커스텀 리액션 + 커스텀 리액션 목록 새로운 커스텀 리액션 @@ -339,23 +333,23 @@ Fuzzy 봇의 상태가 {0} 으로 변경되었습니다. - 퇴장 메세지의 자동삭제가 비활성화되었습니다. + 퇴장 메시지의 자동삭제가 비활성화되었습니다. Fuzzy - 퇴장 메세지는 앞으로 {0} 초 후에 삭제됩니다. + 퇴장 메시지는 앞으로 {0} 초 후에 삭제됩니다. Fuzzy - 현재 퇴장 메세지: {0} + 현재 퇴장 메시지: {0} Fuzzy - 퇴장 메세지를 활성화하기 위해서는 {0} 를 입력하십시오. + 퇴장 메시지를 활성화하기 위해서는 {0} 를 입력하십시오. Fuzzy - 새로운 퇴장 메세지가 설정되었습니다. + 새로운 퇴장 메시지가 설정되었습니다. Fuzzy @@ -369,7 +363,6 @@ Fuzzy 이전 이름 - Fuzzy 채널의 주제가 변경되었습니다. @@ -379,7 +372,6 @@ Fuzzy 내용 - Fuzzy {0} 역할을 성공적으로 생성하였습니다. @@ -410,11 +402,11 @@ Fuzzy 음성 채널 {0} 를 삭제했습니다. - 개인 메세지 + 개인 메시지 Fuzzy - 성공적으로 새로운 기부자를 추가했습니다. 이 유저의 총 기부량은 {0} 입니다. + 성공적으로 새로운 기부자를 추가했습니다. 이 유저의 총 기부량은 {0} 👑 입니다. 이 프로젝트를 위해 수고해주신 아래의 사람들에게 감사드립니다! @@ -432,19 +424,19 @@ Fuzzy 지금부터 DM 전달을 중단하겠습니다. - 환영 메세지에 대한 자동삭제가 비활성화되었습니다. + 환영 메시지에 대한 자동삭제가 비활성화되었습니다. - 환영 메세지는 {0} 초 후에 삭제될 것입니다. + 환영 메시지는 {0} 초 후에 삭제될 것입니다. - 현재 DM 환영 메세지: {0} + 현재 DM 환영 메시지: {0} - {0} 을(를) 입력하여서 DM 환영 메세지를 활성화시킵니다. + {0} 을(를) 입력하여서 DM 환영 메시지를 활성화시킵니다. - 새로운 DM 환영 메세지가 설정되었습니다. + 새로운 DM 환영 메시지가 설정되었습니다. DM 환영 알림이 비활성화되었습니다. @@ -454,13 +446,13 @@ Fuzzy DM 환영 알림 활성화 되었습니다. - 현재 환영 메세지: {0} + 현재 환영 메시지: {0} - {0} 를 입력하여서 환영 메세지를 활성화시킵니다. + {0} 를 입력하여서 환영 메시지를 활성화시킵니다. - 새로운 환영 메세지가 설정되었습니다. + 새로운 환영 메시지가 설정되었습니다. 환영 알림이 비활성화되었습니다. @@ -541,20 +533,20 @@ Fuzzy {0} 이(가) 다음 역할에 대한 언급을 요청했습니다. - {0} `[봇의 소유자]` 로부터 메세지: + {0} `[봇의 소유자]` 로부터 메시지: Fuzzy - 메세지가 전송되었습니다. + 메시지가 전송되었습니다. {0} 이(가) {1} 에서 {2} 로 이동했습니다. - #{0} 에서 메세지가 삭제되었습니다. + #{0} 에서 메시지가 삭제되었습니다. - #{0} 에서 메세지가 업데이트되었습니다. + #{0} 에서 메시지가 업데이트되었습니다. 음소거 @@ -576,7 +568,7 @@ Fuzzy 요청하신 것을 처리하기 위해서는**관리자** 권한이 필요합니다. - 새로운 메세지 + 새로운 메시지 새로운 닉네임 @@ -594,7 +586,7 @@ Fuzzy 해당하는 Shard ID가 없습니다. - 이전 메세지 + 이전 메시지 이전 닉네임 @@ -669,7 +661,7 @@ Fuzzy 자신보다 가장 높은 역할보다 높은 사용자의 역할을 수정할 수 없습니다. - 다루고있었든 메세지 치웠습니다: {0} + 다루고있었던 메시지를 치웠습니다: {0} Fuzzy @@ -777,16 +769,17 @@ Fuzzy 소프트 밴 (강제퇴장) - PLURAL + PLURAL +Fuzzy {0} 은(는) 이 채널을 무시할 것입니다. - {0} 은(는) 더이상 이 채널을 무시하지 않을 것입니다. + {0} 은(는) 더 이상 이 채널을 무시하지 않을 것입니다. - 만약 사용자가 {0} 개 이상의 같은 메세지를 보내면 {1} 합니다. + 만약 사용자가 {0} 개 이상의 같은 메시지를 보내면 {1} 합니다. __무시하는 채널들__: {2} @@ -842,16 +835,16 @@ Fuzzy Fuzzy - {0} 은(는) 이제 {1} 입니다. + {0} 님은 상태는 {1} 입니다. {0} 은(는) 텍스트와 음성 채팅으로부터 **차단해제**되었습니다. - {0} 님이 {1} 음성채널에 입장하셨습니다. + {0} 님이 음성채널 {1} 에 입장하셨습니다. - {0} 님이 {1} 음성채널에서 퇴장하셨습니다. + {0} 님이 음성채널 {1} 에서 퇴장하셨습니다. {0}님이 음성채널 {1} 에서 {2} 로 이동되었습니다. @@ -942,7 +935,7 @@ Fuzzy Fuzzy - {1} 을(를) 받으려면 이 메세지에 {0} 리액션을 추가하세요. + {1} 을(를) 받으려면 이 메시지에 {0} 리액션을 추가하세요. Fuzzy @@ -1142,7 +1135,7 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 Fuzzy - {0} 이(가) {1} (으)로 레이스를 이겼고 {2}! + {0} 이(가) {1} (으)로 레이스를 이겼고 {2} 을 획득했습니다! Fuzzy @@ -1194,41 +1187,44 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 최고의 와이프 - + 당신의 친밀감이 이미 그 와이프로 설정 했거나 당신에게 친밀감이 없는 상태의 와이프에게 친밀감 삭제를 시도했습니다. - + 친밀감이 {0} 에서 {1} 으로 변경되었습니다. + +*도덕성이 의심스럽습니다.*🤔 Make sure to get the formatting right, and leave the thinking emoji - + 친밀감을 다시 바꾸기 위해서는 {0} 시간 {1} 분을 기다려야합니다. - + 당신의 친밀감은 초기화되었습니다. 당신이 좋아하는 사람은 더 이상 없습니다. - + 님이 {0}의 와이프가 되고싶어합니다. - + 님이 {1} 에 {0} 님을 와이프로 요구했습니다. - + 당신을 좋아하는 와이프와 이혼했습니다. {0} 님이 보상금으로 {1} 만큼을 받았습니다. - + 자기 자신에게 친밀감을 설정 할 수 없습니다. - + 🎉 그들의 사랑이 성취되었습니다! 🎉 +{0} 의 새로운 가치는 {1} 입니다! - + 그렇게 싼 와이프는 없습니다. 와이프를 얻기 위해서는 실제 가치보다 낮더라도 {0} 만큼을 지불해야합니다. - + 와이프를 요구하기 위해서는 {0} 이상을 지불해야합니다! - + 그 와이프는 당신의 와이프가 아닙니다. 자기자신을 클레임 할 수 없습니다. @@ -1242,7 +1238,7 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 아무도 없음 - + 당신을 좋아하지 않는 와이프와 이혼했습니다. 당신은 {0}을 돌려받았습니다. 8ball @@ -1256,98 +1252,102 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 아무런 제출 없이 게임이 끝났습니다. - + 아무도 투표하지 않았습니다. 승자없이 게임이 종료되었습니다. - 두문자가 {0} 이었슴니다. + 머리글자는 {0} 이었습니다. - + 아크로포비아 게임이 이미 이 채널에서 진행 중입니다. - + 게임이 시작되었습니다. {0} 머리글자를 사용해서 문장 만드십시오. + Fuzzy - + 제출까지 {0} 초 남았습니다. - + {0} 가 그의 문장을 입력했습니다. (합계: {1}) - + 제출번호를 입력해서 투표를 하십시오. - + {0} 가 투표했습니다! - + 우승자는 {1} 포인트를 가진 {0} 입니다. - + {0} 님이 서버에서 유일한 제출자이기 때문에 승리했습니다. - + 문제 + - + 비겼습니다! 둘다 {0} 을(를) 선택했습니다. - + {0} 가 승리했습니다! {1} 은(는) {2} 을(를) 이겼습니다. - + 제출이 마감되었습니다. - + 동물 레이스가 이미 진행 중입니다. - + 총합: {0} 평균: {1} - + 범주 - + 이 서버에서 클레버봇을 비활성화하였습니다. - + 이 서버에서 클레버봇을 활성화하였습니다. - + 이 채널에서 통화 생성이 비활성화되었습니다. - + 이 채널에서 통화 생성이 활성화되었습니다. - - plural + {0} 무작위 {1} 가 등장했습니다! + plural +Fuzzy - + 무작위 {0} 가 등장했습니다! - + 질문 로딩에 실패하였습니다. - + 게임이 시작되었습니다 - + 행맨 게임이 시작되었습니다 - + 행맨 게임이 이미 시작되었습니다 - + 행맨 게임 시작에 오류가 발생하였습니다. - + "{0}hangman" 용어 종류 목록 - + 리더 보드 + Fuzzy - + 당신은 충분한 {0} 이(가) 없습니다. 결과가 없습니다. @@ -1361,246 +1361,252 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 Kwoth planted 5* - + 이미 이 서버에서 트리비아 게임이 진행중입니다. - + 트리비아 게임 - + {0} 님이 맞췄습니다! 답은 {1} 입니다. - + 이 서버에서 진행중인 트리비아 게임이 없습니다. - + {0} 이(가) {1} 포인트를 갖고있습니다. - + 이 질문 후에 중지합니다. - + 시간초과! 정확한 답은 {0} 입니다. + Fuzzy - + {0} 님이 맞춰서 게임을 이겼습니다! 답은 {1} 입니다. + Fuzzy - + 당신을 상대로 플레이 할 수 없습니다. - + 이미 이 채널에서 TicTacToe 게임이 진행중입니다. - + 비겼습니다! - + 님이 TicTacToe 게임을 생성하였습니다. - + {0} 님이 이겼습니다! - + 3개 일치 + Fuzzy - + 더 이상 움직일 수 없습니다! - + 시간이 만료되었습니다! - + {0}의 이동 - + {0} 대 {1} - + {0} 개의 곡을 대기열에 추가하는 중... - + 자동재생이 비활성화되었습니다. - + 자동재생이 활성화되었습니다. - + 기본 음량이 {0}%로 설정되었습니다. - + 디렉토리 대기열 추가가 완료되었습니다. + Fuzzy - + 페어플레이 - + 재생 완료 - + 페어플레이가 비활성화되었습니다. - + 페어플레이가 활성화되었습니다. - + 원레 위치 - + ID - + 유효하지 않은 입력입니다. - + 이제 최대 재생시간에 제한이 없습니다. - + 최대 재생시간이 {0} 초로 설정되었습니다. - + 이제 음악 대기열 크기는 제한이 없습니다. - + 음악 대기열 크기가 {0} 곡으로 변경되었습니다. - + 당신은 이 서버의 음성채널에 있어야 합니다. - + 이름 - + 현재 재생 중 - + 재생중인 곡이 없습니다. - + 검색 결과가 없습니다. - + 음악 재생이 일시정지되었습니다. - + 음악 대기열 - {0}/{1} 페이지 - + 노래 재생 중 - + `#{0}` - {2} 님의 재생목록 **{1}** ({3} 곡) - + 저장된 재생목록의 {0} 번째 페이지 - + 재생목록이 삭제되었습니다. - + 재생목록 삭제에 실패했습니다. 존재하지 않거나, 당신이 재생목록의 저자가 아닙니다. - + 그 ID에 해당하는 재생목록이 존재하지 않습니다. - + 재생목록 대기열 추가 완료. - + 재생목록이 저장되었습니다. - + {0} 초 한계 - + 대기열 - + 대기열에 추가됨 - + 음악 대기열이 초기화되었습니다. - + 대기열이 {0}/{0} 으(로) 가득찼습니다. - + 곡 삭제됨 context: "removed song #5" - + 현재 곡을 반복재생합니다. - + 현재 재생목록을 반복재생합니다. - + 현재 트랙을 반복재생합니다. - + 현재 트랙 반복이 중지되었습니다. - + 음악 재생이 재개되었습니다. - + 재생목록 반복이 비활성화되었습니다. - + 재생목록 반복이 활성화되었습니다. - + 앞으로 재생 중, 완료, 일시정지, 삭제된 곡들을 이 채널에 출력합니다. - + `{0}:{1}`로 이동하였습니다. + Fuzzy - + 곡을 섞었습니다. - + 곡이 이동되었습니다. - + {0}시간 {1}분 {2}초 - + 바뀐 위치 + Fuzzy - + 무제한 - + 음량은 0과 100 사이의 값이여야 합니다. - + 음량이 {0}% 로 설정되었습니다. - + {0} 채널에서 모든 모듈의 사용을 비활성화했습니다. - + {0} 채널에서 모든 모듈의 사용을 활성화했습니다. 허락함 Fuzzy - + {0} 역할에게 모든 모듈의 사용을 비활성화했습니다. - + {0} 역할에게 모든 모듈의 사용을 활성화했습니다. - + 이 서버에서 모든 모듈의 사용을 비활성화했습니다. - + 이 서버에서 모든 모듈의 사용을 활성화했습니다. - + {0} 사용자에 대한 모든 모듈의 사용을 비활성화합니다. - + {0} 사용자에 대한 모든 모듈의 사용을 활성화합니다. {0} (ID {1})님을 블랙리스트했습니다 @@ -1639,28 +1645,28 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 Fuzzy - + 유효하지 않은 두번째 파라미터입니다. ( {0} 와(과) {1} 사이의 숫자여야 합니다.) - + 초대 필터링이 이 채널에서 비활성화되었습니다. - + 초대 필터링이 이 채널에서 활성화되었습니다. - + 초대 필터링이 이 서버에서 비활성화되었습니다. - + 초대 필터링이 이 서버에서 활성화되었습니다. - + {0} 권한을 #{1} 에서 #{2} (으)로 이동했습니다. - + 색인 #{0} 에 대한 권한을 찾을 수 없습니다. - + 아무런 값이 설정되지 않았습니다. 명령어 @@ -1674,137 +1680,140 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 권한 목록 {0} 페이지 - + 현재 권한 역할은 {0} 입니다. - + 이제 사용자가 권한 수정을 위해서는 {0} 권한이 필요합니다. - + 그 색인에 대한 권한을 찾을 수 없습니다. - + #{0} - {1} 권한을 삭제했습니다. - + {2} 역할에 대한 {0} {1} 의 사용을 비활성화했습니다. - + {2} 역할에 대한 {0} {1} 의 사용을 활성화했습니다. 초. Short of seconds. - + 이 서버에서 {0} {1} 의 사용을 비활성화했습니다. - + 이 서버에서 {0} {1} 의 사용을 활성화했습니다. - + {0} (ID {1} ) 님을 블랙리스트에서 해제하였습니다. + Fuzzy - + 수정불가 - + {2} 사용자의 {0} {1} 의 사용을 비활성화했습니다. - + {2} 사용자의 {0} {1} 의 사용을 활성화했습니다. - + 더 이상 권한 경고를 표시하지 않습니다. - + 앞으로 권한 경고를 표시합니다. - + 단어 필터링이 이 채널에서 비활성화되었습니다. - + 단어 필터링이 이 채널에서 활성화되었습니다. - + 단어 필터링이 이 서버에서 비활성화되었습니다. - + 단어 필터링이 이 서버에서 활성화되었습니다. 능력 - + 좋아하는 애니메이션이 없습니다. - + 이 채널 메시지의 자동번역을 시작합니다. 사용자의 메시지는 자동삭제 됩니다. - + 당신의 자동번역 언어가 제거되었습니다. - + 당신의 자동번역 언어가 {0}>{1} 로 설정되었습니다. - + 이 채널의 자동번역을 시작합니다. - + 이 채널의 자동번역을 중지합니다. - + 올바르지 않은 입력 포맷이거나 무언가가 잘못되었습니다. - + 그 카드를 찾을 수 없습니다. - + 사실 - + 챕터 - + 만화 # - + 경쟁전 패배 - + 경쟁전 플레이 - + 경쟁전 랭크 - + 경쟁전 승리 - + 완료 - + 조건 - + - + 날짜 - + 정의: + Fuzzy - + 시청 종료 + Fuzzy - + 에피소드 - + 오류가 발생했습니다. - + 예시 애니메이션 검색에 실패했습니다. @@ -1816,7 +1825,7 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 장르 - + 해당 태그에 대한 정의를 찾지 못했습니다. 키/무게 @@ -1834,339 +1843,353 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 영화 검색에 실패했습니다. - + 유효하지 않은 소스 또는 언어입니다. + Fuzzy - + 농담이 로드되지 않았습니다. - + 위도/경도 - + 레벨 - + {0}place 태그 목록 Don't translate {0}place - + 위치 - + 마법 아이템이 로드되지 않습니다. - + {0}의 MAL 프로필 - + 봇의 소유자가 MashapeApiKey을 설정하지 않아서 이 기능을 사용 할 수 없습니다. - + 최소/최대 - + 채널을 찾을 수 없습니다 - + 결과를 찾을 수 없습니다. - + 보류 - + 원본 Url - + osu! API키가 필요합니다. - + osu! 정보 검색에 실패했습니다. - + {0} 개 이상의 이미지가 발견되었습니다. 무작위로 {0}개를 표시합니다. + Fuzzy - + 사용자를 찾을 수 없습니다! 다시 시도하기 전에 지역과 배틀태그를 확인해주십시오 - + 볼 예정 - + 플랫폼 - + 능력을 찾을 수 없습니다. - + 포케몬을 찾을 수 없습니다. - + 프로필 링크: - + 품질: - + 빠른대전 플레이 시간 - + 빠른대전 승리 - + 레이팅 - + 점수: - + 검색 쿼리: - + Url 단축에 실패했습니다. - + Url 단축 - + 무언가가 잘못되었습니다. - + 검색어를 입력해주세요. + Fuzzy - + 상태 - + 저장된 Url + Fuzzy - + 스트리머 {0} 은(는) 오프라인입니다. - + 스트리머 {0} 은(는) {1} 명의 시청자와 함께 온라인입니다. + Fuzzy - + 당신은 이 서버에서 {0} 개의 스트리밍을 팔로우 중입니다. - + 당신은 이 서버에서 어떠한 스트리밍도 팔로우하지 않았습니다. + Fuzzy - + 스트리밍이 없습니다. - + 스트리밍 속성이 존재하지 않습니다. - + {0}의 스트리밍 ({1})을 알림에서 삭제했습니다. - + 상태가 변경되면 이 채널에 알립니다. - + 일출 - + 일몰 - + 온도 - + 제목: - + 좋아하는 상위 3개 애니: - + 번역 결과: - + 종류 - + 해당 용어에 대한 정의를 찾지 못했습니다. - + Url - + 시청자 - 보고있는것: + 시청중 Fuzzy - + 해당 용어에 대한 특정 Wikia를 찾지 못했습니다. - + 목적 Wikia를 입력하고 검색 쿼리를 입력하십시오. - + 페이지를 찾지 못했습니다. - + 바람의 속도 - + {0} 번째로 많은 밴을 당한 챔피언 - + 당신의 문장을 Yodify하지 못했습니다. - + 입장 - + `{0}.` {1} [{2:F2}/초] - 합계 {3} /s and total need to be localized to fit the context - `1.` - + 활성 페이지 #{0} - + 총 {0} 명의 사용자. - + 저자 - + 봇 ID - + {0}calc 명령어의 기능 목록 - + 이 채널의 {0} 은 {1} 입니다. - + 채널 주제 - + 실행된 명령어 - + {0} {1} 은(는) {2} {3} 와(과) 같습니다. - + 변환기에서 사용할수있는 단위 - + 단위를 찾지 못해서 {0} 을(를) {1} (으)로 변환 할 수 없습니다. + Fuzzy - + 단위의 종류가 같지 않기때문에 {0} 을(를) {1} (으)로 변환 할 수 없습니다. + Fuzzy - + 작성 시간: - + 크로스 서버 채널에 입장했습니다. + Fuzzy - + 크로스 서버 채널에서 퇴장했습니다. - + 이것은 당신의 CSC 토큰입니다. - + 커스텀 이모지 - + 오류 - + 기능 - + 아이디 - + 색인이 범위를 벗어났습니다. + Fuzzy - + {0} 역할의 사용자 목록 - + 악용을 막기위해서 많은 사용자가 있는 역할의 이 명령어 사용이 제한되었습니다. - + 유효하지 않은 {0} 값입니다. Invalid months value/ Invalid hours value - + 디스코드 입장 - + 서버 입장 - + ID: {0} +맴버: {1} +소유자 ID: {2} - + 이 페이지에서 서버를 찾을 수 없습니다. - + 리피터 목록 - + 맴버 - + 메모리 - + 메시지 - + 메시지 리피터 - + 이름 - + 닉네임 - + 아무도 그 게임을 플레이하고 있지 않습니다. - + 활성화된 리피터가 없습니다. - + 이 페이지에 역할이 없습니다. - + 이 페이지에 Shard가 없습니다. - + 주제가 설정되지 않았습니다. - + 소유자 - + 소유자의 ID - + 상태 - + {0} 서버 +{1} 텍스트 채널 +{2} 음성 채널 - + {0} 키워드를 가진 모든 인용구를 삭제했습니다. - + 인용구 페이지 {0} - + 이 페이지에 인용구가 없습니다. - + 삭제 할 수 있는 인용구를 찾지못했습니다. 인용구가 추가되었습니다. @@ -2181,28 +2204,28 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 가입 날짜 - + 제가 {2} `({3:d.M.yyyy.} at {4:HH:mm})`에 {0} 에게 {1}을(를) 상기시킬 것입니다. 유효하지않은 시간 포맷입니다. 명령어 목록을 확인하십시오. - + 새로운 상기 템플릿이 설정되었습니다. - + {0} 을 {1} 일 {2} 시간 {3} 분마다 반복합니다. 반복 메시지 목록 - 이 서버에 반복 메시지 실행하고있지 안습니다. + 이 서버에 반복 메시지가 실행하고있지 않습니다. #{0} 이 정지되었습니다. - + 이 서버에서 반복 메시지를 찾을 수 없습니다. 결과 @@ -2211,25 +2234,26 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 역할 - + 이 서버의 모든 역할 페이지 #{0} : - + {1} 역할에 대한 페이지 #{0} - + 색상 포맷이 정확하지 않습니다. `#00FF00`을 사용해보십시오. - + {0} 역할의 색상 로테이션을 시작했습니다. + Fuzzy - + {0} 역할의 색상 로테이션을 중지했습니다. - + 이 서버의 {0} 은 {1} 입니다. - + 서버 정보 Shard @@ -2245,7 +2269,6 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 특수 이모지를 찾을 수 없습니다. - Fuzzy {0} 개의 곡을 재생중이며, {1} 개의 대기열이 있습니다. @@ -2254,10 +2277,10 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 텍스트 채널 - + 방 링크: - + 작동 시간 {1} 의 {0} 은(는) {2} 입니다. @@ -2265,7 +2288,6 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 사용자 - Fuzzy 음성 채널 @@ -2284,10 +2306,9 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 📃 {0} 님이 투표를 생성하였습니다. - Fuzzy - + `{0}.` {2} 표를 가진 {1}. {0} 님이 투표하였습니다. @@ -2295,25 +2316,21 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 해당 답변 번호와 함께 개인 메시지를 보내십시오. - Fuzzy 해당 답변 번호와 함께 여기에 메시지를 보내십시오. - Fuzzy {0} 님, 투표해주셔서 감사합니다 - {0} 개의 표가 던져졌습니다. - Fuzzy + {0} 개의 표가 투표되었습니다. - + `{0}pick`을 입력해서 획득하십시오. `{0}pick`을 입력해서 획득하십시오. - Fuzzy 사용자를 찾지 못했습니다. @@ -2331,31 +2348,31 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 {0} 은(는) 음성과 텍스트 채팅으로 부터 {1} 분간 **음소거**되었습니다. - {0} 음성채널에 입장하는 사용자는 {1} 역할을 얻게됩니다. + 음성채널 {0} 에 입장하는 사용자는 {1} 역할을 얻게됩니다. - {0} 음성채널에 입장하는 사용자는 더이상 {1} 역할을 얻지 못합니다. + 음성채널 {0} 에 입장하는 사용자는 더이상 {1} 역할을 얻지 못합니다. 음성채널 역할 - + ID {0} 커스텀 리액션을 작동시키는 메시지는 자동삭제되지 않습니다. - + ID {0} 커스텀 리액션을 작동시키는 메시지는 자동삭제됩니다. - + 이제 ID {0} 커스텀 리액션에 대한 반응은 DM으로 전송되지 않습니다. - + ID {0} 커스텀 리액션에 대한 반응은 DM으로 전송됩니다. 가명을 찾지 못했습니다. - {0} 입력은 이제 {1} 의 가명일것이니다. + {0} 을(를) 입력하면 이제 {1} 의 가명입니다. 가명 목록 @@ -2364,10 +2381,134 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 트리거 {0} 의 가명을 삭제했습니다. - 트리거 {0} 은(는) 가명 없었습니다. + 트리거 {0} 은(는) 가명이 없었습니다. - 경기한 시간 + 경쟁전 플레이 시간 + + + 채널 + + + 명령어 텍스트 + + + 강퇴 + PLURAL + + + 관리자 + + + {0} 페이지 + + + 사유 + + + 새로운 시작 명령어가 추가되었습니다. + + + 시작 명렁어가 성공적으로 삭제되었습니다. + + + 시작 명령어를 찾을 수 없습니다. + + + 서버 + + + 이 페이지에는 시작 명령어가 없습니다. + + + 모든 시작 명령어를 삭제했습니다. + + + 사용자 {0} 님이 밴에서 해제되었습니다. + + + 사용자를 찾을 수 없습니다. + + + 사용자 {0} 님이 경고를 받았습니다. + + + 사용자 {0} 님이 경고를 받았고, {1} 처벌이 적용되었습니다. + + + {0} 서버에 경고했습니다. + + + {0} {1} 에 {2} 이(가) + + + {0} 님이 모든 경고를 삭제했습니다. + + + 이 페이지에는 경고가 없습니다. + + + {0} 의 경고 기록 + + + 처벌이 설정되지 않았습니다. + + + {0} 이(가) 제거했습니다. + + + 경고 처벌 목록 + + + {0} 개의 경고를 받은 사용자에 대한 처벌을 하지않습니다. + + + {1} 개의 경고를 받은 사용자에게 {0} 처벌을 내립니다. + + + 이제 슬로우모드는 {0} 역할에게 적용되지 않습니다. + + + 이제 슬로우모드는 {0} 역할에게 적용됩니다. + + + 이제 슬로우모드는 {0} 님에게 적용되지 않습니다. + + + 이제 슬로우모드는 {0} 님에게 적용됩니다. + + + 다음과 같은 이유로 인해서 보상을 요청하지 못했습니다: + + + 당신은 이미 이번달의 보상을 받은 것 같습니다. 당신의 후원금을 올리지 않는 이상 한 달에 한 번만 보상을 받을 수 있습니다. + + + 이미 지급되었습니다. + + + 당신의 디스코드 계정이 Patreon에 연결되지 않았습니다. 이것이 무슨 뜻인지 모르거나, 어떻게 연결하는지 모른다면 - [Patreon 계정 설정 페이지] (https://patreon.com/settings/account) 에 접속해서 'Connect to discord' 버튼을 클릭하십시오. + + + 디스코드 계정이 연결되지 않았습니다. + + + 보상을 받을 수 있는 자격을 얻기 위해서는 Patreon에서 프로젝트를 후원해야 합니다. {0} 명령어를 이용해서 링크를 얻을 수 있습니다. + + + 후원 중이지 않습니다. + + + 다시 시도하지 않았다면, 후원을 한 후에 몇 시간을 기다려야합니다. + + + 잠시만 기다려주십시오. + + + {0} 을 받았습니다. 프로젝트를 후원 해주셔서 감사합니다! + + + 보상은 매 달 5일에 요구 할 수 있습니다. \ No newline at end of file From 2574546c823b87696edbe8b14fdbb53aab0f7b64 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:31 +0200 Subject: [PATCH 44/98] Update ResponseStrings.nb-NO.resx (POEditor.com) --- .../Resources/ResponseStrings.nb-NO.resx | 128 +++++++++++++++++- 1 file changed, 127 insertions(+), 1 deletion(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.nb-NO.resx b/src/NadekoBot/Resources/ResponseStrings.nb-NO.resx index 08aa81fa..52009361 100644 --- a/src/NadekoBot/Resources/ResponseStrings.nb-NO.resx +++ b/src/NadekoBot/Resources/ResponseStrings.nb-NO.resx @@ -761,7 +761,8 @@ Grunn: {1} soft-banned (sparket) - PLURAL + PLURAL +Fuzzy {0} vil nå ignorere denne kanalen. @@ -2334,5 +2335,130 @@ Eier ID: {2} Kompetitiv spilltid + + Kanal + + + Kommando tekst + + + Sparket + PLURAL + + + Moderator + + + side {0} + + + Grunn + + + Ny oppstartskommando lagt til. + + + Oppstartskommando fjernet. + + + Fant ikke oppstartskommando + + + Server + + + Ingen oppstartskommandoer på denne siden. + + + Fjernet alle oppstartskommandoer + + + Bruker {0} er ikke lenger utestengt + + + Fant ikke bruker. + + + Advarte bruker {0} + + + Bruker {0} ble advart og straffet med {0} + + + Advart på server {0} + + + Den {0} kl. {1} av {2} + On 02.04.2017 at 16:03 by Kwoth + + + Alle advarsler fjernet for {0} + + + Ingen advarsler på denne siden. + + + Advarselslogg for {0} + + + Ingen straff satt. + + + fjernet av {0} + + + Straffliste + + + Å ha {0} advarsler vil ikke lenger gi noen straff. + + + Brukere med {1} advarsler vil bli straffet med {0} + + + Slowmode vil nå ignorere rollen {0}. + + + Slowmode ignorerer ikke lenger rollen {0}. + + + Slowmode vil nå ignorere brukeren {0}. + + + Slowmode vil ikke lenger ignorere brukeren {0} + + + Kunne ikke hevde premie p.g.a. én av følgende grunner: + + + Det er mulig du allerede har mottatt premien din for denne måneden. Du kan bare hevde premien én gang i måneden med mindre du øker summen. + + + Allerede belønnet. + + + Din Discord konto er ikke tilkoblet Patreon. Om du er usikker på hva dette betyr, eller ikke er sikker på hvordan du gjør det, kan du gå til [Patreon kontoinnstillinger](https://patreon.com/settings/account) og klikk på 'Connect to Discord'-knappen. + + + Discord kontoen er ikke tilknyttet. + + + For å være kvalifisert for belønning, må du støtte prosjektet på Patreon. Du kan bruke {0} kommandoen for å få link. + + + Støttes ikke + + + Du må vente noen timer etter du har gitt ditt løfte. Prøv igjen om litt. + + + Vent litt. + + + Du har mottatt {0}. Takk for at du støtter prosjektet! + + + Belønninger kan bare hevdes fra og med den 5. dagen i måneden. + \ No newline at end of file From a4219a89db020d48637517abdf5b551c7d47fa2f Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:34 +0200 Subject: [PATCH 45/98] Update ResponseStrings.pl-PL.resx (POEditor.com) --- .../Resources/ResponseStrings.pl-PL.resx | 277 +++++++++++++----- 1 file changed, 201 insertions(+), 76 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.pl-PL.resx b/src/NadekoBot/Resources/ResponseStrings.pl-PL.resx index 2d71a47b..01fe013c 100644 --- a/src/NadekoBot/Resources/ResponseStrings.pl-PL.resx +++ b/src/NadekoBot/Resources/ResponseStrings.pl-PL.resx @@ -203,16 +203,16 @@ Lista własnych reakcji - Własne reakcje + Niestandardowe reakcje - Nowe własne reakcje + Nowe niestandardowe reakcje - Własne reakcje nie zostały znalezione. + Niestandardowe reakcje nie zostały znalezione. - Własne reakcje z tym ID nie zostały znalezione. + Niestandardowe reakcje z tym ID nie zostały znalezione. Odpowiedź @@ -221,7 +221,7 @@ Statystyki niestandardowych reakcji - + Statystyki wyczyszczone dla {0} niestandardowych reakcji. @@ -480,7 +480,7 @@ Powód: {1} Fuzzy - + Twojego servra lokal jest teraz {0} - {1} @@ -520,7 +520,7 @@ Powód: {1} Logowanie nie będzie ignorowało {0} - + Logowanie wydarzenia {1} zatrzymane. @@ -755,7 +755,8 @@ Powód: {1} lekko zbanowany (wyrzucony) - PLURAL + PLURAL +Fuzzy {0} będzie ignorował ten kanał. @@ -880,7 +881,7 @@ Powód: {1} Migracja zakończona! - + Błąd podczas migracji, sprawdz konsole bota po więcej informacji. @@ -921,7 +922,7 @@ Powód: {1} Wydarzenie reagowania kwiatkami rozpoczęło się! - dał (0} dla {1} + dał {0} dla {1} X has gifted 15 flowers to Y @@ -979,10 +980,10 @@ Powód: {1} Trwa {0} sekund. Nie nikomu. Ciiii. - + Wydarzenie SneakyGame zakończyło się. {0} użytkowników otrzymało nagrodę. - + Wydarzenie SneakyGameStatus rozpoczęło się. Reszka @@ -1010,10 +1011,10 @@ Trwa {0} sekund. Nie nikomu. Ciiii. Komendy i aliasy - + Lista komend została wygenerowana na nowo. - + Wpisz `{0}h NazwaKomendy` aby otrzymać pomoc dla danej komendy, np. `{0}h >8ball` Nie mogę znaleźć komendy. Proszę sprawdź czy komenda istnieje, zanim jej użyjesz. @@ -1048,7 +1049,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Ten moduł nie istnieje. - + Wymaga {0} uprawnień na serwerze. Spis treści @@ -1094,7 +1095,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś {1} czyli {0} wygrał wyścig i {2}! - Użyty numer jest nie poprawny. Możesz rzucić {0}-{1} kośćmi na raz + Użyty numer jest niepoprawny. Możesz rzucić {0}-{1} kośćmi na raz wyrzucono {0} @@ -1164,7 +1165,8 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś - + 🎉 To prawdziwa miłość! 🎉 +Nowa wartość {0} to {1}! Żadna waifu nie jest taka tania. Musisz zapłacić co najmniej {0} aby zdobyć waifu, nawet jeśli nie jest tyle warta. @@ -1188,13 +1190,13 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Rozwiodłeś się z waifu, która cię nie lubi. W zamian dostałeś {0}. - Magiczna kula nr 8 + Kula nr. 8 - + Gra zakończona bez żadnych zgłoszeń. Jakies pomysły jak przetlumaczyć Submission by miało sens? @@ -1207,19 +1209,19 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś - + Gra rozpoczęta. Stwórz zdanie z podanym akronimem: {0}. - + Masz {0} sekund aby coś zgłosić. - + {0} zgłosił swoje zdanie. (łącznie {1}) - + Głosuj, wpisując numer zgłoszenia. - + {0} dał swój głos! Zwycięzcą jest {0} z {1} punktami. @@ -1266,7 +1268,6 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś {0} się pojawiły! - Fuzzy Nie udało się załadować pytania. @@ -1293,7 +1294,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Nie masz wystarczająco {0} - Brak rezultatów + Brak wyników podniósł {0} @@ -1304,7 +1305,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Kwoth planted 5* - Trivia jest aktywna na tym serwerze + Trivia jest aktywna na tym serwerze. Trivia @@ -1313,13 +1314,13 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś {0} zgadł! Odpowiedź to: {1} - Trivia nie jest aktywna na tym serwerze + Trivia nie jest aktywna na tym serwerze. {0} posiada {1} punktów - Koniec po tym pytaniu + Koniec po tym pytaniu. Koniec czasu! Prawidłowa odpowiedź to {0} @@ -1331,7 +1332,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Nie możesz grać przeciwko sobie. - + Gra kółko i krzyżyk jest aktywna na tym serwerze. Remis! @@ -1385,7 +1386,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Fair play włączony. - + Z pozycji ID @@ -1415,7 +1416,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Teraz gra - + Brak aktywnego odtwarzacza muzyki. Brak wyników @@ -1430,7 +1431,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Gra utwór - + `#{0}` - **{1}** przez *{2}* ({3} piosenek) Strona {0} zapisanych playlist @@ -1451,7 +1452,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Playlista zapisana - + Limit {0} Kolejka @@ -1506,7 +1507,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś {0}g {1}m {2}s - + Do pozycji bez limitu @@ -1613,7 +1614,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Strona uprawnień {0} - + Aktualna rola z uprawnieniami to {0}. Użytkownicy wymagają roli {0}, by móc edytować uprawnienia. @@ -1811,7 +1812,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Brak rezultatów. - + Wstrzymane Oryginalny URL @@ -1820,7 +1821,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Klucz osu! API jest wymagany. - + Nie udało się wywołać sygnatury osu!. Znaleziono {0} obrazków. Pokazuję przypadkowe {0} @@ -1835,7 +1836,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Platforma - + Nie znaleziono umięjętności. Pokemon nieznaleziony @@ -1844,13 +1845,13 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Link profilowy: - + Jakość: - + Szybkie wygrane Ocena @@ -1871,7 +1872,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Coś poszło nie tak. - + Proszę o sprecyzowanie kryteriów wyszukiwania. Status @@ -1902,7 +1903,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Usunięto stream użytkownika {0} ({1}) z powiadomień. - + Powiadomię ten kanał kiedy status się zmieni. Wschód słońca @@ -1926,7 +1927,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Typy - + Nie znaleziono definicji dla tego terminu. Url @@ -1938,7 +1939,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś Oglądane - + Nie znaleziono tego terminu na konkretnej wikii. @@ -1964,7 +1965,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś `1.` - + Strona aktywności #{0} Łącznie {0} użytkowników. @@ -1979,7 +1980,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś - + {0} tego kanału to {1} Temat kanału @@ -2009,7 +2010,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś - + To jest twój token CSC Niestandardowe emotikony @@ -2027,7 +2028,7 @@ Nie zapomnij zostawić swojej discordowej nazwy użytkownika albo ID w wiadomoś - + Lista użytkowników w roli {0} @@ -2081,7 +2082,7 @@ ID właściciela: {2} Brak roli na tej stronie. - + Brak shard'ów na tej stronie. Brak tematu. @@ -2093,7 +2094,7 @@ ID właściciela: {2} ID właściciela - + Obecność {0} serwerów @@ -2107,10 +2108,10 @@ ID właściciela: {2} {0} strona cytatów - + Brak cytatów ona tej stronie. - + Nie znaleziono żadnych cytatów które możesz usunąć. Dodano cytat @@ -2122,10 +2123,10 @@ ID właściciela: {2} Region - + Zarejestrowany - + Przypomnę {0} dla {2} `({3:d.M.yyyy.} o {4:HH:mm})` @@ -2155,10 +2156,10 @@ ID właściciela: {2} Role - + Strona #{} wszystkich ról na tym serwerze: - + Strona #{0} ról {1} Kolory zostały podane w niepoprawnej formie. Użyj np. `#00ff00` @@ -2170,16 +2171,16 @@ ID właściciela: {2} Zakończono zmienianie kolorów dla roli {0} - + {0} tego serwera to {1} Informacje o serwerze - + Shard - + Statystyki odłamka @@ -2191,7 +2192,7 @@ ID właściciela: {2} Nie znaleziono żadnych specjalnych emotikon - + Teraz leci {0} piosenek; {1} w kolejce Kanały głosowe @@ -2200,7 +2201,7 @@ ID właściciela: {2} Twój link do pokoju: - + Czas działania @@ -2219,13 +2220,13 @@ ID właściciela: {2} - + Nie ma oddanych głosów. - + Ankieta już istnieje na tym serwerze. - + 📃 {0} stworzył ankietę, która wymaga twojej uwagi: `{0}.` {1} z {2} głosami. @@ -2244,25 +2245,25 @@ ID właściciela: {2} Dziękuję za oddany głos, {0} - + {0} oddanych głosów. - + Podnieś je przez napisanie `{0}pick` - + Podnieś to przez napisanie `{0}pick` - + Nie znaleziono użytkownika. - + Strona {0} - Musisz znajdować się w kanale głosowym na tym serwerze. + Musisz znajdować się na kanale głosowym na tym serwerze. - + Niema żadnych ról w kanałach głosowych. {0} został **wyciszony** w kanałach tekstowych oraz głosowych na {1} minut. @@ -2271,7 +2272,7 @@ ID właściciela: {2} Użytkownicy którzy dołączą do kanału głosowego {0} , otrzymają rolę {1}. - + Użytkownicy którzy dołączą do kanału głosowego {0} już nie dostaną roli. Uprawnienia kanału głosowego @@ -2283,10 +2284,10 @@ ID właściciela: {2} - + Odpowiedź na niestandardową reakcję z id {0} będzie wysłana jako wiadomość prywatna. - + Odpowiedź na niestandardową reakcję z id {0} będzie wysłana jako wiadomość prywatna. @@ -2295,7 +2296,7 @@ ID właściciela: {2} - + Lista pseudonimów @@ -2306,5 +2307,129 @@ ID właściciela: {2} + + Kanał + + + + + + Wyrzucony + PLURAL + + + Moderator + + + strona {0} + + + Powód + + + + + + + + + + + + Serwer + + + + + + + + + Użytkownik {0} został odbanowany. + + + Użytkownik nieznaleziony. + + + Użytkownik {0} został ostrzeżony. + + + + + + + + + Dnia {0} o godzinie {1} przez {2} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Otrzymałeś {0}. Dziękujemy, że wspierasz projekt! + + + + \ No newline at end of file From 4995b88fc71baf154688e68a41966e7ab686581f Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:36 +0200 Subject: [PATCH 46/98] Update ResponseStrings.pt-BR.resx (POEditor.com) --- .../Resources/ResponseStrings.pt-BR.resx | 127 +++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.pt-BR.resx b/src/NadekoBot/Resources/ResponseStrings.pt-BR.resx index abbdde18..a416a95e 100644 --- a/src/NadekoBot/Resources/ResponseStrings.pt-BR.resx +++ b/src/NadekoBot/Resources/ResponseStrings.pt-BR.resx @@ -762,7 +762,8 @@ Razão: {1} Banidos temporariamente (kickados) - PLURAL + PLURAL +Fuzzy {0} irá ignorar esse canal. @@ -2383,5 +2384,129 @@ OwnerID: {2} Tempo de jogo competitivo + + Canal + + + Comando de Texto + + + Chutado + PLURAL + + + Moderador + + + página {0} + + + Motivo + + + Novo comando de inicialização adicionado. + + + Comando de inicialização removido com sucesso. + + + Comando de inicialização não encontrado. + + + Servidor + + + Não há comandos de inicialização nesta página. + + + Todos os comandos de inicialização foram removidos. + + + Usuário {0} foi desbanido. + + + Usuário não encontrado. + + + Usuário {0} foi advertido. + + + Usuário {0} foi advertido e {1} punição foi aplicada. + + + Advertiu no server {0} + + + Em {0} às {1} por {2} + + + Todas as advertências foram removidas para {0} + + + Não há advertências nessa página. + + + Log de advertências para {0} + + + Nenhuma punição definida. + + + Limpado por {0} + + + Lista de punições por advertência + + + Possuir {0} advertências não irá mais resultar em punição. + + + Eu irei aplicar punição {0} para usuários com {1} advertências. + + + Modo lento agora irá ignorar o cargo {0}. + + + Modo lento não ira mais ignorar o cargo {0}. + + + Modo lento irá ignorar o usuário {0}. + + + Modo lento não irá mais ignorar o usuário {0}. + + + Falha em reivindicar recompensas devido a uma das seguintes razões: + + + Talvez você já tenha recebido sua recompensa esse mês. Você pode receber recompensas apenas uma vez por mês a não ser que você aumente o seu pagamento. + + + Já recompensado + + + Sua conta do discord pode não estar conectada ao Patreon. Se você não tem certeza do que isso significa, ou não sabe como conectá-la - Você deve ir para [Página de configurações de conta do Patreon)(https://patreon.com/settings/account) e clicar em 'Connect to discord' button. + + + Conta do discord não conectada + + + Para poder receber recompensas, você deve dar suporte ao projeto no patreon. Você pode usar o comando {0} para receber o link. + + + Não suportando + + + Você deve esperar algumas horas depois de realizar seu pagamento. Se não o fez, tente novamente mais tarde. + + + Espere um momento + + + Você recebeu {0} Obrigado por dar suporte ao projeto! + + + Recompensas podem ser reivindicadas no ou a partir do 5° dia de cada mês + \ No newline at end of file From 1a2433bbaf2cb12d13a03b9979cbfdd941c376cf Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:39 +0200 Subject: [PATCH 47/98] Update ResponseStrings.ru-RU.resx (POEditor.com) --- .../Resources/ResponseStrings.ru-RU.resx | 146 +++++++++++++++++- 1 file changed, 142 insertions(+), 4 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.ru-RU.resx b/src/NadekoBot/Resources/ResponseStrings.ru-RU.resx index 8edacbe6..0044bbbc 100644 --- a/src/NadekoBot/Resources/ResponseStrings.ru-RU.resx +++ b/src/NadekoBot/Resources/ResponseStrings.ru-RU.resx @@ -743,7 +743,8 @@ Fuzzy выгнаны - PLURAL + PLURAL +Fuzzy {0} будет игнорировать данный канал. @@ -1119,7 +1120,7 @@ Paypal <{1}> сменил свою предрасположенность с {0} на {1}. -*Это сомнительно с моральной точки зрения* :thinking: +*Это сомнительно с моральной точки зрения.*🤔 Make sure to get the formatting right, and leave the thinking emoji @@ -2261,11 +2262,11 @@ ID Владельца: {2} Fuzzy - Сообщение, инициирующее настраеваемую реакцию с номером {0}, будет автоматически удалено. + Сообщение, инициирующее настраиваемую реакцию с номером {0}, будет автоматически удалено. Fuzzy - Ответное сообщение для настраеваемой реакции с номером {0} не будет отправлено в ЛС. + Ответное сообщение для настраиваемой реакции с номером {0} не будет отправлено в ЛС. Fuzzy @@ -2295,5 +2296,142 @@ Fuzzy Время в игре + + Канал + + + Текст команды + + + Выгнаны + PLURAL + + + Модератор + + + страница {0} + + + Причина + + + Новая команда автозапуска добавлена. + Fuzzy + + + Новая команда автозапуска успешно удалена. + Fuzzy + + + Команда автозапуска не найдена. + Fuzzy + + + Сервер + + + Не найдено команд автозапуска на этой странице. + Fuzzy + + + Удалены все команды автозапуска. + Fuzzy + + + Пользователь {0} был разбанен. + + + Пользователь не найден. + + + Пользователь {0} получил предупреждение. + Fuzzy + + + Пользователь {0} получил предупреждение и наказание {1} было применено. + Fuzzy + + + Предупреждение было вынесено на сервере {0} + + + {0} в {1} пользователем {2} + Fuzzy + + + Все предупреждения были удалены для пользователя {0}. + + + На этой странице нет предупреждений. + + + Регистрация предупреждений для пользователя {0} + Fuzzy + + + Наказания не выставлены. + Fuzzy + + + очищен пользователем {0} + + + Список наказаний для предупреждений + Fuzzy + + + Наказание больше не будет применено после {0} предупреждений. + Fuzzy + + + Для пользователей с {1} предупреждениями будет применено наказание {0}. + Fuzzy + + + Медленный режим больше не распространяется на роль {0}. + + + Медленный режим теперь распространяется на роль {0}. + + + Медленный режим больше не распространяется на пользователя {0}. + + + Медленный режим теперь распространяется на пользователя {0}. + + + Не удалось получить награды по одной из следующих причин: + + + Возможно, Вы уже получили Ваши награды за этот месяц. Вы можете получать награды только раз в месяц, если Вы не увеличивали Ваше пожертвование. + + + Уже были получены + + + Ваш аккаунт в Discord, скорее всего, не подключён к Patreon. Если Вы не уверены, что это значит или не знаете, как его подключить, то Вам необходимо перейти на [Страницу настроек аккаунта в Patreon](https://patreon.com/settings/account) и нажать кнопку "Connect to discord." + + + Аккаунт Discord не подключён + + + Для получения наград Вам необходимо поддерживать проект в Patreon. Вы можете воспользоваться командой {0}, чтобы получить ссылку. + + + Вы не поддерживаете проект + + + Вам необходимо подождать несколько часов после Вашего пожертвования, если Вы не делали этого, попробуйте позже. + + + Подождите немного + + + Вы получили {0}. Спасибо за поддержку проекта! + + + Награды могут быть получены только начиная с 5-го числа месяца. + \ No newline at end of file From b04b03495fe29aa92cbd42b0f834ad24488693f5 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:42 +0200 Subject: [PATCH 48/98] Update ResponseStrings.sr-cyrl-rs.resx (POEditor.com) --- .../Resources/ResponseStrings.sr-cyrl-rs.resx | 127 +++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.sr-cyrl-rs.resx b/src/NadekoBot/Resources/ResponseStrings.sr-cyrl-rs.resx index 8fe7d18e..31342757 100644 --- a/src/NadekoBot/Resources/ResponseStrings.sr-cyrl-rs.resx +++ b/src/NadekoBot/Resources/ResponseStrings.sr-cyrl-rs.resx @@ -752,7 +752,8 @@ Reason: {1} soft-banned (kicked) - PLURAL + PLURAL +Fuzzy {0} will ignore this channel. @@ -2326,5 +2327,129 @@ Lasts {1} seconds. Don't tell anyone. Shhh. + + + + + + + + + PLURAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 1dd3bbe312ab466bc85cdc1bd06ca8c7cf98fb3d Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:44 +0200 Subject: [PATCH 49/98] Update ResponseStrings.es-ES.resx (POEditor.com) --- .../Resources/ResponseStrings.es-ES.resx | 129 +++++++++++++++++- 1 file changed, 127 insertions(+), 2 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.es-ES.resx b/src/NadekoBot/Resources/ResponseStrings.es-ES.resx index 37e12fc6..b5813634 100644 --- a/src/NadekoBot/Resources/ResponseStrings.es-ES.resx +++ b/src/NadekoBot/Resources/ResponseStrings.es-ES.resx @@ -741,8 +741,9 @@ Razón: {1} Modo lento iniciado - advertido (expulsado) - PLURAL + advertidos (expulsado) + PLURAL +Fuzzy {0} ignorará este canal. @@ -2277,5 +2278,129 @@ IDs de dueños: {2} Tiempo de juego en competitivo + + Canal + + + Comando de texto + + + Expulsados + PLURAL + + + Moderador + + + Página {0} + + + Razón + + + Nuevo comando de inicio añadido. + + + Comando de inicio removido satisfactoriamente. + + + Comando de inicio no encontrado. + + + Servidor + + + No hay comandos de inicio en esta página. + + + Reiniciados todos los comandos de inicio. + + + El usuario {0} ha sido desbloqueado. + + + No encuentro tal usuario. + + + El usuario {0} ha sido advertido. + + + El usuario {0} ha sido advertido y el castigo {0} ha sido aplicado. + + + Advertido en el servidor {0} + + + El {0} a las {1} por {2} + + + Todas las advertencias han sido reiniciadas por {0}. + + + No hay advertencias en esta página. + + + Registro de advertencias para {0} + + + No hay castigos configurados. + + + Reiniciados por {0} + + + Lista de castigos de advertencia + + + Tener {0} advertencias ya no ejecutará un castigo. + + + Aplicaré el castigo {0} a los usuarios con {1} advertecias. + + + El modo lento ahora ignorará el rol {0}. + + + El modo lento ya no ignorará el rol {0}. + + + El modo lento ignorará al usuario {0}. + + + El modo lento ya no ignorará al usuario {0}. + + + Imposible reclamar recompensas debido a una de las siguientes razones: + + + Tal vez ya has recibido tu recompensa de este mes. Puedes recibir recompensa solo una vez cada mes a menos que incrementes el monto. + + + Ya recompensado + + + Puede que tu cuenta de Discord no esté conectada a Patreon. Si no estás seguro de lo que significa, o no sabes cómo conectarla, tienes que ir a la página de configuración de Patreon (https://patreon.com/settings/account) y presionar el botón de 'conectar a Discord'. + + + Cuenta de Discord no conectada. + + + Para elegir una recompensa, debes apoyar el proyecto en Patreon. Puedes usar el comando {0} para obtener el enlace. + + + No apoyando + + + Tienes que esperar algunas horas después de hacer tu colaboración, sino, trata otra vez. + + + Espera un tiempo + + + Has recibido {0} ¡Gracias por apoyar el proyecto! + + + Las recompensas pueden ser reclamadas el día 5 de cada mes. + \ No newline at end of file From a0e855d2d0956aeddefc6eb636274d4bcc6c9f7a Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:47 +0200 Subject: [PATCH 50/98] Update ResponseStrings.sv-SE.resx (POEditor.com) --- .../Resources/ResponseStrings.sv-SE.resx | 138 +++++++++++++++++- 1 file changed, 131 insertions(+), 7 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.sv-SE.resx b/src/NadekoBot/Resources/ResponseStrings.sv-SE.resx index 6ee45f0f..8d392491 100644 --- a/src/NadekoBot/Resources/ResponseStrings.sv-SE.resx +++ b/src/NadekoBot/Resources/ResponseStrings.sv-SE.resx @@ -256,8 +256,7 @@ du kan inte attackera dig själv - -{0} har svimmat! + {0} har svimmat! helade {0} med en {1} @@ -765,7 +764,8 @@ Anledning: {1} mjukt-bannad (kickad) - PLURAL + PLURAL +Fuzzy {0} kommer ignorera denna kanal. @@ -2330,7 +2330,7 @@ Medlemmar: {1} Användare som går in i röstkanalen {0} får rollen {1}. - Användare som går + Användare som går med {0} röstkanalen kommer inte längre få en roll. Röstkanalsroller @@ -2342,11 +2342,10 @@ Medlemmar: {1} Meddelandet som triggrar den egengjorda reaktion med id {0} kommer bli - Svar meddelande för custom reaktion med id {0} kommer inte att skickas som ett DM. + Svar meddelande för den egengjorda reaktion med id {0} kommer inte att skickas som ett DM. - - + Svar meddelande för den egengjoda reaktion med id {0} kommer att skickas som ett DM. Ingen alias hittad @@ -2366,5 +2365,130 @@ Medlemmar: {1} Kompetitiv speltid + + Kanal + + + Kommando Text + + + Sparkad + PLURAL + + + Moderator + + + Sida {0} + + + Anledning + + + Ny uppstart kommando tillagd. + + + Uppstart kommando har blivit avtagen. + + + Uppstart kommando hittas inte. + + + Server + + + Ingen uppstart kommando har hittats på denna sidan. + + + Rensat alla uppstart kommando. + + + Användaren {0} har blivit icke avstängd. + + + Användaren hittades inte. + + + Användaren {0} har blivit varnad. + + + Användaren {0} har blivit varnad och {1} straff har blivit tillämpat. + + + Varning på {0} server + + + På {0} i {1} av {2} + + + Alla varningar har blivit rensad. + + + Inga varningar på denna sidan. + + + Varning log för {0} + + + Ingen straff ställt. + + + rensad av {0} + + + Varning straff lista + + + Har {0} varningar kommer inte längre aktivera ett straff. + + + Jag kommer att tillägga {0} straff till användare med {1} varningar. + + + Långsam läge kommer nu att bli ignorerad {0} roll. + + + Långsam läge kommer inte längre att bli ignorerad {0} roll. + + + Långsam läge kommer nu ignorera användaren {0} + + + Långsam läge kommer inte längre ignorera användaren {0} + + + Misslyckad anpråk av pris på grund av följande anledningar: + + + Du har kanske redan mottagit din pris för denna månaden. Du kan bara motta priser en gång per månad om inte du ökar din pledge. + + + Redan belönat + + + Din discord konto är kanske inte ansluten till Patreon. Om du inte är säker om vad det betyder, eller inte vet hur du skall ansluta det - du måse då gå till [Patreon account settings page] +(https://patreon.com/settings/account) och klicka på 'Connect to discord' knappen. + + + Discord konto är icke ansluten. + + + För att vara berättigad till priset så måste du stödja projektet på patreon. Du kan använda {0} kommandot för att få länken. + + + Ingen stöd + + + Du måste vänta några timmer efter din pledge, om du inte har gjort det, prova igen senare. + + + Vänta en stund + + + Du har mottagit {0} Tack för att du har stödjat projektet! + + + Pris kan bli hävdad på eller efter femte av varje månad. + \ No newline at end of file From 74d747279f084f8699eacd0ac6cdb2b07fc198d2 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:49 +0200 Subject: [PATCH 51/98] Update ResponseStrings.tr-TR.resx (POEditor.com) --- .../Resources/ResponseStrings.tr-TR.resx | 127 +++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.tr-TR.resx b/src/NadekoBot/Resources/ResponseStrings.tr-TR.resx index b63550e8..182ad0d4 100644 --- a/src/NadekoBot/Resources/ResponseStrings.tr-TR.resx +++ b/src/NadekoBot/Resources/ResponseStrings.tr-TR.resx @@ -741,7 +741,8 @@ Sebep: {1} Hafif bir şekilde yasaklandılar (atıldılar) - PLURAL + PLURAL +Fuzzy {0} bu kanalı yoksayacak. @@ -2281,5 +2282,129 @@ Kurucu Kimliği: {2} Rekabetçi oyun süresi + + Kanal + + + Kanal Mesajı + + + Atıldı + PLURAL + + + Moderatör + + + sayfa {0} + + + Sebep + + + Yeni başlangıç komutu eklendi. + + + Başlangıç komutu başarıyla kaldırıldı. + + + Başlangıç komutu bulunamadı. + + + Sunucu + + + Bu sayfada başlangıç komutları bulunmuyor. + + + Tüm başlangıç komutları temizlendi. + + + {0} kullanıcısının yasağı kaldırıldı. + + + Kullanıcı bulunamadı. + + + {0} kullanıcısı uyarıldı. + + + {0} kullanıcısı uyarıldı ve {1} cezası uygulandı. + + + {0} sunucusunda uyarıldı. + + + {0} - {1} tarihinde {2} tarafından + + + {0} için tüm uyarılar silindi. + + + Bu sayfada uyarı bulunamadı. + + + {0} için Uyarı Kayıtları + + + Hiç ceza belirlenmedi. + + + {0} tarafından temizlendi. + + + Uyarı ceza listesi + + + {0} uyarılarına sahip olmak artık cezayı tetiklemeyecektir. + + + {1} uyarılarıyla {0} cezasını kullanıcılara uygulayacağım. + + + Yavaş mod, artık {0} rolünü görmezden gelecektir. + + + Yavaş mod, artık {0} rolünü görmezden gelmeyecek. + + + Yavaş mod, artık {0} kullanıcısını yoksayacak. + + + Yavaş mod, {0} kullanıcısını artık görmezden gelmeyecek. + + + Aşağıdaki nedenlerden biriyle ödül talebinde bulunamadı: + + + Belki de bu ay için ödülünüzü zaten almışsınızdır. Bağış miktarınızı artırmadıkça, yalnızca ayda bir kez ödül alabilirsiniz. + + + Zaten ödüllendirildi + + + Discord hesabınız Patreon'a bağlı olmayabilir. Bunun ne anlama geldiğinden emin değilseniz veya nasıl bağlanacağınızı bilmiyorsanız - [Patreon hesap ayarları sayfasına] (https://patreon.com/settings/account) adresine gidin ve 'Bağlantı' butonuna tıklayın. + + + Discord hesabı bağlı değil + + + Ödül için uygun olabilmeniz için, projeyi patreon'da bağış yapmanız gerek. Bağlantıyı almak için {0} komutunu kullanabilirsiniz. + + + Desteklemiyor + + + Bağış yaptıktan sonra birkaç saat beklemek zorundasınız, yapmadıysanız, daha sonra tekrar deneyin. + + + Biraz bekleyin + + + {0} Projeyi desteklediğiniz için teşekkürlerimizi aldınız! + + + Ödüller, her ayın 5'inde veya sonrasında talep edilebilir. + \ No newline at end of file From 8927f9c1bee2d7dfa089dbacece37652448a36be Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 5 Apr 2017 12:19:52 +0200 Subject: [PATCH 52/98] Update ResponseStrings.id-ID.resx (POEditor.com) --- .../Resources/ResponseStrings.id-ID.resx | 362 ++++++++++++------ 1 file changed, 244 insertions(+), 118 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.id-ID.resx b/src/NadekoBot/Resources/ResponseStrings.id-ID.resx index d2f4e2d2..f6cad4b4 100644 --- a/src/NadekoBot/Resources/ResponseStrings.id-ID.resx +++ b/src/NadekoBot/Resources/ResponseStrings.id-ID.resx @@ -1,121 +1,121 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Markas itu telah diklaim atau dihancurkan. @@ -742,7 +742,8 @@ Alasan: {1} Ban halus (Dikeluarkan) - PLURAL + PLURAL +Fuzzy {0} akan mengabaikan channel ini. @@ -2281,5 +2282,130 @@ ID Pemilik: {2} Waktu bermain kompetitif + + Saluran + + + Teks perintah + + + Ditendang + PLURAL + + + Moderator + + + Halaman {0} + + + Alasan + + + Perintah startup ditambahkan. + + + Penghilangan perintah startup sukses. + + + Perintah startup tidak ditemukan. + + + Server + + + Tidak ada perintah startup dihalaman ini. + + + Membersihkan semua perintah startup. + + + Pengguna {0} telah dinonlarangkan. + + + Pengguna tidak ditemukan + + + Pengguna {0} telah diperingatkan. + + + Pengguna {0} telah diperingatkan dan hukuman {1} diberikan. + + + Diperingatkan di server {0} + + + Di {0} saat {1} oleh {2} + + + Semua peringatan telah dibersihkan untuk {0}. + + + Tidak ada peringatan dihalaman ini. + + + Berkas peringatan untuk {0} + + + Tidak ada hukuman ditetapkan. + + + Dibersihkan oleh {0} + + + Daftar peringatan hukum + + + Mempunyai {0} peringatan tidak akan memulai hukuman. + + + Saya akan menambahkan hukuman {0} untuk pengguna dengan {1} peringatan. + + + Slowmode akan mengabaikan peran {0}. + + + Slowmode tidak akan lagi mengabaikan peran {0} + + + Slowmode akan mengabaikan pengguna {0} + Fuzzy + + + Slowmode tidak akan lagi mengabaikan pengguna {0}. + + + Gagal untuk mengambil hadiah karena salah satu dari alasan ini: + + + Mungkin anda telah mendapatkan hadiah anda untuk bulan ini. Anda hanya bisa mendapatkan hadiah sekali sebulan kecuali anda menambahkan jumlah janji anda. + + + Telah dihadiahkan + + + Akun DIscord anda mungkin tidak terkoneksi ke Patreon. Jika anda tidak yakin artinya, atau tidak tahu cara menghubungkannya ` anda harus pergi ke [Halaman pengaturan akun Patreon] (https://patreon.com/settings/account) dan menekan tombol 'Connect to Discord'. + + + Akun Discord tidak terhubung + + + Untuk berhak mendapatkan hadiah, anda harus mendukung proyek di Patreon. + + + Tidak mendukung. + + + Anda harus menunggu beberapa jam setelah memohon, jika anda tidak, cobalah nanti lagi. + + + Tunggulah sebentar. + + + Anda telah menerima {0}. Terima kasih untuk mendukung proyek ini! + + + Hadiah bisa diambil saat atau setelah tanggal 5 dari setiap bulan. + \ No newline at end of file From 2869a60d6c9702b215450964a2f0d4bbf9e4636a Mon Sep 17 00:00:00 2001 From: snippet Date: Wed, 5 Apr 2017 23:04:37 +1000 Subject: [PATCH 53/98] Adds .rolehoist command --- docs/Commands List.md | 1 + .../Modules/Administration/Administration.cs | 12 +++++++++ .../Resources/CommandStrings.Designer.cs | 27 +++++++++++++++++++ src/NadekoBot/Resources/CommandStrings.resx | 9 +++++++ 4 files changed, 49 insertions(+) diff --git a/docs/Commands List.md b/docs/Commands List.md index 715df776..da4d922c 100644 --- a/docs/Commands List.md +++ b/docs/Commands List.md @@ -26,6 +26,7 @@ Commands and aliases | Description | Usage `.removeallroles` `.rar` | Removes all roles from a mentioned user. **Requires ManageRoles server permission.** | `.rar @User` `.createrole` `.cr` | Creates a role with a given name. **Requires ManageRoles server permission.** | `.cr Awesome Role` `.rolecolor` `.rc` | Set a role's color to the hex or 0-255 rgb color value provided. **Requires ManageRoles server permission.** | `.rc Admin 255 200 100` or `.rc Admin ffba55` +`.rolehoist` `.rh` | Set whether the role should be displayed separately in the sidebar **Requires ManageRoles server permission.** | `.rh Guests true` or `.rolehoist "Space Wizards" true` `.deafen` `.deaf` | Deafens mentioned user or users. **Requires DeafenMembers server permission.** | `.deaf "@Someguy"` or `.deaf "@Someguy" "@Someguy"` `.undeafen` `.undef` | Undeafens mentioned user or users. **Requires DeafenMembers server permission.** | `.undef "@Someguy"` or `.undef "@Someguy" "@Someguy"` `.delvoichanl` `.dvch` | Deletes a voice channel with a given name. **Requires ManageChannels server permission.** | `.dvch VoiceChannelName` diff --git a/src/NadekoBot/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs index 6ecefe10..5b0adfaa 100644 --- a/src/NadekoBot/Modules/Administration/Administration.cs +++ b/src/NadekoBot/Modules/Administration/Administration.cs @@ -196,6 +196,18 @@ namespace NadekoBot.Modules.Administration await ReplyConfirmLocalized("cr", Format.Bold(r.Name)).ConfigureAwait(false); } + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.ManageRoles)] + [RequireBotPermission(GuildPermission.ManageRoles)] + public async Task RoleHoist(string roleSearchName, bool targetState) + { + var roleName = roleSearchName.ToUpperInvariant(); + var role = Context.Guild.Roles.FirstOrDefault(r => r.Name.ToUpperInvariant() == roleName); + + await role.ModifyAsync(r => r.Hoist = targetState).ConfigureAwait(false); + } + [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [RequireUserPermission(GuildPermission.ManageRoles)] diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index d021e161..ef52ebd4 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -6593,6 +6593,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to rolehoist rh. + /// + public static string rolehoist_cmd { + get { + return ResourceManager.GetString("rolehoist_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Toggles if this role is displayed in the sidebar or not. + /// + public static string rolehoist_desc { + get { + return ResourceManager.GetString("rolehoist_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}rh Guests true` or `{0}rh "Space Wizards" true. + /// + public static string rolehoist_usage { + get { + return ResourceManager.GetString("rolehoist_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to rolemdl rm. /// diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 1a943af1..859f0043 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3366,4 +3366,13 @@ `{0}time London, UK` + + rolehoist rh + + + Toggles if this role is displayed in the sidebar or not + + + `{0}rh Guests true` or `{0}rh "Space Wizards" true + \ No newline at end of file From 80cb6e86c45ead7552002c49bbc967223833966e Mon Sep 17 00:00:00 2001 From: snippet Date: Wed, 5 Apr 2017 23:30:29 +1000 Subject: [PATCH 54/98] Adds response to .rh / .rolehoist Also swaps to PermissionAction from bool --- src/NadekoBot/Modules/Administration/Administration.cs | 6 ++++-- src/NadekoBot/Resources/ResponseStrings.Designer.cs | 9 +++++++++ src/NadekoBot/Resources/ResponseStrings.resx | 3 +++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/NadekoBot/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs index 5b0adfaa..fffac1f7 100644 --- a/src/NadekoBot/Modules/Administration/Administration.cs +++ b/src/NadekoBot/Modules/Administration/Administration.cs @@ -12,6 +12,7 @@ using NadekoBot.Services.Database.Models; using static NadekoBot.Modules.Permissions.Permissions; using System.Collections.Concurrent; using NLog; +using NadekoBot.Modules.Permissions; namespace NadekoBot.Modules.Administration { @@ -200,12 +201,13 @@ namespace NadekoBot.Modules.Administration [RequireContext(ContextType.Guild)] [RequireUserPermission(GuildPermission.ManageRoles)] [RequireBotPermission(GuildPermission.ManageRoles)] - public async Task RoleHoist(string roleSearchName, bool targetState) + public async Task RoleHoist(string roleSearchName, PermissionAction targetState) { var roleName = roleSearchName.ToUpperInvariant(); var role = Context.Guild.Roles.FirstOrDefault(r => r.Name.ToUpperInvariant() == roleName); - await role.ModifyAsync(r => r.Hoist = targetState).ConfigureAwait(false); + await role.ModifyAsync(r => r.Hoist = targetState.Value).ConfigureAwait(false); + await ReplyConfirmLocalized("rh", Format.Bold(role.Name), Format.Bold(targetState.Value.ToString())).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index f4171166..1836004a 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -1168,6 +1168,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Set the display of guild role {0} to {1}.. + /// + public static string administration_rh { + get { + return ResourceManager.GetString("administration_rh", resourceCulture); + } + } + /// /// Looks up a localized string similar to Role {0} as been added to the list.. /// diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 2a1d1e7f..e3de1903 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2406,4 +2406,7 @@ Owner ID: {2} Time in {0} is {1} - {2} Time in London, UK is 15:30 - Time Zone Name + + Set the display of guild role {0} to {1}. + \ No newline at end of file From b09cd7ea434ed52c19e92fbaa649323ea6265d3d Mon Sep 17 00:00:00 2001 From: Kwoth Date: Thu, 6 Apr 2017 19:48:21 +0200 Subject: [PATCH 55/98] patreon error fix --- src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs index 303774f4..924c720f 100644 --- a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs @@ -13,6 +13,7 @@ using NadekoBot.Services; using NadekoBot.Services.Database.Models; using NadekoBot.Extensions; using Discord; +using NLog; namespace NadekoBot.Modules.Utility { @@ -74,11 +75,13 @@ namespace NadekoBot.Modules.Utility private readonly Timer update; private readonly SemaphoreSlim claimLockJustInCase = new SemaphoreSlim(1, 1); + private readonly Logger _log; private PatreonThingy() { if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) return; + _log = LogManager.GetCurrentClassLogger(); update = new Timer(async (_) => await LoadPledges(), null, TimeSpan.Zero, TimeSpan.FromHours(3)); } @@ -119,6 +122,10 @@ namespace NadekoBot.Modules.Utility Reward = x, }).ToImmutableArray(); } + catch (Exception ex) + { + _log.Warn(ex); + } finally { var _ = Task.Run(async () => From 6efd78ca215656e040ff9db526ec47a841d20b70 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Thu, 6 Apr 2017 20:59:07 +0200 Subject: [PATCH 56/98] Patreon stuff improved --- .../Utility/Commands/PatreonCommands.cs | 20 ++++++++- src/NadekoBot/Resources/CommandStrings.resx | 41 +++++++++++++++++-- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs index 924c720f..583b1f5b 100644 --- a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs @@ -28,6 +28,16 @@ namespace NadekoBot.Modules.Utility { patreon = PatreonThingy.Instance; } + + [NadekoCommand, Usage, Description, Aliases] + [OwnerOnly] + public async Task PatreonRewardsReload() + { + await patreon.LoadPledges().ConfigureAwait(false); + + await Context.Channel.SendConfirmAsync("👌").ConfigureAwait(false); + } + [NadekoCommand, Usage, Description, Aliases] public async Task ClaimPatreonRewards() { @@ -53,13 +63,15 @@ namespace NadekoBot.Modules.Utility await ReplyConfirmLocalized("clpa_success", amount + NadekoBot.BotConfig.CurrencySign).ConfigureAwait(false); return; } + var rem = (patreon.Interval - (DateTime.UtcNow - patreon.LastUpdate)); var helpcmd = Format.Code(NadekoBot.ModulePrefixes[typeof(Help.Help).Name] + "donate"); await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() .WithDescription(GetText("clpa_fail")) .AddField(efb => efb.WithName(GetText("clpa_fail_already_title")).WithValue(GetText("clpa_fail_already"))) .AddField(efb => efb.WithName(GetText("clpa_fail_wait_title")).WithValue(GetText("clpa_fail_wait"))) .AddField(efb => efb.WithName(GetText("clpa_fail_conn_title")).WithValue(GetText("clpa_fail_conn"))) - .AddField(efb => efb.WithName(GetText("clpa_fail_sup_title")).WithValue(GetText("clpa_fail_sup", helpcmd)))) + .AddField(efb => efb.WithName(GetText("clpa_fail_sup_title")).WithValue(GetText("clpa_fail_sup", helpcmd))) + .WithFooter(efb => efb.WithText(GetText("clpa_next_update", rem)))) .ConfigureAwait(false); } } @@ -72,21 +84,25 @@ namespace NadekoBot.Modules.Utility private readonly SemaphoreSlim getPledgesLocker = new SemaphoreSlim(1, 1); public ImmutableArray Pledges { get; private set; } + public DateTime LastUpdate { get; private set; } = DateTime.UtcNow; private readonly Timer update; private readonly SemaphoreSlim claimLockJustInCase = new SemaphoreSlim(1, 1); private readonly Logger _log; + public readonly TimeSpan Interval = TimeSpan.FromHours(1); + private PatreonThingy() { if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) return; _log = LogManager.GetCurrentClassLogger(); - update = new Timer(async (_) => await LoadPledges(), null, TimeSpan.Zero, TimeSpan.FromHours(3)); + update = new Timer(async (_) => await LoadPledges(), null, TimeSpan.Zero, Interval); } public async Task LoadPledges() { + LastUpdate = DateTime.UtcNow; await getPledgesLocker.WaitAsync(1000).ConfigureAwait(false); try { diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 1a943af1..cb6958bb 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -2596,10 +2596,10 @@ listquotes liqu - `{0}liqu` or `{0}liqu 3` + Lists all quotes on the server ordered alphabetically. 15 Per page. - Lists all quotes on the server ordered alphabetically. 15 Per page. + `{0}liqu` or `{0}liqu 3` typedel @@ -3211,7 +3211,7 @@ Toggles whether the response message of the custom reaction will be sent as a direct message. - `{0}crad 44` + `{0}crdm 44` aliaslist cmdmaplist aliases @@ -3334,7 +3334,7 @@ clparew - Claim patreon rewards. If you're subscribed to bot owner's patreon you can user this command to claim your rewards - assuming bot owner did setup has their patreon key. + Claim patreon rewards. If you're subscribed to bot owner's patreon you can use this command to claim your rewards - assuming bot owner did setup has their patreon key. `{0}clparew` @@ -3366,4 +3366,37 @@ `{0}time London, UK` + + parewrel + + + Forces the update of the list of patrons who are eligible for the reward. + + + `{0}parewrel` + + + shopadd + + + Adds an item to the shop by specifying type price and name. + + + `{0}shopadd role 1000 Rich` + + + shoprem shoprm + + + Removes an item from the shop by its color. + + + shop + + + Lists this server's administrators' shop. Paginated. + + + `{0}shop` or `{0}shop 2` + \ No newline at end of file From 936ba264c97942c339f86b9f8a41ae3660e2254d Mon Sep 17 00:00:00 2001 From: Kwoth Date: Thu, 6 Apr 2017 21:00:46 +0200 Subject: [PATCH 57/98] A lot of work on flower shop --- .../DataStructures/IndexedCollection.cs | 128 ++ .../DataStructures/PermissionsCollection.cs | 103 +- .../20170405161814_flower-shop.Designer.cs | 1518 +++++++++++++++++ .../Migrations/20170405161814_flower-shop.cs | 79 + .../NadekoSqliteContextModelSnapshot.cs | 62 + .../Modules/Gambling/Commands/FlowerShop.cs | 170 ++ .../Resources/CommandStrings.Designer.cs | 107 +- .../Resources/ResponseStrings.Designer.cs | 63 + src/NadekoBot/Resources/ResponseStrings.resx | 22 + .../Services/Database/Models/GuildConfig.cs | 2 + .../Services/Database/Models/ShopEntry.cs | 41 + 11 files changed, 2207 insertions(+), 88 deletions(-) create mode 100644 src/NadekoBot/DataStructures/IndexedCollection.cs create mode 100644 src/NadekoBot/Migrations/20170405161814_flower-shop.Designer.cs create mode 100644 src/NadekoBot/Migrations/20170405161814_flower-shop.cs create mode 100644 src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs create mode 100644 src/NadekoBot/Services/Database/Models/ShopEntry.cs diff --git a/src/NadekoBot/DataStructures/IndexedCollection.cs b/src/NadekoBot/DataStructures/IndexedCollection.cs new file mode 100644 index 00000000..72b4f343 --- /dev/null +++ b/src/NadekoBot/DataStructures/IndexedCollection.cs @@ -0,0 +1,128 @@ +using NadekoBot.Services.Database.Models; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace NadekoBot.DataStructures +{ + public class IndexedCollection : IList where T : IIndexed + { + public List Source { get; } + private readonly object _locker = new object(); + + public IndexedCollection(IEnumerable source) + { + lock (_locker) + { + Source = source.OrderBy(x => x.Index).ToList(); + for (var i = 0; i < Source.Count; i++) + { + if (Source[i].Index != i) + Source[i].Index = i; + } + } + } + + public static implicit operator List(IndexedCollection x) => + x.Source; + + public IEnumerator GetEnumerator() => + Source.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => + Source.GetEnumerator(); + + public void Add(T item) + { + lock (_locker) + { + item.Index = Source.Count; + Source.Add(item); + } + } + + public virtual void Clear() + { + lock (_locker) + { + Source.Clear(); + } + } + + public bool Contains(T item) + { + lock (_locker) + { + return Source.Contains(item); + } + } + + public void CopyTo(T[] array, int arrayIndex) + { + lock (_locker) + { + Source.CopyTo(array, arrayIndex); + } + } + + public virtual bool Remove(T item) + { + bool removed; + lock (_locker) + { + if (removed = Source.Remove(item)) + { + for (int i = 0; i < Source.Count; i++) + { + // hm, no idea how ef works, so I don't want to set if it's not changed, + // maybe it will try to update db? + // But most likely it just compares old to new values, meh. + if (Source[i].Index != i) + Source[i].Index = i; + } + } + } + return removed; + } + + public int Count => Source.Count; + public bool IsReadOnly => false; + public int IndexOf(T item) => item.Index; + + public virtual void Insert(int index, T item) + { + lock (_locker) + { + Source.Insert(index, item); + for (int i = index; i < Source.Count; i++) + { + Source[i].Index = i; + } + } + } + + public virtual void RemoveAt(int index) + { + lock (_locker) + { + Source.RemoveAt(index); + for (int i = index; i < Source.Count; i++) + { + Source[i].Index = i; + } + } + } + + public virtual T this[int index] { + get { return Source[index]; } + set { + lock (_locker) + { + value.Index = index; + Source[index] = value; + } + } + } + } + +} diff --git a/src/NadekoBot/DataStructures/PermissionsCollection.cs b/src/NadekoBot/DataStructures/PermissionsCollection.cs index e7963e64..484c4f9d 100644 --- a/src/NadekoBot/DataStructures/PermissionsCollection.cs +++ b/src/NadekoBot/DataStructures/PermissionsCollection.cs @@ -6,132 +6,67 @@ using NadekoBot.Services.Database.Models; namespace NadekoBot.DataStructures { - public class PermissionsCollection : IList where T : IIndexed + public class PermissionsCollection : IndexedCollection where T : IIndexed { - public List Source { get; } - private readonly object _locker = new object(); - - public PermissionsCollection(IEnumerable source) + private readonly object _localLocker = new object(); + public PermissionsCollection(IEnumerable source) : base(source) { - lock (_locker) - { - Source = source.OrderBy(x => x.Index).ToList(); - for (var i = 0; i < Source.Count; i++) - { - if(Source[i].Index != i) - Source[i].Index = i; - } - } } public static implicit operator List(PermissionsCollection x) => x.Source; - public IEnumerator GetEnumerator() => - Source.GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() => - Source.GetEnumerator(); - - public void Add(T item) + public override void Clear() { - lock (_locker) - { - item.Index = Source.Count; - Source.Add(item); - } - } - - public void Clear() - { - lock (_locker) + lock (_localLocker) { var first = Source[0]; - Source.Clear(); + base.Clear(); Source[0] = first; } } - public bool Contains(T item) - { - lock (_locker) - { - return Source.Contains(item); - } - } - - public void CopyTo(T[] array, int arrayIndex) - { - lock (_locker) - { - Source.CopyTo(array, arrayIndex); - } - } - - public bool Remove(T item) + public override bool Remove(T item) { bool removed; - lock (_locker) + lock (_localLocker) { if(Source.IndexOf(item) == 0) throw new ArgumentException("You can't remove first permsission (allow all)"); - if (removed = Source.Remove(item)) - { - for (int i = 0; i < Source.Count; i++) - { - // hm, no idea how ef works, so I don't want to set if it's not changed, - // maybe it will try to update db? - // But most likely it just compares old to new values, meh. - if (Source[i].Index != i) - Source[i].Index = i; - } - } + removed = base.Remove(item); } return removed; } - public int Count => Source.Count; - public bool IsReadOnly => false; - public int IndexOf(T item) => item.Index; - - public void Insert(int index, T item) + public override void Insert(int index, T item) { - lock (_locker) + lock (_localLocker) { if(index == 0) // can't insert on first place. Last item is always allow all. throw new IndexOutOfRangeException(nameof(index)); - Source.Insert(index, item); - for (int i = index; i < Source.Count; i++) - { - Source[i].Index = i; - } + base.Insert(index, item); } } - public void RemoveAt(int index) + public override void RemoveAt(int index) { - lock (_locker) + lock (_localLocker) { if(index == 0) // you can't remove first permission (allow all) - throw new IndexOutOfRangeException(nameof(index)); + throw new IndexOutOfRangeException(nameof(index)); - Source.RemoveAt(index); - for (int i = index; i < Source.Count; i++) - { - Source[i].Index = i; - } + base.RemoveAt(index); } } - public T this[int index] { + public override T this[int index] { get { return Source[index]; } set { - lock (_locker) + lock (_localLocker) { if(index == 0) // can't set first element. It's always allow all throw new IndexOutOfRangeException(nameof(index)); - value.Index = index; - Source[index] = value; + base[index] = value; } } } diff --git a/src/NadekoBot/Migrations/20170405161814_flower-shop.Designer.cs b/src/NadekoBot/Migrations/20170405161814_flower-shop.Designer.cs new file mode 100644 index 00000000..5acf9f8e --- /dev/null +++ b/src/NadekoBot/Migrations/20170405161814_flower-shop.Designer.cs @@ -0,0 +1,1518 @@ +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("20170405161814_flower-shop")] + partial class flowershop + { + 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.RewardedUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AmountRewardedThisMonth"); + + b.Property("DateAdded"); + + b.Property("LastReward"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("RewardedUsers"); + }); + + 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.ShopEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AuthorId"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Index"); + + b.Property("Name"); + + b.Property("Price"); + + b.Property("RoleId"); + + b.Property("RoleName"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("ShopEntry"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("ShopEntryId"); + + b.Property("Text"); + + b.HasKey("Id"); + + b.HasIndex("ShopEntryId"); + + b.ToTable("ShopEntryItem"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("RoleId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("SlowmodeIgnoredRole"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("SlowmodeIgnoredUser"); + }); + + 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.ShopEntry", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("ShopEntries") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ShopEntry") + .WithMany("Items") + .HasForeignKey("ShopEntryId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("SlowmodeIgnoredRoles") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("SlowmodeIgnoredUsers") + .HasForeignKey("GuildConfigId"); + }); + + 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/20170405161814_flower-shop.cs b/src/NadekoBot/Migrations/20170405161814_flower-shop.cs new file mode 100644 index 00000000..7d0cde56 --- /dev/null +++ b/src/NadekoBot/Migrations/20170405161814_flower-shop.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace NadekoBot.Migrations +{ + public partial class flowershop : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "ShopEntry", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + AuthorId = table.Column(nullable: false), + DateAdded = table.Column(nullable: true), + GuildConfigId = table.Column(nullable: true), + Index = table.Column(nullable: false), + Name = table.Column(nullable: true), + Price = table.Column(nullable: false), + RoleId = table.Column(nullable: false), + RoleName = table.Column(nullable: true), + Type = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ShopEntry", x => x.Id); + table.ForeignKey( + name: "FK_ShopEntry_GuildConfigs_GuildConfigId", + column: x => x.GuildConfigId, + principalTable: "GuildConfigs", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "ShopEntryItem", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + DateAdded = table.Column(nullable: true), + ShopEntryId = table.Column(nullable: true), + Text = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ShopEntryItem", x => x.Id); + table.ForeignKey( + name: "FK_ShopEntryItem_ShopEntry_ShopEntryId", + column: x => x.ShopEntryId, + principalTable: "ShopEntry", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_ShopEntry_GuildConfigId", + table: "ShopEntry", + column: "GuildConfigId"); + + migrationBuilder.CreateIndex( + name: "IX_ShopEntryItem_ShopEntryId", + table: "ShopEntryItem", + column: "ShopEntryId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ShopEntryItem"); + + migrationBuilder.DropTable( + name: "ShopEntry"); + } + } +} diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index 303783e4..c255ba79 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -971,6 +971,54 @@ namespace NadekoBot.Migrations b.ToTable("SelfAssignableRoles"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AuthorId"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Index"); + + b.Property("Name"); + + b.Property("Price"); + + b.Property("RoleId"); + + b.Property("RoleName"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("ShopEntry"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("ShopEntryId"); + + b.Property("Text"); + + b.HasKey("Id"); + + b.HasIndex("ShopEntryId"); + + b.ToTable("ShopEntryItem"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => { b.Property("Id") @@ -1377,6 +1425,20 @@ namespace NadekoBot.Migrations .HasForeignKey("BotConfigId"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntry", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("ShopEntries") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ShopEntry") + .WithMany("Items") + .HasForeignKey("ShopEntryId"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => { b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") diff --git a/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs b/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs new file mode 100644 index 00000000..56be01ff --- /dev/null +++ b/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs @@ -0,0 +1,170 @@ +using Discord; +using Discord.Commands; +using Microsoft.EntityFrameworkCore; +using NadekoBot.Attributes; +using NadekoBot.DataStructures; +using NadekoBot.Extensions; +using NadekoBot.Services; +using NadekoBot.Services.Database; +using NadekoBot.Services.Database.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.Modules.Gambling +{ + public partial class Gambling + { + [Group] + public class FlowerShop : NadekoSubmodule + { + public enum Role { + Role + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task Shop(int page = 1) + { + if (page <= 0) + return; + page -= 1; + List entries; + using (var uow = DbHandler.UnitOfWork()) + { + entries = new IndexedCollection(uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.ShopEntries)).ShopEntries); + } + + await Context.Channel.SendPaginatedConfirmAsync(page + 1, (curPage) => + { + var theseEntries = entries.Skip((curPage - 1) * 9).Take(9); + + if (!theseEntries.Any()) + return new EmbedBuilder().WithErrorColor() + .WithDescription(GetText("shop_none")); + var embed = new EmbedBuilder().WithOkColor() + .WithTitle(GetText("shop", NadekoBot.BotConfig.CurrencySign)); + + for (int i = 0; i < entries.Count; i++) + { + var entry = entries[i]; + embed.AddField(efb => efb.WithName($"#{i + 1} - {entry.Price}{NadekoBot.BotConfig.CurrencySign}").WithValue(EntryToString(entry)).WithIsInline(true)); + } + return embed; + }, entries.Count / 9, true); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task Buy(int entryNumber) + { + var channel = (ITextChannel)Context.Channel; + + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.Administrator)] + public async Task ShopAdd(ShopEntryType type, int price, string name) + { + var entry = new ShopEntry() + { + Name = name, + Price = price, + Type = type, + AuthorId = Context.User.Id, + }; + using (var uow = DbHandler.UnitOfWork()) + { + var entries = new IndexedCollection(uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.ShopEntries)).ShopEntries); + entries.Add(entry); + uow.GuildConfigs.For(Context.Guild.Id, set => set).ShopEntries = entries; + uow.Complete(); + } + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() + .WithTitle(GetText("shop_item_add")) + .AddField(efb => efb.WithName(GetText("name")).WithValue(name).WithIsInline(true)) + .AddField(efb => efb.WithName(GetText("price")).WithValue(price.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName(GetText("type")).WithValue(type.ToString()).WithIsInline(true))); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.Administrator)] + public async Task ShopAdd(Role _, int price, [Remainder] IRole role) + { + var entry = new ShopEntry() + { + Name = "-", + Price = price, + Type = ShopEntryType.Role, + AuthorId = Context.User.Id, + RoleId = role.Id, + RoleName = role.Name + }; + using (var uow = DbHandler.UnitOfWork()) + { + var entries = new IndexedCollection(uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.ShopEntries)).ShopEntries); + entries.Add(entry); + uow.GuildConfigs.For(Context.Guild.Id, set => set).ShopEntries = entries; + uow.Complete(); + } + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() + .WithTitle(GetText("shop_item_add")) + .AddField(efb => efb.WithName(GetText("name")).WithValue(GetText("shop_role", Format.Bold(entry.RoleName))).WithIsInline(true)) + .AddField(efb => efb.WithName(GetText("price")).WithValue(price.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName(GetText("type")).WithValue("Role").WithIsInline(true))); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task ShopRemove(int index) + { + if (index < 0) + return; + ShopEntry removed; + using (var uow = DbHandler.UnitOfWork()) + { + var config = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.ShopEntries)); + var entries = new IndexedCollection(config.ShopEntries); + removed = entries.ElementAtOrDefault(index); + if (removed != null) + { + entries.Remove(removed); + + config.ShopEntries = entries; + uow.Complete(); + } + } + + if(removed == null) + await ReplyErrorLocalized("shop_rem_fail").ConfigureAwait(false); + else + await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() + .WithTitle(GetText("shop_item_add")) + .AddField(efb => efb.WithName(GetText("name")).WithValue(GetText("shop_role", Format.Bold(removed.RoleName))).WithIsInline(true)) + .AddField(efb => efb.WithName(GetText("price")).WithValue(removed.Price.ToString()).WithIsInline(true)) + .AddField(efb => efb.WithName(GetText("type")).WithValue(removed.Type.ToString()).WithIsInline(true))); + } + + public string EntryToString(ShopEntry entry) + { + if (entry.Type == ShopEntryType.Role) + { + return Format.Bold(entry.Name) + "\n" + GetText("shop_role", Format.Bold(entry.RoleName)); + } + else if (entry.Type == ShopEntryType.List) + { + + } + else if (entry.Type == ShopEntryType.Infinite_List) + { + + } + return ""; + } + } + } +} diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index d021e161..5729c282 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -1716,7 +1716,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to Claim patreon rewards. If you're subscribed to bot owner's patreon you can user this command to claim your rewards - assuming bot owner did setup has their patreon key.. + /// Looks up a localized string similar to Claim patreon rewards. If you're subscribed to bot owner's patreon you can use this command to claim your rewards - assuming bot owner did setup has their patreon key.. /// public static string claimpatreonrewards_desc { get { @@ -2103,7 +2103,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to `{0}crad 44`. + /// Looks up a localized string similar to `{0}crdm 44`. /// public static string crdm_usage { get { @@ -4173,7 +4173,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to `{0}liqu` or `{0}liqu 3`. + /// Looks up a localized string similar to Lists all quotes on the server ordered alphabetically. 15 Per page.. /// public static string listquotes_desc { get { @@ -4182,7 +4182,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to Lists all quotes on the server ordered alphabetically. 15 Per page.. + /// Looks up a localized string similar to `{0}liqu` or `{0}liqu 3`. /// public static string listquotes_usage { get { @@ -5297,6 +5297,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to parewrel. + /// + public static string patreonrewardsreload_cmd { + get { + return ResourceManager.GetString("patreonrewardsreload_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Forces the update of the list of patrons who are eligible for the reward.. + /// + public static string patreonrewardsreload_desc { + get { + return ResourceManager.GetString("patreonrewardsreload_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}parewrel`. + /// + public static string patreonrewardsreload_usage { + get { + return ResourceManager.GetString("patreonrewardsreload_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to pause p. /// @@ -7484,6 +7511,78 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to shop. + /// + public static string shop_cmd { + get { + return ResourceManager.GetString("shop_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lists this server's administrators' shop. Paginated.. + /// + public static string shop_desc { + get { + return ResourceManager.GetString("shop_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}shop` or `{0}shop 2`. + /// + public static string shop_usage { + get { + return ResourceManager.GetString("shop_usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to shopadd. + /// + public static string shopadd_cmd { + get { + return ResourceManager.GetString("shopadd_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Adds an item to the shop by specifying type price and name.. + /// + public static string shopadd_desc { + get { + return ResourceManager.GetString("shopadd_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}shopadd role 1000 Rich`. + /// + public static string shopadd_usage { + get { + return ResourceManager.GetString("shopadd_usage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to shoprem shoprm. + /// + public static string shopremove_cmd { + get { + return ResourceManager.GetString("shopremove_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Removes an item from the shop by its color.. + /// + public static string shopremove_desc { + get { + return ResourceManager.GetString("shopremove_desc", resourceCulture); + } + } + /// /// Looks up a localized string similar to shorten. /// diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index f4171166..c174661e 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -2755,6 +2755,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Name. + /// + public static string gambling_name { + get { + return ResourceManager.GetString("gambling_name", resourceCulture); + } + } + /// /// Looks up a localized string similar to No more cards in the deck.. /// @@ -2854,6 +2863,42 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Shop. + /// + public static string gambling_shop { + get { + return ResourceManager.GetString("gambling_shop", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Shop item added. + /// + public static string gambling_shop_item_add { + get { + return ResourceManager.GetString("gambling_shop_item_add", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No shop items found on this page.. + /// + public static string gambling_shop_none { + get { + return ResourceManager.GetString("gambling_shop_none", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You will get {0} role.. + /// + public static string gambling_shop_role { + get { + return ResourceManager.GetString("gambling_shop_role", resourceCulture); + } + } + /// /// Looks up a localized string similar to Bet. /// @@ -2972,6 +3017,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Type. + /// + public static string gambling_type { + get { + return ResourceManager.GetString("gambling_type", resourceCulture); + } + } + /// /// Looks up a localized string similar to your affinity is already set to that waifu or you're trying to remove your affinity while not having one.. /// @@ -6115,6 +6169,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Next update in {0}. + /// + public static string utility_clpa_next_update { + get { + return ResourceManager.GetString("utility_clpa_next_update", resourceCulture); + } + } + /// /// Looks up a localized string similar to You've received {0} Thanks for supporting the project!. /// diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 2a1d1e7f..b87bfe8d 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2406,4 +2406,26 @@ Owner ID: {2} Time in {0} is {1} - {2} Time in London, UK is 15:30 - Time Zone Name + + Name + + + Shop + + + Shop item added + + + No shop items found on this page. + + + You will get {0} role. + + + Type + + + Next update in {0} + Next update in 05:30 + \ No newline at end of file diff --git a/src/NadekoBot/Services/Database/Models/GuildConfig.cs b/src/NadekoBot/Services/Database/Models/GuildConfig.cs index aaf7addf..e5a2c8b6 100644 --- a/src/NadekoBot/Services/Database/Models/GuildConfig.cs +++ b/src/NadekoBot/Services/Database/Models/GuildConfig.cs @@ -76,6 +76,8 @@ namespace NadekoBot.Services.Database.Models public HashSet SlowmodeIgnoredUsers { get; set; } public HashSet SlowmodeIgnoredRoles { get; set; } + public List ShopEntries { get; set; } + //public List ProtectionIgnoredChannels { get; set; } = new List(); } diff --git a/src/NadekoBot/Services/Database/Models/ShopEntry.cs b/src/NadekoBot/Services/Database/Models/ShopEntry.cs new file mode 100644 index 00000000..ad46fc9c --- /dev/null +++ b/src/NadekoBot/Services/Database/Models/ShopEntry.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; + +namespace NadekoBot.Services.Database.Models +{ + public enum ShopEntryType + { + Role, + List, + Infinite_List, + } + + public class ShopEntry : DbEntity, IIndexed + { + public int Index { get; set; } + public int Price { get; set; } + public string Name { get; set; } + public ulong AuthorId { get; set; } + + public ShopEntryType Type { get; set; } + public string RoleName { get; set; } + public ulong RoleId { get; set; } + public List Items { get; set; } + } + + public class ShopEntryItem : DbEntity + { + public string Text { get; set; } + + public override bool Equals(object obj) + { + if (obj == null || GetType() != obj.GetType()) + { + return false; + } + return ((ShopEntryItem)obj).Text == Text; + } + + public override int GetHashCode() => + Text.GetHashCode(); + } +} From b3f6b4473b8eb156b12f4e242b2639db754e32ae Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 8 Apr 2017 17:47:32 +0200 Subject: [PATCH 58/98] Woops, shop item purchase fix --- src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs b/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs index dbb268d8..57a05e10 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs @@ -151,7 +151,7 @@ namespace NadekoBot.Modules.Gambling .AddField(efb => efb.WithName(GetText("name")).WithValue(entry.Name).WithIsInline(true))) .ConfigureAwait(false); - await CurrencyHandler.AddCurrencyAsync(Context.User.Id, + await CurrencyHandler.AddCurrencyAsync(entry.AuthorId, $"Shop error refund - {entry.Name}", GetProfitAmount(entry.Price)).ConfigureAwait(false); } From 57e9c62b11a50b3547caa9cdaa1ccf7c4322df60 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 8 Apr 2017 17:48:54 +0200 Subject: [PATCH 59/98] transaction Name fix --- src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs b/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs index 57a05e10..f04e7c65 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs @@ -152,7 +152,7 @@ namespace NadekoBot.Modules.Gambling .ConfigureAwait(false); await CurrencyHandler.AddCurrencyAsync(entry.AuthorId, - $"Shop error refund - {entry.Name}", + $"Shop sell item - {entry.Name}", GetProfitAmount(entry.Price)).ConfigureAwait(false); } catch From a89d00ff317cbcc01297f86eccd560f7adc20ed2 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 8 Apr 2017 21:03:07 +0200 Subject: [PATCH 60/98] .gvc added --- ...70408162851_game-voice-channel.Designer.cs | 1520 +++++++++++++++++ .../20170408162851_game-voice-channel.cs | 24 + .../NadekoSqliteContextModelSnapshot.cs | 2 + .../Commands/GameChannelCommands.cs | 131 ++ .../Modules/Gambling/Commands/FlowerShop.cs | 1 - src/NadekoBot/Modules/Music/Music.cs | 2 +- .../Resources/CommandStrings.Designer.cs | 29 +- src/NadekoBot/Resources/CommandStrings.resx | 11 +- .../Resources/ResponseStrings.Designer.cs | 27 + src/NadekoBot/Resources/ResponseStrings.resx | 9 + .../Services/Database/Models/GuildConfig.cs | 1 + 11 files changed, 1753 insertions(+), 4 deletions(-) create mode 100644 src/NadekoBot/Migrations/20170408162851_game-voice-channel.Designer.cs create mode 100644 src/NadekoBot/Migrations/20170408162851_game-voice-channel.cs create mode 100644 src/NadekoBot/Modules/Administration/Commands/GameChannelCommands.cs diff --git a/src/NadekoBot/Migrations/20170408162851_game-voice-channel.Designer.cs b/src/NadekoBot/Migrations/20170408162851_game-voice-channel.Designer.cs new file mode 100644 index 00000000..fa371c1d --- /dev/null +++ b/src/NadekoBot/Migrations/20170408162851_game-voice-channel.Designer.cs @@ -0,0 +1,1520 @@ +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("20170408162851_game-voice-channel")] + partial class gamevoicechannel + { + 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("GameVoiceChannel"); + + 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.RewardedUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AmountRewardedThisMonth"); + + b.Property("DateAdded"); + + b.Property("LastReward"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("RewardedUsers"); + }); + + 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.ShopEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AuthorId"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Index"); + + b.Property("Name"); + + b.Property("Price"); + + b.Property("RoleId"); + + b.Property("RoleName"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("ShopEntry"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("ShopEntryId"); + + b.Property("Text"); + + b.HasKey("Id"); + + b.HasIndex("ShopEntryId"); + + b.ToTable("ShopEntryItem"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("RoleId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("SlowmodeIgnoredRole"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("SlowmodeIgnoredUser"); + }); + + 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.ShopEntry", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("ShopEntries") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ShopEntry") + .WithMany("Items") + .HasForeignKey("ShopEntryId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("SlowmodeIgnoredRoles") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("SlowmodeIgnoredUsers") + .HasForeignKey("GuildConfigId"); + }); + + 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/20170408162851_game-voice-channel.cs b/src/NadekoBot/Migrations/20170408162851_game-voice-channel.cs new file mode 100644 index 00000000..3b9cb6c6 --- /dev/null +++ b/src/NadekoBot/Migrations/20170408162851_game-voice-channel.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace NadekoBot.Migrations +{ + public partial class gamevoicechannel : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "GameVoiceChannel", + table: "GuildConfigs", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "GameVoiceChannel", + table: "GuildConfigs"); + } + } +} diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index c255ba79..a8e43d26 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -533,6 +533,8 @@ namespace NadekoBot.Migrations b.Property("FilterWords"); + b.Property("GameVoiceChannel"); + b.Property("GreetMessageChannelId"); b.Property("GuildId"); diff --git a/src/NadekoBot/Modules/Administration/Commands/GameChannelCommands.cs b/src/NadekoBot/Modules/Administration/Commands/GameChannelCommands.cs new file mode 100644 index 00000000..f2e5fb6c --- /dev/null +++ b/src/NadekoBot/Modules/Administration/Commands/GameChannelCommands.cs @@ -0,0 +1,131 @@ +using Discord; +using Discord.Commands; +using Microsoft.EntityFrameworkCore; +using NadekoBot.Attributes; +using NadekoBot.Services; +using NadekoBot.Services.Database; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Discord.WebSocket; +using NLog; +using NadekoBot.Extensions; + +namespace NadekoBot.Modules.Administration +{ + public partial class Administration + { + [Group] + public class GameChannelCommands : NadekoSubmodule + { + private static readonly Timer _t; + + private static readonly ConcurrentHashSet gameVoiceChannels = new ConcurrentHashSet(); + + private static new readonly Logger _log; + + static GameChannelCommands() + { + //_t = new Timer(_ => { + + //}, null, ); + + _log = LogManager.GetCurrentClassLogger(); + + gameVoiceChannels = new ConcurrentHashSet( + NadekoBot.AllGuildConfigs.Where(gc => gc.GameVoiceChannel != null) + .Select(gc => gc.GameVoiceChannel.Value)); + + NadekoBot.Client.UserVoiceStateUpdated += Client_UserVoiceStateUpdated; + + } + + private static Task Client_UserVoiceStateUpdated(SocketUser usr, SocketVoiceState oldState, SocketVoiceState newState) + { + var _ = Task.Run(async () => + { + try + { + var gUser = usr as SocketGuildUser; + if (gUser == null) + return; + + var game = gUser.Game?.Name.TrimTo(50).ToLowerInvariant(); + + if (oldState.VoiceChannel == newState.VoiceChannel || + newState.VoiceChannel == null) + return; + + if (!gameVoiceChannels.Contains(newState.VoiceChannel.Id) || + string.IsNullOrWhiteSpace(game)) + return; + + var vch = gUser.Guild.VoiceChannels + .FirstOrDefault(x => x.Name.ToLowerInvariant() == game); + + if (vch == null) + return; + + await Task.Delay(1000).ConfigureAwait(false); + await gUser.ModifyAsync(gu => gu.Channel = vch).ConfigureAwait(false); + } + catch (Exception ex) + { + _log.Warn(ex); + } + }); + + return Task.CompletedTask; + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequireUserPermission(GuildPermission.Administrator)] + [RequireBotPermission(GuildPermission.MoveMembers)] + public async Task GameVoiceChannel() + { + var vch = ((IGuildUser)Context.User).VoiceChannel; + + if (vch == null) + { + await ReplyErrorLocalized("not_in_voice").ConfigureAwait(false); + return; + } + ulong? id; + using (var uow = DbHandler.UnitOfWork()) + { + var gc = uow.GuildConfigs.For(Context.Guild.Id, set => set); + + if (gc.GameVoiceChannel == vch.Id) + { + gameVoiceChannels.TryRemove(vch.Id); + id = gc.GameVoiceChannel = null; + } + else + { + if(gc.GameVoiceChannel != null) + gameVoiceChannels.TryRemove(gc.GameVoiceChannel.Value); + gameVoiceChannels.Add(vch.Id); + id = gc.GameVoiceChannel = vch.Id; + } + + uow.Complete(); + } + + if (id == null) + { + await ReplyConfirmLocalized("gvc_disabled").ConfigureAwait(false); + } + else + { + gameVoiceChannels.Add(vch.Id); + await ReplyConfirmLocalized("gvc_enabled", Format.Bold(vch.Name)).ConfigureAwait(false); + } + } + } + } +} diff --git a/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs b/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs index f04e7c65..4fab3906 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/FlowerShop.cs @@ -140,7 +140,6 @@ namespace NadekoBot.Modules.Gambling removed = uow.Complete(); } - _log.Warn($"Removed {removed} items"); try { await (await Context.User.CreateDMChannelAsync()) diff --git a/src/NadekoBot/Modules/Music/Music.cs b/src/NadekoBot/Modules/Music/Music.cs index 315ddb52..d6484011 100644 --- a/src/NadekoBot/Modules/Music/Music.cs +++ b/src/NadekoBot/Modules/Music/Music.cs @@ -20,7 +20,7 @@ namespace NadekoBot.Modules.Music { [NadekoModule("Music", "!!")] [DontAutoLoad] - public class Music : NadekoTopLevelModule + public class Music : NadekoTopLevelModule { public static ConcurrentDictionary MusicPlayers { get; } = new ConcurrentDictionary(); diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index ff0aa011..256ff9fe 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -3002,6 +3002,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to gvc. + /// + public static string gamevoicechannel_cmd { + get { + return ResourceManager.GetString("gamevoicechannel_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Toggles game voice channel feature in the voice channel you're currently in. Users who join the game voice channel will get automatically redirected to the voice channel with the name of their current game if it exists. Can't move users to channels that the bot has no connect permission for. One per server.. + /// + public static string gamevoicechannel_desc { + get { + return ResourceManager.GetString("gamevoicechannel_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}gvc`. + /// + public static string gamevoicechannel_usage { + get { + return ResourceManager.GetString("gamevoicechannel_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to gelbooru. /// @@ -7629,7 +7656,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to Adds an item to the list of items for sale in the shop entry given the index.. + /// Looks up a localized string similar to Adds an item to the list of items for sale in the shop entry given the index. You usually want to run this command in the secret channel, so that the unique items are not leaked.. /// public static string shoplistadd_desc { get { diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 363b09af..a0a397a6 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3417,11 +3417,20 @@ `{0}buy 2` + + gvc + + + Toggles game voice channel feature in the voice channel you're currently in. Users who join the game voice channel will get automatically redirected to the voice channel with the name of their current game if it exists. Can't move users to channels that the bot has no connect permission for. One per server. + + + `{0}gvc` + shoplistadd - Adds an item to the list of items for sale in the shop entry given the index. + Adds an item to the list of items for sale in the shop entry given the index. You usually want to run this command in the secret channel, so that the unique items are not leaked. `{0}shoplistadd 1 Uni-que-Steam-Key` diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index 52a31610..1d0d3075 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -519,6 +519,24 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Game Voice Channel feature has been disabled on this server.. + /// + public static string administration_gvc_disabled { + get { + return ResourceManager.GetString("administration_gvc_disabled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} is a Game Voice Channel now.. + /// + public static string administration_gvc_enabled { + get { + return ResourceManager.GetString("administration_gvc_enabled", resourceCulture); + } + } + /// /// Looks up a localized string similar to You can't use this command on users with a role higher or equal to yours in the role hierarchy.. /// @@ -916,6 +934,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to You are not in voice channel on this server.. + /// + public static string administration_not_in_voice { + get { + return ResourceManager.GetString("administration_not_in_voice", resourceCulture); + } + } + /// /// Looks up a localized string similar to Old message. /// diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 8b8ed781..4831a40f 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2431,6 +2431,15 @@ Owner ID: {2} Next update in {0} Next update in 05:30 + + Game Voice Channel feature has been disabled on this server. + + + {0} is a Game Voice Channel now. + + + You are not in voice channel on this server. + Item diff --git a/src/NadekoBot/Services/Database/Models/GuildConfig.cs b/src/NadekoBot/Services/Database/Models/GuildConfig.cs index e5a2c8b6..7d0ef6d2 100644 --- a/src/NadekoBot/Services/Database/Models/GuildConfig.cs +++ b/src/NadekoBot/Services/Database/Models/GuildConfig.cs @@ -77,6 +77,7 @@ namespace NadekoBot.Services.Database.Models public HashSet SlowmodeIgnoredRoles { get; set; } public List ShopEntries { get; set; } + public ulong? GameVoiceChannel { get; set; } = null; //public List ProtectionIgnoredChannels { get; set; } = new List(); } From 98c330d6a62fc3a9b2bb4d45b655150db46b404c Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sun, 9 Apr 2017 22:28:42 +0200 Subject: [PATCH 61/98] ;gmod, ;cmd, ;lgp and .resetglobalperms added. Bot owner can disable modules or commands bot-wide. --- .../20170409193757_gmod-and-cmod.Designer.cs | 1553 +++++++++++++++++ .../20170409193757_gmod-and-cmod.cs | 56 + .../NadekoSqliteContextModelSnapshot.cs | 33 + .../Modules/Administration/Administration.cs | 17 + .../Commands/GameChannelCommands.cs | 2 +- .../Commands/GlobalPermissionCommands.cs | 118 ++ .../Utility/Commands/CommandMapCommands.cs | 6 +- .../Commands/CrossServerTextChannel.cs | 68 +- .../Utility/Commands/MessageRepeater.cs | 21 +- .../Utility/Commands/PatreonCommands.cs | 9 +- .../Modules/Utility/Commands/Remind.cs | 19 +- .../Utility/Commands/UnitConversion.cs | 9 +- src/NadekoBot/Modules/Utility/Utility.cs | 9 +- .../Resources/CommandStrings.Designer.cs | 110 +- src/NadekoBot/Resources/CommandStrings.resx | 38 +- .../Resources/ResponseStrings.Designer.cs | 72 + src/NadekoBot/Resources/ResponseStrings.resx | 24 + src/NadekoBot/Services/CommandHandler.cs | 25 +- .../Services/Database/Models/BotConfig.cs | 19 + .../Repositories/Impl/BotConfigRepository.cs | 2 + 20 files changed, 2157 insertions(+), 53 deletions(-) create mode 100644 src/NadekoBot/Migrations/20170409193757_gmod-and-cmod.Designer.cs create mode 100644 src/NadekoBot/Migrations/20170409193757_gmod-and-cmod.cs create mode 100644 src/NadekoBot/Modules/Permissions/Commands/GlobalPermissionCommands.cs diff --git a/src/NadekoBot/Migrations/20170409193757_gmod-and-cmod.Designer.cs b/src/NadekoBot/Migrations/20170409193757_gmod-and-cmod.Designer.cs new file mode 100644 index 00000000..fe9da269 --- /dev/null +++ b/src/NadekoBot/Migrations/20170409193757_gmod-and-cmod.Designer.cs @@ -0,0 +1,1553 @@ +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("20170409193757_gmod-and-cmod")] + partial class gmodandcmod + { + 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.BlockedCmdOrMdl", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("BotConfigId1"); + + b.Property("DateAdded"); + + b.Property("Name"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.HasIndex("BotConfigId1"); + + b.ToTable("BlockedCmdOrMdl"); + }); + + 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("GameVoiceChannel"); + + 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.RewardedUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AmountRewardedThisMonth"); + + b.Property("DateAdded"); + + b.Property("LastReward"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("RewardedUsers"); + }); + + 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.ShopEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AuthorId"); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("Index"); + + b.Property("Name"); + + b.Property("Price"); + + b.Property("RoleId"); + + b.Property("RoleName"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("ShopEntry"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("ShopEntryId"); + + b.Property("Text"); + + b.HasKey("Id"); + + b.HasIndex("ShopEntryId"); + + b.ToTable("ShopEntryItem"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("RoleId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("SlowmodeIgnoredRole"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DateAdded"); + + b.Property("GuildConfigId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("SlowmodeIgnoredUser"); + }); + + 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.BlockedCmdOrMdl", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("BlockedCommands") + .HasForeignKey("BotConfigId"); + + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("BlockedModules") + .HasForeignKey("BotConfigId1"); + }); + + 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.ShopEntry", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("ShopEntries") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ShopEntry") + .WithMany("Items") + .HasForeignKey("ShopEntryId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("SlowmodeIgnoredRoles") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("SlowmodeIgnoredUsers") + .HasForeignKey("GuildConfigId"); + }); + + 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/20170409193757_gmod-and-cmod.cs b/src/NadekoBot/Migrations/20170409193757_gmod-and-cmod.cs new file mode 100644 index 00000000..5cef1a06 --- /dev/null +++ b/src/NadekoBot/Migrations/20170409193757_gmod-and-cmod.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace NadekoBot.Migrations +{ + public partial class gmodandcmod : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "BlockedCmdOrMdl", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + BotConfigId = table.Column(nullable: true), + BotConfigId1 = table.Column(nullable: true), + DateAdded = table.Column(nullable: true), + Name = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_BlockedCmdOrMdl", x => x.Id); + table.ForeignKey( + name: "FK_BlockedCmdOrMdl_BotConfig_BotConfigId", + column: x => x.BotConfigId, + principalTable: "BotConfig", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_BlockedCmdOrMdl_BotConfig_BotConfigId1", + column: x => x.BotConfigId1, + principalTable: "BotConfig", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_BlockedCmdOrMdl_BotConfigId", + table: "BlockedCmdOrMdl", + column: "BotConfigId"); + + migrationBuilder.CreateIndex( + name: "IX_BlockedCmdOrMdl_BotConfigId1", + table: "BlockedCmdOrMdl", + column: "BotConfigId1"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "BlockedCmdOrMdl"); + } + } +} diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index a8e43d26..2e1fd50c 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -99,6 +99,28 @@ namespace NadekoBot.Migrations b.ToTable("BlacklistItem"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.BlockedCmdOrMdl", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("BotConfigId1"); + + b.Property("DateAdded"); + + b.Property("Name"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.HasIndex("BotConfigId1"); + + b.ToTable("BlockedCmdOrMdl"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.BotConfig", b => { b.Property("Id") @@ -1277,6 +1299,17 @@ namespace NadekoBot.Migrations .HasForeignKey("BotConfigId"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.BlockedCmdOrMdl", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("BlockedCommands") + .HasForeignKey("BotConfigId"); + + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("BlockedModules") + .HasForeignKey("BotConfigId1"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => { b.HasOne("NadekoBot.Services.Database.Models.ClashWar", "ClashWar") diff --git a/src/NadekoBot/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs index fffac1f7..71f20464 100644 --- a/src/NadekoBot/Modules/Administration/Administration.cs +++ b/src/NadekoBot/Modules/Administration/Administration.cs @@ -67,6 +67,23 @@ namespace NadekoBot.Modules.Administration await ReplyConfirmLocalized("perms_reset").ConfigureAwait(false); } + [NadekoCommand, Usage, Description, Aliases] + [OwnerOnly] + public async Task ResetGlobalPermissions() + { + using (var uow = DbHandler.UnitOfWork()) + { + var gc = uow.BotConfig.GetOrCreate(); + gc.BlockedCommands.Clear(); + gc.BlockedModules.Clear(); + + GlobalPermissionCommands.BlockedCommands.Clear(); + GlobalPermissionCommands.BlockedModules.Clear(); + await uow.CompleteAsync(); + } + await ReplyConfirmLocalized("global_perms_reset").ConfigureAwait(false); + } + [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [RequireUserPermission(GuildPermission.Administrator)] diff --git a/src/NadekoBot/Modules/Administration/Commands/GameChannelCommands.cs b/src/NadekoBot/Modules/Administration/Commands/GameChannelCommands.cs index f2e5fb6c..0e557b40 100644 --- a/src/NadekoBot/Modules/Administration/Commands/GameChannelCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/GameChannelCommands.cs @@ -22,7 +22,7 @@ namespace NadekoBot.Modules.Administration [Group] public class GameChannelCommands : NadekoSubmodule { - private static readonly Timer _t; + //private static readonly Timer _t; private static readonly ConcurrentHashSet gameVoiceChannels = new ConcurrentHashSet(); diff --git a/src/NadekoBot/Modules/Permissions/Commands/GlobalPermissionCommands.cs b/src/NadekoBot/Modules/Permissions/Commands/GlobalPermissionCommands.cs new file mode 100644 index 00000000..41ba61b3 --- /dev/null +++ b/src/NadekoBot/Modules/Permissions/Commands/GlobalPermissionCommands.cs @@ -0,0 +1,118 @@ +using Discord; +using Discord.Commands; +using NadekoBot.Attributes; +using NadekoBot.DataStructures; +using NadekoBot.Extensions; +using NadekoBot.Services; +using NadekoBot.Services.Database; +using NadekoBot.TypeReaders; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.Modules.Permissions +{ + public partial class Permissions + { + [Group] + public class GlobalPermissionCommands : NadekoSubmodule + { + public static readonly ConcurrentHashSet BlockedModules; + public static readonly ConcurrentHashSet BlockedCommands; + + static GlobalPermissionCommands() + { + BlockedModules = new ConcurrentHashSet(NadekoBot.BotConfig.BlockedModules.Select(x => x.Name)); + BlockedCommands = new ConcurrentHashSet(NadekoBot.BotConfig.BlockedCommands.Select(x => x.Name)); + } + + [NadekoCommand, Usage, Description, Aliases] + [OwnerOnly] + public async Task Lgp() + { + if (!BlockedModules.Any() && !BlockedCommands.Any()) + { + await ReplyErrorLocalized("lgp_none").ConfigureAwait(false); + return; + } + + var embed = new EmbedBuilder().WithOkColor(); + + if (BlockedModules.Any()) + embed.AddField(efb => efb.WithName(GetText("blocked_modules")).WithValue(string.Join("\n", BlockedModules)).WithIsInline(false)); + + if (BlockedCommands.Any()) + embed.AddField(efb => efb.WithName(GetText("blocked_commands")).WithValue(string.Join("\n", BlockedCommands)).WithIsInline(false)); + + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [OwnerOnly] + public async Task Gmod(ModuleInfo module) + { + var moduleName = module.Name.ToLowerInvariant(); + if (BlockedModules.Add(moduleName)) + { + using (var uow = DbHandler.UnitOfWork()) + { + var bc = uow.BotConfig.GetOrCreate(); + bc.BlockedModules.Add(new Services.Database.Models.BlockedCmdOrMdl + { + Name = moduleName, + }); + uow.Complete(); + } + await ReplyConfirmLocalized("gmod_add", Format.Bold(module.Name)).ConfigureAwait(false); + return; + } + else if (BlockedModules.TryRemove(moduleName)) + { + using (var uow = DbHandler.UnitOfWork()) + { + var bc = uow.BotConfig.GetOrCreate(); + bc.BlockedModules.RemoveWhere(x => x.Name == moduleName); + uow.Complete(); + } + await ReplyConfirmLocalized("gmod_remove", Format.Bold(module.Name)).ConfigureAwait(false); + return; + } + } + + [NadekoCommand, Usage, Description, Aliases] + [OwnerOnly] + public async Task Gcmd(CommandOrCrInfo cmd) + { + var commandName = cmd.Name.ToLowerInvariant(); + if (BlockedCommands.Add(commandName)) + { + using (var uow = DbHandler.UnitOfWork()) + { + var bc = uow.BotConfig.GetOrCreate(); + bc.BlockedCommands.Add(new Services.Database.Models.BlockedCmdOrMdl + { + Name = commandName, + }); + uow.Complete(); + } + await ReplyConfirmLocalized("gcmd_add", Format.Bold(cmd.Name)).ConfigureAwait(false); + return; + } + else if (BlockedCommands.TryRemove(commandName)) + { + using (var uow = DbHandler.UnitOfWork()) + { + var bc = uow.BotConfig.GetOrCreate(); + bc.BlockedCommands.RemoveWhere(x => x.Name == commandName); + uow.Complete(); + } + await ReplyConfirmLocalized("gcmd_remove", Format.Bold(cmd.Name)).ConfigureAwait(false); + return; + } + } + } + } +} diff --git a/src/NadekoBot/Modules/Utility/Commands/CommandMapCommands.cs b/src/NadekoBot/Modules/Utility/Commands/CommandMapCommands.cs index 51fa03d1..11eb5017 100644 --- a/src/NadekoBot/Modules/Utility/Commands/CommandMapCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/CommandMapCommands.cs @@ -16,7 +16,6 @@ namespace NadekoBot.Modules.Utility { public partial class Utility { - public class CommandAliasEqualityComparer : IEqualityComparer { public bool Equals(CommandAlias x, CommandAlias y) => x.Trigger == y.Trigger; @@ -41,6 +40,11 @@ namespace NadekoBot.Modules.Utility .ToDictionary(ca => ca.Trigger, ca => ca.Mapping)))); } + public static void Unload() + { + AliasMaps.Clear(); + } + [NadekoCommand, Usage, Description, Aliases] [RequireUserPermission(GuildPermission.Administrator)] [RequireContext(ContextType.Guild)] diff --git a/src/NadekoBot/Modules/Utility/Commands/CrossServerTextChannel.cs b/src/NadekoBot/Modules/Utility/Commands/CrossServerTextChannel.cs index 45318177..0f1a78b5 100644 --- a/src/NadekoBot/Modules/Utility/Commands/CrossServerTextChannel.cs +++ b/src/NadekoBot/Modules/Utility/Commands/CrossServerTextChannel.cs @@ -3,6 +3,7 @@ using Discord.Commands; using NadekoBot.Attributes; using NadekoBot.Extensions; using NadekoBot.Services; +using System; using System.Collections.Concurrent; using System.Linq; using System.Threading.Tasks; @@ -16,43 +17,50 @@ namespace NadekoBot.Modules.Utility { static CrossServerTextChannel() { - NadekoBot.Client.MessageReceived += async imsg => + NadekoBot.Client.MessageReceived += Client_MessageReceived; + } + + public static void Unload() + { + NadekoBot.Client.MessageReceived -= Client_MessageReceived; + } + + private static async Task Client_MessageReceived(Discord.WebSocket.SocketMessage imsg) + { + try { - try + if (imsg.Author.IsBot) + return; + var msg = imsg as IUserMessage; + if (msg == null) + return; + var channel = imsg.Channel as ITextChannel; + if (channel == null) + return; + if (msg.Author.Id == NadekoBot.Client.CurrentUser.Id) return; + foreach (var subscriber in Subscribers) { - if (imsg.Author.IsBot) - return; - var msg = imsg as IUserMessage; - if (msg == null) - return; - var channel = imsg.Channel as ITextChannel; - if (channel == null) - return; - if (msg.Author.Id == NadekoBot.Client.CurrentUser.Id) return; - foreach (var subscriber in Subscribers) + var set = subscriber.Value; + if (!set.Contains(channel)) + continue; + foreach (var chan in set.Except(new[] { channel })) { - var set = subscriber.Value; - if (!set.Contains(channel)) - continue; - foreach (var chan in set.Except(new[] {channel})) + try { - try - { - await chan.SendMessageAsync(GetMessage(channel, (IGuildUser) msg.Author, - msg)).ConfigureAwait(false); - } - catch - { - // ignored - } + await chan.SendMessageAsync(GetMessage(channel, (IGuildUser)msg.Author, + msg)).ConfigureAwait(false); + } + catch + { + // ignored } } } - catch - { - // ignored - } - }; + } + catch + { + // ignored + } } private static string GetMessage(ITextChannel channel, IGuildUser user, IUserMessage message) => diff --git a/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs b/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs index 58752c28..4b40b98b 100644 --- a/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs +++ b/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs @@ -48,7 +48,6 @@ namespace NadekoBot.Modules.Utility Task.Run(Run); } - private async Task Run() { source = new CancellationTokenSource(); @@ -124,7 +123,12 @@ namespace NadekoBot.Modules.Utility { var _ = Task.Run(async () => { +#if !GLOBAL_NADEKO await Task.Delay(5000).ConfigureAwait(false); +#else + await Task.Delay(30000).ConfigureAwait(false); +#endif + //todo this is pretty terrible Repeaters = new ConcurrentDictionary>(NadekoBot.AllGuildConfigs .ToDictionary(gc => gc.GuildId, gc => new ConcurrentQueue(gc.GuildRepeaters @@ -134,6 +138,21 @@ namespace NadekoBot.Modules.Utility }); } + public static void Unload() + { + _ready = false; + foreach (var kvp in Repeaters) + { + RepeatRunner r; + while (kvp.Value.TryDequeue(out r)) + { + r.Stop(); + } + } + + Repeaters.Clear(); + } + [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [RequireUserPermission(GuildPermission.ManageMessages)] diff --git a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs index 583b1f5b..618fb588 100644 --- a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs @@ -29,6 +29,11 @@ namespace NadekoBot.Modules.Utility patreon = PatreonThingy.Instance; } + public static void Unload() + { + patreon.Updater.Change(Timeout.Infinite, Timeout.Infinite); + } + [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] public async Task PatreonRewardsReload() @@ -86,7 +91,7 @@ namespace NadekoBot.Modules.Utility public ImmutableArray Pledges { get; private set; } public DateTime LastUpdate { get; private set; } = DateTime.UtcNow; - private readonly Timer update; + public readonly Timer Updater; private readonly SemaphoreSlim claimLockJustInCase = new SemaphoreSlim(1, 1); private readonly Logger _log; @@ -97,7 +102,7 @@ namespace NadekoBot.Modules.Utility if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) return; _log = LogManager.GetCurrentClassLogger(); - update = new Timer(async (_) => await LoadPledges(), null, TimeSpan.Zero, Interval); + Updater = new Timer(async (_) => await LoadPledges(), null, TimeSpan.Zero, Interval); } public async Task LoadPledges() diff --git a/src/NadekoBot/Modules/Utility/Commands/Remind.cs b/src/NadekoBot/Modules/Utility/Commands/Remind.cs index 8d490563..8da05b89 100644 --- a/src/NadekoBot/Modules/Utility/Commands/Remind.cs +++ b/src/NadekoBot/Modules/Utility/Commands/Remind.cs @@ -32,10 +32,15 @@ namespace NadekoBot.Modules.Utility }; private new static readonly Logger _log; + private static readonly CancellationTokenSource cancelSource; + private static readonly CancellationToken cancelAllToken; static RemindCommands() { _log = LogManager.GetCurrentClassLogger(); + + cancelSource = new CancellationTokenSource(); + cancelAllToken = cancelSource.Token; List reminders; using (var uow = DbHandler.UnitOfWork()) { @@ -45,11 +50,17 @@ namespace NadekoBot.Modules.Utility foreach (var r in reminders) { - Task.Run(() => StartReminder(r)); + Task.Run(() => StartReminder(r, cancelAllToken)); } } - private static async Task StartReminder(Reminder r) + public static void Unload() + { + if (!cancelSource.IsCancellationRequested) + cancelSource.Cancel(); + } + + private static async Task StartReminder(Reminder r, CancellationToken t) { var now = DateTime.Now; @@ -58,7 +69,7 @@ namespace NadekoBot.Modules.Utility if (time.TotalMilliseconds > int.MaxValue) return; - await Task.Delay(time).ConfigureAwait(false); + await Task.Delay(time, t).ConfigureAwait(false); try { IMessageChannel ch; @@ -188,7 +199,7 @@ namespace NadekoBot.Modules.Utility { // ignored } - await StartReminder(rem); + await StartReminder(rem, cancelAllToken); } [NadekoCommand, Usage, Description, Aliases] diff --git a/src/NadekoBot/Modules/Utility/Commands/UnitConversion.cs b/src/NadekoBot/Modules/Utility/Commands/UnitConversion.cs index 4046627b..87283de3 100644 --- a/src/NadekoBot/Modules/Utility/Commands/UnitConversion.cs +++ b/src/NadekoBot/Modules/Utility/Commands/UnitConversion.cs @@ -49,14 +49,19 @@ namespace NadekoBot.Modules.Utility } Units = data.ToList(); } - catch (Exception e) + catch (Exception ex) { - _log.Warn("Could not load units: " + e.Message); + _log.Warn("Could not load units: " + ex.Message); } _timer = new Timer(async (obj) => await UpdateCurrency(), null, _updateInterval, _updateInterval); } + public static void Unload() + { + _timer.Change(Timeout.Infinite, Timeout.Infinite); + } + public static async Task UpdateCurrency() { try diff --git a/src/NadekoBot/Modules/Utility/Utility.cs b/src/NadekoBot/Modules/Utility/Utility.cs index 1ac77e73..0e2eba1b 100644 --- a/src/NadekoBot/Modules/Utility/Utility.cs +++ b/src/NadekoBot/Modules/Utility/Utility.cs @@ -25,6 +25,12 @@ namespace NadekoBot.Modules.Utility { private static ConcurrentDictionary _rotatingRoleColors = new ConcurrentDictionary(); + public static void Unload() + { + _rotatingRoleColors.ForEach(x => x.Value?.Change(Timeout.Infinite, Timeout.Infinite)); + _rotatingRoleColors.Clear(); + } + //[NadekoCommand, Usage, Description, Aliases] //[RequireContext(ContextType.Guild)] //public async Task Midorina([Remainder] string arg) @@ -49,7 +55,7 @@ namespace NadekoBot.Modules.Utility // var roleStrings = roles // .Select(x => $"{reactions[j++]} -> {x.Name}"); - + // var msg = await Context.Channel.SendConfirmAsync("Pick a Role", // string.Join("\n", roleStrings)).ConfigureAwait(false); @@ -100,6 +106,7 @@ namespace NadekoBot.Modules.Utility // } // })); //} + [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index 256ff9fe..0a128d7f 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -3012,7 +3012,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to Toggles game voice channel feature in the voice channel you're currently in. Users who join the game voice channel will get automatically redirected to the voice channel with the name of their current game if it exists. Can't move users to channels that the bot has no connect permission for. One per server.. + /// Looks up a localized string similar to Toggles game voice channel feature in the voice channel you're currently in. Users who join the game voice channel will get automatically redirected to the voice channel with the name of their current game, if it exists. Can't move users to channels that the bot has no connect permission for. One per server.. /// public static string gamevoicechannel_desc { get { @@ -3029,6 +3029,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to globalcommand gcmd. + /// + public static string gcmd_cmd { + get { + return ResourceManager.GetString("gcmd_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enables or disables a command from use on all servers.. + /// + public static string gcmd_desc { + get { + return ResourceManager.GetString("gcmd_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}gcmd `. + /// + public static string gcmd_usage { + get { + return ResourceManager.GetString("gcmd_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to gelbooru. /// @@ -3110,6 +3137,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to globalmodule gmod. + /// + public static string gmod_cmd { + get { + return ResourceManager.GetString("gmod_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enable or disable a module from use on all servers.. + /// + public static string gmod_desc { + get { + return ResourceManager.GetString("gmod_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}gmod nsfw disable`. + /// + public static string gmod_usage { + get { + return ResourceManager.GetString("gmod_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to google g. /// @@ -4055,6 +4109,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to listglobalperms lgp. + /// + public static string lgp_cmd { + get { + return ResourceManager.GetString("lgp_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lists global permissions set by the bot owner.. + /// + public static string lgp_desc { + get { + return ResourceManager.GetString("lgp_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}lgp`. + /// + public static string lgp_usage { + get { + return ResourceManager.GetString("lgp_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to linux. /// @@ -6512,6 +6593,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to resetglobalperms. + /// + public static string resetglobalpermissions_cmd { + get { + return ResourceManager.GetString("resetglobalpermissions_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Resets global permissions set by bot owner.. + /// + public static string resetglobalpermissions_desc { + get { + return ResourceManager.GetString("resetglobalpermissions_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}resetglobalperms`. + /// + public static string resetglobalpermissions_usage { + get { + return ResourceManager.GetString("resetglobalpermissions_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to resetperms. /// diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index a0a397a6..715ae1ba 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3421,7 +3421,7 @@ gvc - Toggles game voice channel feature in the voice channel you're currently in. Users who join the game voice channel will get automatically redirected to the voice channel with the name of their current game if it exists. Can't move users to channels that the bot has no connect permission for. One per server. + Toggles game voice channel feature in the voice channel you're currently in. Users who join the game voice channel will get automatically redirected to the voice channel with the name of their current game, if it exists. Can't move users to channels that the bot has no connect permission for. One per server. `{0}gvc` @@ -3438,4 +3438,40 @@ `{0}shoprm 1` + + globalcommand gcmd + + + Enables or disables a command from use on all servers. + + + `{0}gcmd ` + + + globalmodule gmod + + + Enable or disable a module from use on all servers. + + + `{0}gmod nsfw disable` + + + listglobalperms lgp + + + Lists global permissions set by the bot owner. + + + `{0}lgp` + + + resetglobalperms + + + Resets global permissions set by bot owner. + + + `{0}resetglobalperms` + \ No newline at end of file diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index 1d0d3075..67942c21 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -411,6 +411,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Global permissions have been reset.. + /// + public static string administration_global_perms_reset { + get { + return ResourceManager.GetString("administration_global_perms_reset", resourceCulture); + } + } + /// /// Looks up a localized string similar to Greet announcements disabled.. /// @@ -4711,6 +4720,24 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Blocked Commands. + /// + public static string permissions_blocked_commands { + get { + return ResourceManager.GetString("permissions_blocked_commands", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Blocked Modules. + /// + public static string permissions_blocked_modules { + get { + return ResourceManager.GetString("permissions_blocked_modules", resourceCulture); + } + } + /// /// Looks up a localized string similar to Command {0} now has a {1}s cooldown.. /// @@ -4801,6 +4828,42 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to Command {0} has been disabled on all servers.. + /// + public static string permissions_gcmd_add { + get { + return ResourceManager.GetString("permissions_gcmd_add", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Command {0} has been enabled on all servers.. + /// + public static string permissions_gcmd_remove { + get { + return ResourceManager.GetString("permissions_gcmd_remove", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Module {0} has been disabled on all servers.. + /// + public static string permissions_gmod_add { + get { + return ResourceManager.GetString("permissions_gmod_add", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Module {0} has been enabled on all servers.. + /// + public static string permissions_gmod_remove { + get { + return ResourceManager.GetString("permissions_gmod_remove", resourceCulture); + } + } + /// /// Looks up a localized string similar to Invalid second parameter.(Must be a number between {0} and {1}). /// @@ -4846,6 +4909,15 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to No blocked commands or modules.. + /// + public static string permissions_lgp_none { + get { + return ResourceManager.GetString("permissions_lgp_none", resourceCulture); + } + } + /// /// Looks up a localized string similar to Moved permission {0} from #{1} to #{2}. /// diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 4831a40f..e3c2ffa4 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2431,6 +2431,9 @@ Owner ID: {2} Next update in {0} Next update in 05:30 + + Global permissions have been reset. + Game Voice Channel feature has been disabled on this server. @@ -2485,4 +2488,25 @@ Owner ID: {2} {0} unique items left. + + Blocked Commands + + + Blocked Modules + + + Command {0} has been disabled on all servers. + + + Command {0} has been enabled on all servers. + + + Module {0} has been disabled on all servers. + + + Module {0} has been enabled on all servers. + + + No blocked commands or modules. + \ No newline at end of file diff --git a/src/NadekoBot/Services/CommandHandler.cs b/src/NadekoBot/Services/CommandHandler.cs index 8cd840e0..06b447b1 100644 --- a/src/NadekoBot/Services/CommandHandler.cs +++ b/src/NadekoBot/Services/CommandHandler.cs @@ -486,15 +486,22 @@ namespace NadekoBot.Services } } - int price; - if (Permissions.CommandCostCommands.CommandCosts.TryGetValue(cmd.Aliases.First().Trim().ToLowerInvariant(), out price) && price > 0) - { - var success = await CurrencyHandler.RemoveCurrencyAsync(context.User.Id, $"Running {cmd.Name} command.", price).ConfigureAwait(false); - if (!success) - { - return new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, $"Insufficient funds. You need {price}{NadekoBot.BotConfig.CurrencySign} to run this command.")); - } - } + //int price; + //if (Permissions.CommandCostCommands.CommandCosts.TryGetValue(cmd.Aliases.First().Trim().ToLowerInvariant(), out price) && price > 0) + //{ + // var success = await CurrencyHandler.RemoveCurrencyAsync(context.User.Id, $"Running {cmd.Name} command.", price).ConfigureAwait(false); + // if (!success) + // { + // return new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, $"Insufficient funds. You need {price}{NadekoBot.BotConfig.CurrencySign} to run this command.")); + // } + //} + } + + if (cmd.Name != "resetglobalperms" && + (GlobalPermissionCommands.BlockedCommands.Contains(cmd.Aliases.First().ToLowerInvariant()) || + GlobalPermissionCommands.BlockedModules.Contains(module.Name.ToLowerInvariant()))) + { + return new ExecuteCommandResult(cmd, null, SearchResult.FromError(CommandError.Exception, $"Command or module is blocked globally by the bot owner.")); } // Bot will ignore commands which are ran more often than what specified by diff --git a/src/NadekoBot/Services/Database/Models/BotConfig.cs b/src/NadekoBot/Services/Database/Models/BotConfig.cs index b25dc744..81bbb87f 100644 --- a/src/NadekoBot/Services/Database/Models/BotConfig.cs +++ b/src/NadekoBot/Services/Database/Models/BotConfig.cs @@ -62,6 +62,25 @@ Nadeko Support Server: https://discord.gg/nadekobot"; public string ErrorColor { get; set; } = "ee281f"; public string Locale { get; set; } = null; public List StartupCommands { get; set; } + public HashSet BlockedCommands { get; set; } + public HashSet BlockedModules { get; set; } + } + + public class BlockedCmdOrMdl : DbEntity + { + public string Name { get; set; } + + public override bool Equals(object obj) + { + if (obj == null || GetType() != obj.GetType()) + { + return false; + } + + return ((BlockedCmdOrMdl)obj).Name.ToLowerInvariant() == Name.ToLowerInvariant(); + } + + public override int GetHashCode() => Name.GetHashCode(); } public class StartupCommand : DbEntity, IIndexed diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/BotConfigRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/BotConfigRepository.cs index 1e40f86c..c9b7ad7d 100644 --- a/src/NadekoBot/Services/Database/Repositories/Impl/BotConfigRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/Impl/BotConfigRepository.cs @@ -22,6 +22,8 @@ namespace NadekoBot.Services.Database.Repositories.Impl .Include(bc => bc.EightBallResponses) .Include(bc => bc.ModulePrefixes) .Include(bc => bc.StartupCommands) + .Include(bc => bc.BlockedCommands) + .Include(bc => bc.BlockedModules) //.Include(bc => bc.CommandCosts) .FirstOrDefault(); else From 19160c6bbcf8a8c81913b215d4bf5aee4e453b04 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sun, 9 Apr 2017 23:22:06 +0200 Subject: [PATCH 62/98] closes #431, if gmod or gcmd is active on some module or command, they won't show up on -mdls or -cmds respectively --- src/NadekoBot/Modules/Help/Help.cs | 2 ++ src/NadekoBot/Modules/Searches/Searches.cs | 2 +- src/NadekoBot/Resources/CommandStrings.Designer.cs | 2 +- src/NadekoBot/Resources/CommandStrings.resx | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/NadekoBot/Modules/Help/Help.cs b/src/NadekoBot/Modules/Help/Help.cs index 4ca96023..1208260b 100644 --- a/src/NadekoBot/Modules/Help/Help.cs +++ b/src/NadekoBot/Modules/Help/Help.cs @@ -31,6 +31,7 @@ namespace NadekoBot.Modules.Help .WithTitle(GetText("list_of_modules")) .WithDescription(string.Join("\n", NadekoBot.CommandService.Modules.GroupBy(m => m.GetTopLevelModule()) + .Where(m => !Permissions.Permissions.GlobalPermissionCommands.BlockedModules.Contains(m.Key.Name.ToLowerInvariant())) .Select(m => "• " + m.Key.Name) .OrderBy(s => s))); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); @@ -45,6 +46,7 @@ namespace NadekoBot.Modules.Help if (string.IsNullOrWhiteSpace(module)) return; var cmds = NadekoBot.CommandService.Commands.Where(c => c.Module.GetTopLevelModule().Name.ToUpperInvariant().StartsWith(module)) + .Where(c => !Permissions.Permissions.GlobalPermissionCommands.BlockedCommands.Contains(c.Aliases.First().ToLowerInvariant())) .OrderBy(c => c.Aliases.First()) .Distinct(new CommandTextEqualityComparer()) .AsEnumerable(); diff --git a/src/NadekoBot/Modules/Searches/Searches.cs b/src/NadekoBot/Modules/Searches/Searches.cs index 3e6aa1bc..b25bf15e 100644 --- a/src/NadekoBot/Modules/Searches/Searches.cs +++ b/src/NadekoBot/Modules/Searches/Searches.cs @@ -585,7 +585,7 @@ namespace NadekoBot.Modules.Searches { if (usr == null) usr = Context.User; - await Context.Channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={usr.AvatarUrl}").ConfigureAwait(false); + await Context.Channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={usr.RealAvatarUrl()}").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index 0a128d7f..48192ab6 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -5037,7 +5037,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to Mentions every person from the provided role or roles (separated by a ',') on this server. Requires you to have the mention everyone permission.. + /// Looks up a localized string similar to Mentions every person from the provided role or roles (separated by a ',') on this server.. /// public static string mentionrole_desc { get { diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 715ae1ba..1b5cff49 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -733,7 +733,7 @@ mentionrole menro - Mentions every person from the provided role or roles (separated by a ',') on this server. Requires you to have the mention everyone permission. + Mentions every person from the provided role or roles (separated by a ',') on this server. `{0}menro RoleName` From c9937a4fbe29f0d212df0a1ed9388aea7a6b222d Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sun, 9 Apr 2017 23:23:19 +0200 Subject: [PATCH 63/98] version upped to 1.3 --- src/NadekoBot/Services/Impl/StatsService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NadekoBot/Services/Impl/StatsService.cs b/src/NadekoBot/Services/Impl/StatsService.cs index f18845ad..570c44ff 100644 --- a/src/NadekoBot/Services/Impl/StatsService.cs +++ b/src/NadekoBot/Services/Impl/StatsService.cs @@ -16,7 +16,7 @@ namespace NadekoBot.Services.Impl private readonly DiscordShardedClient _client; private readonly DateTime _started; - public const string BotVersion = "1.26a"; + public const string BotVersion = "1.3"; public string Author => "Kwoth#2560"; public string Library => "Discord.Net"; From 4badd92b5a3f8c92d2203afdf32f46c71e1815e4 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sun, 9 Apr 2017 23:29:08 +0200 Subject: [PATCH 64/98] updated commandlist --- docs/Commands List.md | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/docs/Commands List.md b/docs/Commands List.md index da4d922c..dc705b8e 100644 --- a/docs/Commands List.md +++ b/docs/Commands List.md @@ -19,14 +19,15 @@ You can support the project on patreon: or paypa Commands and aliases | Description | Usage ----------------|--------------|------- `.resetperms` | Resets the bot's permissions module on this server to the default value. **Requires Administrator server permission.** | `.resetperms` +`.resetglobalperms` | Resets global permissions set by bot owner. **Bot owner only** | `.resetglobalperms` `.delmsgoncmd` | Toggles the automatic deletion of the user's successful command message to prevent chat flood. **Requires Administrator server permission.** | `.delmsgoncmd` `.setrole` `.sr` | Sets a role for a given user. **Requires ManageRoles server permission.** | `.sr @User Guest` `.removerole` `.rr` | Removes a role from a given user. **Requires ManageRoles server permission.** | `.rr @User Admin` `.renamerole` `.renr` | Renames a role. The role you are renaming must be lower than bot's highest role. **Requires ManageRoles server permission.** | `.renr "First role" SecondRole` `.removeallroles` `.rar` | Removes all roles from a mentioned user. **Requires ManageRoles server permission.** | `.rar @User` `.createrole` `.cr` | Creates a role with a given name. **Requires ManageRoles server permission.** | `.cr Awesome Role` +`.rolehoist` `.rh` | Toggles if this role is displayed in the sidebar or not **Requires ManageRoles server permission.** | `.rh Guests true` or `.rh "Space Wizards" true `.rolecolor` `.rc` | Set a role's color to the hex or 0-255 rgb color value provided. **Requires ManageRoles server permission.** | `.rc Admin 255 200 100` or `.rc Admin ffba55` -`.rolehoist` `.rh` | Set whether the role should be displayed separately in the sidebar **Requires ManageRoles server permission.** | `.rh Guests true` or `.rolehoist "Space Wizards" true` `.deafen` `.deaf` | Deafens mentioned user or users. **Requires DeafenMembers server permission.** | `.deaf "@Someguy"` or `.deaf "@Someguy" "@Someguy"` `.undeafen` `.undef` | Undeafens mentioned user or users. **Requires DeafenMembers server permission.** | `.undef "@Someguy"` or `.undef "@Someguy" "@Someguy"` `.delvoichanl` `.dvch` | Deletes a voice channel with a given name. **Requires ManageChannels server permission.** | `.dvch VoiceChannelName` @@ -36,10 +37,11 @@ Commands and aliases | Description | Usage `.settopic` `.st` | Sets a topic on the current channel. **Requires ManageChannels server permission.** | `.st My new topic` `.setchanlname` `.schn` | Changes the name of the current channel. **Requires ManageChannels server permission.** | `.schn NewName` `.prune` `.clr` | `.prune` removes all Nadeko's messages in the last 100 messages. `.prune X` removes last `X` number of messages from the channel (up to 100). `.prune @Someone` removes all Someone's messages in the last 100 messages. `.prune @Someone X` removes last `X` number of 'Someone's' messages in the channel. | `.prune` or `.prune 5` or `.prune @Someone` or `.prune @Someone X` -`.mentionrole` `.menro` | Mentions every person from the provided role or roles (separated by a ',') on this server. Requires you to have the mention everyone permission. **Requires MentionEveryone server permission.** | `.menro RoleName` +`.mentionrole` `.menro` | Mentions every person from the provided role or roles (separated by a ',') on this server. **Requires MentionEveryone server permission.** | `.menro RoleName` `.donators` | List of the lovely people who donated to keep this project alive. | `.donators` `.donadd` | Add a donator to the database. **Bot owner only** | `.donadd Donate Amount` `.autoassignrole` `.aar` | Automaticaly assigns a specified role to every user who joins the server. **Requires ManageRoles server permission.** | `.aar` to disable, `.aar Role Name` to enable +`.gvc` | Toggles game voice channel feature in the voice channel you're currently in. Users who join the game voice channel will get automatically redirected to the voice channel with the name of their current game, if it exists. Can't move users to channels that the bot has no connect permission for. One per server. **Requires Administrator server permission.** | `.gvc` `.languageset` `.langset` | Sets this server's response language. If bot's response strings have been translated to that language, bot will use that language in this server. Reset by using `default` as the locale name. Provide no arguments to see currently set language. | `.langset de-DE ` or `.langset default` `.langsetdefault` `.langsetd` | Sets the bot's default response language. All servers which use a default locale will use this one. Setting to `default` will use the host's current culture. Provide no arguments to see currently set language. | `.langsetd en-US` or `.langsetd default` `.languageslist` `.langli` | List of languages for which translation (or part of it) exist atm. | `.langli` @@ -64,6 +66,7 @@ Commands and aliases | Description | Usage `.antispamignore` | Toggles whether antispam ignores current channel. Antispam must be enabled. | `.antispamignore` `.antilist` `.antilst` | Shows currently enabled protection features. | `.antilist` `.slowmode` | Toggles slowmode. Disable by specifying no parameters. To enable, specify a number of messages each user can send, and an interval in seconds. For example 1 message every 5 seconds. **Requires ManageMessages server permission.** | `.slowmode 1 5` or `.slowmode` +`.slowmodewl` | Ignores a role or a user from the slowmode feature. **Requires ManageMessages server permission.** | `.slowmodewl SomeRole` or `.slowmodewl AdminDude` `.adsarm` | Toggles the automatic deletion of confirmations for `.iam` and `.iamn` commands. **Requires ManageMessages server permission.** | `.adsarm` `.asar` | Adds a role to the list of self-assignable roles. **Requires ManageRoles server permission.** | `.asar Gamer` `.rsar` | Removes a specified role from the list of self-assignable roles. **Requires ManageRoles server permission.** | `.rsar` @@ -136,7 +139,7 @@ Commands and aliases | Description | Usage `.listcustreactg` `.lcrg` | Lists global or server custom reactions (20 commands per page) grouped by trigger, and show a number of responses for each. Running the command in DM will list global custom reactions, while running it in server will list that server's custom reactions. | `.lcrg 1` `.showcustreact` `.scr` | Shows a custom reaction's response on a given ID. | `.scr 1` `.delcustreact` `.dcr` | Deletes a custom reaction on a specific index. If ran in DM, it is bot owner only and deletes a global custom reaction. If ran in a server, it requires Administration privileges and removes server custom reaction. | `.dcr 5` -`.crdm` | Toggles whether the response message of the custom reaction will be sent as a direct message. | `.crad 44` +`.crdm` | Toggles whether the response message of the custom reaction will be sent as a direct message. | `.crdm 44` `.crad` | Toggles whether the message triggering the custom reaction will be automatically deleted. | `.crad 59` `.crstatsclear` | Resets the counters on `.crstats`. You can specify a trigger to clear stats only for that trigger. **Bot owner only** | `.crstatsclear` or `.crstatsclear rng` `.crstats` | Shows a list of custom reactions and the number of times they have been executed. Paginated with 10 per page. Use `.crstatsclear` to reset the counters. | `.crstats` or `.crstats 3` @@ -163,6 +166,11 @@ Commands and aliases | Description | Usage `$shuffle` `$sh` | Reshuffles all cards back into the deck. | `$sh` `$flip` | Flips coin(s) - heads or tails, and shows an image. | `$flip` or `$flip 3` `$betflip` `$bf` | Bet to guess will the result be heads or tails. Guessing awards you 1.95x the currency you've bet (rounded up). Multiplier can be changed by the bot owner. | `$bf 5 heads` or `$bf 3 t` +`$shop` | Lists this server's administrators' shop. Paginated. | `$shop` or `$shop 2` +`$buy` | Buys an item from the shop on a given index. If buying items, make sure that the bot can DM you. | `$buy 2` +`$shopadd` | Adds an item to the shop by specifying type price and name. Available types are role and list. **Requires Administrator server permission.** | `$shopadd role 1000 Rich` +`$shoplistadd` | Adds an item to the list of items for sale in the shop entry given the index. You usually want to run this command in the secret channel, so that the unique items are not leaked. **Requires Administrator server permission.** | `$shoplistadd 1 Uni-que-Steam-Key` +`$shoprem` `$shoprm` | Removes an item from the shop by its color. **Requires Administrator server permission.** | `$shoprm 1` `$slotstats` | Shows the total stats of the slot command for this bot's session. **Bot owner only** | `$slotstats` `$slottest` | Tests to see how much slots payout for X number of plays. **Bot owner only** | `$slottest 1000` `$slot` | Play Nadeko slots. Max bet is 999. 3 seconds cooldown per user. | `$slot 5` @@ -303,6 +311,9 @@ Commands and aliases | Description | Usage `;chnlfilterwords` `;cfw` | Toggles automatic deletion of messages containing filtered words on the channel. Does not negate the `;srvrfilterwords` enabled setting. Does not affect the Bot Owner. | `;cfw` `;fw` | Adds or removes (if it exists) a word from the list of filtered words. Use`;sfw` or `;cfw` to toggle filtering. | `;fw poop` `;lstfilterwords` `;lfw` | Shows a list of filtered words. | `;lfw` +`;listglobalperms` `;lgp` | Lists global permissions set by the bot owner. **Bot owner only** | `;lgp` +`;globalmodule` `;gmod` | Enable or disable a module from use on all servers. **Bot owner only** | `;gmod nsfw disable` +`;globalcommand` `;gcmd` | Enables or disables a command from use on all servers. **Bot owner only** | `;gcmd ` ###### [Back to ToC](#table-of-contents) @@ -321,6 +332,7 @@ Commands and aliases | Description | Usage Commands and aliases | Description | Usage ----------------|--------------|------- `~weather` `~we` | Shows weather data for a specified city. You can also specify a country after a comma. | `~we Moscow, RU` +`~time` | Shows the current time and timezone in the specified location. | `~time London, UK` `~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` @@ -398,6 +410,7 @@ Commands and aliases | Description | Usage `.showemojis` `.se` | Shows a name and a link to every SPECIAL emoji in the message. | `.se A message full of SPECIAL emojis` `.listservers` | Lists servers the bot is on with some basic info. 15 per page. **Bot owner only** | `.listservers 3` `.savechat` | Saves a number of messages to a text file and sends it to you. **Bot owner only** | `.savechat 150` +`.ping` | Ping the bot to see if there are latency issues. | `.ping` `.activity` | Checks for spammers. **Bot owner only** | `.activity` `.calculate` `.calc` | Evaluate a mathematical expression. | `.calc 1+1` `.calcops` | Shows all available operations in the `.calc` command | `.calcops` @@ -413,9 +426,12 @@ Commands and aliases | Description | Usage `.repeatremove` `.reprm` | Removes a repeating message on a specified index. Use `.repeatlist` to see indexes. **Requires ManageMessages server permission.** | `.reprm 2` `.repeat` | Repeat a message every `X` minutes in the current channel. You can have up to 5 repeating messages on the server in total. **Requires ManageMessages server permission.** | `.repeat 5 Hello there` `.repeatlist` `.replst` | Shows currently repeating messages and their indexes. **Requires ManageMessages server permission.** | `.repeatlist` -`.listquotes` `.liqu` | `.liqu` or `.liqu 3` | Lists all quotes on the server ordered alphabetically. 15 Per page. +`.parewrel` | Forces the update of the list of patrons who are eligible for the reward. **Bot owner only** | `.parewrel` +`.clparew` | Claim patreon rewards. If you're subscribed to bot owner's patreon you can use this command to claim your rewards - assuming bot owner did setup has their patreon key. | `.clparew` +`.listquotes` `.liqu` | Lists all quotes on the server ordered alphabetically. 15 Per page. | `.liqu` or `.liqu 3` `...` | Shows a random quote with a specified name. | `... abc` `.qsearch` | Shows a random quote for a keyword that contains any text specified in the search. | `.qsearch keyword text` +`.quoteid` `.qid` | Displays the quote with the specified ID number. Quote ID numbers can be found by typing `.liqu [num]` where `[num]` is a number of a page which contains 15 quotes. | `.qid 123456` `..` | Adds a new quote with the specified name and message. | `.. sayhi Hi` `.deletequote` `.delq` | Deletes a quote with the specified ID. You have to be either server Administrator or the creator of the quote to delete it. | `.delq 123456` `.delallq` `.daq` | Deletes all quotes on a specified keyword. **Requires Administrator server permission.** | `.delallq kek` From e5131e0416f3ae3ff42b1820185482dd94e5a299 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sun, 9 Apr 2017 23:31:16 +0200 Subject: [PATCH 65/98] now shows that you can specify a reason --- src/NadekoBot/Resources/CommandStrings.Designer.cs | 2 +- src/NadekoBot/Resources/CommandStrings.resx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index 48192ab6..c135ff21 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -9744,7 +9744,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to `{0}warn @b1nzy`. + /// Looks up a localized string similar to `{0}warn @b1nzy Very rude person`. /// public static string warn_usage { get { diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 1b5cff49..6c67e584 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3247,7 +3247,7 @@ Warns a user. - `{0}warn @b1nzy` + `{0}warn @b1nzy Very rude person` scadd From a0e363ff660637e53442acdb7853a905f8ae3f77 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 10 Apr 2017 02:29:33 +0200 Subject: [PATCH 66/98] mute role will be applied to newly created channels now too --- .../Administration/Commands/MuteCommands.cs | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/NadekoBot/Modules/Administration/Commands/MuteCommands.cs b/src/NadekoBot/Modules/Administration/Commands/MuteCommands.cs index 0a130383..9399fc90 100644 --- a/src/NadekoBot/Modules/Administration/Commands/MuteCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/MuteCommands.cs @@ -1,5 +1,6 @@ using Discord; using Discord.Commands; +using Discord.WebSocket; using Microsoft.EntityFrameworkCore; using NadekoBot.Attributes; using NadekoBot.Services; @@ -32,6 +33,9 @@ namespace NadekoBot.Modules.Administration Chat, All } + private static readonly OverwritePermissions denyOverwrite = new OverwritePermissions(sendMessages: PermValue.Deny, attachFiles: PermValue.Deny); + + private static readonly new Logger _log = LogManager.GetCurrentClassLogger(); static MuteCommands() { @@ -152,21 +156,26 @@ namespace NadekoBot.Modules.Administration muteRole = guild.Roles.FirstOrDefault(r => r.Name == muteRoleName) ?? await guild.CreateRoleAsync(defaultMuteRoleName, GuildPermissions.None).ConfigureAwait(false); } + } - foreach (var toOverwrite in (await guild.GetTextChannelsAsync())) + foreach (var toOverwrite in (await guild.GetTextChannelsAsync())) + { + try { - try + if (!toOverwrite.PermissionOverwrites.Select(x => x.Permissions).Contains(denyOverwrite)) { - await toOverwrite.AddPermissionOverwriteAsync(muteRole, new OverwritePermissions(sendMessages: PermValue.Deny, attachFiles: PermValue.Deny)) + await toOverwrite.AddPermissionOverwriteAsync(muteRole, denyOverwrite) .ConfigureAwait(false); + + await Task.Delay(200).ConfigureAwait(false); } - catch - { - // ignored - } - await Task.Delay(200).ConfigureAwait(false); + } + catch + { + // ignored } } + return muteRole; } From bece18dffc09678d543d3cdb9767d01299c8d18f Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 10 Apr 2017 02:53:36 +0200 Subject: [PATCH 67/98] .repinv now posts in the channel repeater originates from, not current one --- .../Utility/Commands/MessageRepeater.cs | 84 ++++++++++--------- 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs b/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs index 4b40b98b..4bc2f2f5 100644 --- a/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs +++ b/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs @@ -36,6 +36,7 @@ namespace NadekoBot.Modules.Utility public Repeater Repeater { get; } public SocketGuild Guild { get; } public ITextChannel Channel { get; private set; } + private IUserMessage oldMsg = null; public RepeatRunner(Repeater repeater, ITextChannel channel = null) { @@ -52,49 +53,13 @@ namespace NadekoBot.Modules.Utility { source = new CancellationTokenSource(); token = source.Token; - IUserMessage oldMsg = null; try { while (!token.IsCancellationRequested) { - var toSend = "🔄 " + Repeater.Message; await Task.Delay(Repeater.Interval, token).ConfigureAwait(false); - //var lastMsgInChannel = (await Channel.GetMessagesAsync(2)).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 - { - // ignored - } - try - { - if (Channel == null) - Channel = Guild.GetTextChannel(Repeater.ChannelId); - - if (Channel != null) - oldMsg = await Channel.SendMessageAsync(toSend).ConfigureAwait(false); - } - catch (HttpException ex) when (ex.HttpCode == System.Net.HttpStatusCode.Forbidden) - { - _log.Warn("Missing permissions. Repeater stopped. ChannelId : {0}", Channel?.Id); - return; - } - catch (HttpException ex) when (ex.HttpCode == System.Net.HttpStatusCode.NotFound) - { - _log.Warn("Channel not found. Repeater stopped. ChannelId : {0}", Channel?.Id); - return; - } - catch (Exception ex) - { - _log.Warn(ex); - } + await Trigger().ConfigureAwait(false); } } catch (OperationCanceledException) @@ -102,6 +67,46 @@ namespace NadekoBot.Modules.Utility } } + public async Task Trigger() + { + var toSend = "🔄 " + Repeater.Message; + //var lastMsgInChannel = (await Channel.GetMessagesAsync(2)).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 + { + // ignored + } + try + { + if (Channel == null) + Channel = Guild.GetTextChannel(Repeater.ChannelId); + + if (Channel != null) + oldMsg = await Channel.SendMessageAsync(toSend).ConfigureAwait(false); + } + catch (HttpException ex) when (ex.HttpCode == System.Net.HttpStatusCode.Forbidden) + { + _log.Warn("Missing permissions. Repeater stopped. ChannelId : {0}", Channel?.Id); + return; + } + catch (HttpException ex) when (ex.HttpCode == System.Net.HttpStatusCode.NotFound) + { + _log.Warn("Channel not found. Repeater stopped. ChannelId : {0}", Channel?.Id); + return; + } + catch (Exception ex) + { + _log.Warn(ex); + } + } + public void Reset() { source.Cancel(); @@ -176,9 +181,10 @@ namespace NadekoBot.Modules.Utility return; } var repeater = repList[index].Repeater; - repList[index].Reset(); - await Context.Channel.SendMessageAsync("🔄 " + repeater.Message).ConfigureAwait(false); + await repList[index].Trigger(); + + await Context.Channel.SendMessageAsync("🔄").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] From 81d2272a9a5f24b8d0c46c60be3fa9d2a4d446a2 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 10 Apr 2017 03:00:17 +0200 Subject: [PATCH 68/98] fixed missing here and everyone mention removals from custom reactions, repeaters and others --- src/NadekoBot/Modules/CustomReactions/CustomReactions.cs | 2 +- src/NadekoBot/Modules/CustomReactions/Extensions.cs | 2 +- src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs b/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs index ac6fd4c9..b250c510 100644 --- a/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs +++ b/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs @@ -28,7 +28,7 @@ namespace NadekoBot.Modules.CustomReactions { return await channel.EmbedAsync(crembed.ToEmbed(), crembed.PlainText ?? ""); } - return await channel.SendMessageAsync(cr.ResponseWithContext(context)); + return await channel.SendMessageAsync(cr.ResponseWithContext(context).SanitizeMentions()); } } diff --git a/src/NadekoBot/Modules/CustomReactions/Extensions.cs b/src/NadekoBot/Modules/CustomReactions/Extensions.cs index a0b91962..b40e3fa8 100644 --- a/src/NadekoBot/Modules/CustomReactions/Extensions.cs +++ b/src/NadekoBot/Modules/CustomReactions/Extensions.cs @@ -15,7 +15,7 @@ namespace NadekoBot.Modules.CustomReactions { public static Dictionary> responsePlaceholders = new Dictionary>() { - {"%target%", (ctx, trigger) => { return ctx.Content.Substring(trigger.Length).Trim(); } } + {"%target%", (ctx, trigger) => { return ctx.Content.Substring(trigger.Length).Trim().SanitizeMentions(); } } }; public static Dictionary> placeholders = new Dictionary>() diff --git a/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs b/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs index 4bc2f2f5..4b05391d 100644 --- a/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs +++ b/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs @@ -89,7 +89,7 @@ namespace NadekoBot.Modules.Utility Channel = Guild.GetTextChannel(Repeater.ChannelId); if (Channel != null) - oldMsg = await Channel.SendMessageAsync(toSend).ConfigureAwait(false); + oldMsg = await Channel.SendMessageAsync(toSend.SanitizeMentions()).ConfigureAwait(false); } catch (HttpException ex) when (ex.HttpCode == System.Net.HttpStatusCode.Forbidden) { From 4a3bb0f57eb3dd9a278f98ae062d040dd9396e20 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 10 Apr 2017 03:02:46 +0200 Subject: [PATCH 69/98] sanitized mentions in quote commands --- src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs b/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs index b8819255..a11ad7c9 100644 --- a/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs @@ -34,7 +34,7 @@ namespace NadekoBot.Modules.Utility if (quotes.Any()) await Context.Channel.SendConfirmAsync(GetText("quotes_page", page + 1), - string.Join("\n", quotes.Select(q => $"`#{q.Id}` {Format.Bold(q.Keyword),-20} by {q.AuthorName}"))) + string.Join("\n", quotes.Select(q => $"`#{q.Id}` {Format.Bold(q.Keyword.SanitizeMentions()),-20} by {q.AuthorName.SanitizeMentions()}"))) .ConfigureAwait(false); else await ReplyErrorLocalized("quotes_page_none").ConfigureAwait(false); @@ -132,7 +132,7 @@ namespace NadekoBot.Modules.Utility return; } - else { await Context.Channel.SendMessageAsync($"`#{qfromid.Id}` 🗯️ " + qfromid.Keyword.ToLowerInvariant() + ": " + + else { await Context.Channel.SendMessageAsync($"`#{qfromid.Id}` 🗯️ " + qfromid.Keyword.ToLowerInvariant().SanitizeMentions() + ": " + qfromid.Text.SanitizeMentions()); } } } @@ -208,7 +208,7 @@ namespace NadekoBot.Modules.Utility await uow.CompleteAsync(); } - await ReplyConfirmLocalized("quotes_deleted", Format.Bold(keyword)).ConfigureAwait(false); + await ReplyConfirmLocalized("quotes_deleted", Format.Bold(keyword.SanitizeMentions())).ConfigureAwait(false); } } } From a3bd89460b72569e48aa04faf4388d8128b1f0c9 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 10 Apr 2017 03:14:52 +0200 Subject: [PATCH 70/98] ;fwmsgs should ocne again dm the first bot owner, not a random one --- src/NadekoBot/Services/CommandHandler.cs | 3 ++- src/NadekoBot/Services/IBotCredentials.cs | 2 +- src/NadekoBot/Services/Impl/BotCredentials.cs | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/NadekoBot/Services/CommandHandler.cs b/src/NadekoBot/Services/CommandHandler.cs index 06b447b1..0febdb9d 100644 --- a/src/NadekoBot/Services/CommandHandler.cs +++ b/src/NadekoBot/Services/CommandHandler.cs @@ -75,12 +75,13 @@ namespace NadekoBot.Services } }))) .Where(ch => ch != null) + .OrderBy(x => NadekoBot.Credentials.OwnerIds.IndexOf(x.Id)) .ToList(); if (!ownerChannels.Any()) _log.Warn("No owner channels created! Make sure you've specified correct OwnerId in the credentials.json file."); else - _log.Info($"Created {ownerChannels.Count} out of {NadekoBot.Credentials.OwnerIds.Count} owner message channels."); + _log.Info($"Created {ownerChannels.Count} out of {NadekoBot.Credentials.OwnerIds.Length} owner message channels."); }); _client.MessageReceived += MessageReceivedHandler; diff --git a/src/NadekoBot/Services/IBotCredentials.cs b/src/NadekoBot/Services/IBotCredentials.cs index 63bea8b8..0a89b471 100644 --- a/src/NadekoBot/Services/IBotCredentials.cs +++ b/src/NadekoBot/Services/IBotCredentials.cs @@ -10,7 +10,7 @@ namespace NadekoBot.Services string Token { get; } string GoogleApiKey { get; } - ImmutableHashSet OwnerIds { get; } + ImmutableArray OwnerIds { get; } string MashapeKey { get; } string LoLApiKey { get; } string PatreonAccessToken { get; } diff --git a/src/NadekoBot/Services/Impl/BotCredentials.cs b/src/NadekoBot/Services/Impl/BotCredentials.cs index a0220778..27ea4090 100644 --- a/src/NadekoBot/Services/Impl/BotCredentials.cs +++ b/src/NadekoBot/Services/Impl/BotCredentials.cs @@ -21,7 +21,7 @@ namespace NadekoBot.Services.Impl public string Token { get; } - public ImmutableHashSet OwnerIds { get; } + public ImmutableArray OwnerIds { get; } public string LoLApiKey { get; } public string OsuApiKey { get; } @@ -62,7 +62,7 @@ namespace NadekoBot.Services.Impl Token = data[nameof(Token)]; if (string.IsNullOrWhiteSpace(Token)) throw new ArgumentNullException(nameof(Token), "Token is missing from credentials.json or Environment varibles."); - OwnerIds = data.GetSection("OwnerIds").GetChildren().Select(c => ulong.Parse(c.Value)).ToImmutableHashSet(); + OwnerIds = data.GetSection("OwnerIds").GetChildren().Select(c => ulong.Parse(c.Value)).ToImmutableArray(); LoLApiKey = data[nameof(LoLApiKey)]; GoogleApiKey = data[nameof(GoogleApiKey)]; MashapeKey = data[nameof(MashapeKey)]; From 06ca1c5f8f96ce2f2f18e200f4004600f32746d1 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 10 Apr 2017 19:56:10 +0200 Subject: [PATCH 71/98] You can now use actualcustomreactions as a module name to enable/disable actual custom reactions, as opposed to commands to manage them which are in CustomReactions module --- .../Games/Commands/PlantAndPickCommands.cs | 3 ++- .../Commands/GlobalPermissionCommands.cs | 2 +- .../Modules/Permissions/Permissions.cs | 8 +++---- src/NadekoBot/NadekoBot.cs | 1 + src/NadekoBot/TypeReaders/ModuleTypeReader.cs | 21 +++++++++++++++++++ 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs b/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs index 7c081289..44eb474a 100644 --- a/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs @@ -181,7 +181,7 @@ namespace NadekoBot.Modules.Games return old; }); } - +#if !GLOBAL_NADEKO [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [RequireUserPermission(GuildPermission.ManageMessages)] @@ -218,6 +218,7 @@ namespace NadekoBot.Modules.Games await ReplyConfirmLocalized("curgen_disabled").ConfigureAwait(false); } } +#endif private static KeyValuePair> GetRandomCurrencyImage() { diff --git a/src/NadekoBot/Modules/Permissions/Commands/GlobalPermissionCommands.cs b/src/NadekoBot/Modules/Permissions/Commands/GlobalPermissionCommands.cs index 41ba61b3..e493f03d 100644 --- a/src/NadekoBot/Modules/Permissions/Commands/GlobalPermissionCommands.cs +++ b/src/NadekoBot/Modules/Permissions/Commands/GlobalPermissionCommands.cs @@ -52,7 +52,7 @@ namespace NadekoBot.Modules.Permissions [NadekoCommand, Usage, Description, Aliases] [OwnerOnly] - public async Task Gmod(ModuleInfo module) + public async Task Gmod(ModuleOrCrInfo module) { var moduleName = module.Name.ToLowerInvariant(); if (BlockedModules.Add(moduleName)) diff --git a/src/NadekoBot/Modules/Permissions/Permissions.cs b/src/NadekoBot/Modules/Permissions/Permissions.cs index a942fd7e..e9f92c66 100644 --- a/src/NadekoBot/Modules/Permissions/Permissions.cs +++ b/src/NadekoBot/Modules/Permissions/Permissions.cs @@ -363,7 +363,7 @@ namespace NadekoBot.Modules.Permissions [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task SrvrMdl(ModuleInfo module, PermissionAction action) + public async Task SrvrMdl(ModuleOrCrInfo module, PermissionAction action) { await AddPermissions(Context.Guild.Id, new Permissionv2 { @@ -419,7 +419,7 @@ namespace NadekoBot.Modules.Permissions [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task UsrMdl(ModuleInfo module, PermissionAction action, [Remainder] IGuildUser user) + public async Task UsrMdl(ModuleOrCrInfo module, PermissionAction action, [Remainder] IGuildUser user) { await AddPermissions(Context.Guild.Id, new Permissionv2 { @@ -480,7 +480,7 @@ namespace NadekoBot.Modules.Permissions [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task RoleMdl(ModuleInfo module, PermissionAction action, [Remainder] IRole role) + public async Task RoleMdl(ModuleOrCrInfo module, PermissionAction action, [Remainder] IRole role) { if (role == role.Guild.EveryoneRole) return; @@ -542,7 +542,7 @@ namespace NadekoBot.Modules.Permissions [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ChnlMdl(ModuleInfo module, PermissionAction action, [Remainder] ITextChannel chnl) + public async Task ChnlMdl(ModuleOrCrInfo module, PermissionAction action, [Remainder] ITextChannel chnl) { await AddPermissions(Context.Guild.Id, new Permissionv2 { diff --git a/src/NadekoBot/NadekoBot.cs b/src/NadekoBot/NadekoBot.cs index 6673cacb..075c12e8 100644 --- a/src/NadekoBot/NadekoBot.cs +++ b/src/NadekoBot/NadekoBot.cs @@ -112,6 +112,7 @@ namespace NadekoBot CommandService.AddTypeReader(new CommandTypeReader()); CommandService.AddTypeReader(new CommandOrCrTypeReader()); CommandService.AddTypeReader(new ModuleTypeReader()); + CommandService.AddTypeReader(new ModuleOrCrTypeReader()); CommandService.AddTypeReader(new GuildTypeReader()); diff --git a/src/NadekoBot/TypeReaders/ModuleTypeReader.cs b/src/NadekoBot/TypeReaders/ModuleTypeReader.cs index ae93576e..10278060 100644 --- a/src/NadekoBot/TypeReaders/ModuleTypeReader.cs +++ b/src/NadekoBot/TypeReaders/ModuleTypeReader.cs @@ -17,4 +17,25 @@ namespace NadekoBot.TypeReaders return Task.FromResult(TypeReaderResult.FromSuccess(module)); } } + + public class ModuleOrCrTypeReader : TypeReader + { + public override Task Read(ICommandContext context, string input) + { + input = input.ToLowerInvariant(); + var module = NadekoBot.CommandService.Modules.GroupBy(m => m.GetTopLevelModule()).FirstOrDefault(m => m.Key.Name.ToLowerInvariant() == input)?.Key; + if (module == null && input != "actualcustomreactions") + return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "No such module found.")); + + return Task.FromResult(TypeReaderResult.FromSuccess(new ModuleOrCrInfo + { + Name = input, + })); + } + } + + public class ModuleOrCrInfo + { + public string Name { get; set; } + } } From ade2b69a86347097c84e4a96584618b2ace2f74f Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 10 Apr 2017 20:02:18 +0200 Subject: [PATCH 72/98] help updated, commandlist regenerated --- src/NadekoBot/Resources/CommandStrings.Designer.cs | 2 +- src/NadekoBot/Resources/CommandStrings.resx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index c135ff21..ec6654e3 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -7980,7 +7980,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to Play Nadeko slots. Max bet is 999. 3 seconds cooldown per user.. + /// Looks up a localized string similar to Play Nadeko slots. Max bet is 9999. 1.5 second cooldown per user.. /// public static string slot_desc { get { diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 6c67e584..a46b89e8 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -2992,7 +2992,7 @@ slot - Play Nadeko slots. Max bet is 999. 3 seconds cooldown per user. + Play Nadeko slots. Max bet is 9999. 1.5 second cooldown per user. `{0}slot 5` From a0d93c93c2a475d52cedc3a788473df6f25d3ab0 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 10 Apr 2017 20:03:33 +0200 Subject: [PATCH 73/98] Version upped to 1.3a --- docs/Commands List.md | 4 ++-- src/NadekoBot/Services/Impl/StatsService.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/Commands List.md b/docs/Commands List.md index dc705b8e..6c47c7ed 100644 --- a/docs/Commands List.md +++ b/docs/Commands List.md @@ -100,7 +100,7 @@ Commands and aliases | Description | Usage `.bye` | Toggles anouncements on the current channel when someone leaves the server. **Requires ManageServer server permission.** | `.bye` `.byemsg` | Sets a new leave announcement message. Type `%user%` if you want to show the name the user who left. Type `%id%` to show id. Using this command with no message will show the current bye message. You can use embed json from instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.byemsg %user% has left.` `.byedel` | Sets the time it takes (in seconds) for bye messages to be auto-deleted. Set it to `0` to disable automatic deletion. **Requires ManageServer server permission.** | `.byedel 0` or `.byedel 30` -`.warn` | Warns a user. **Requires BanMembers server permission.** | `.warn @b1nzy` +`.warn` | Warns a user. **Requires BanMembers server permission.** | `.warn @b1nzy Very rude person` `.warnlog` | See a list of warnings of a certain user. **Requires BanMembers server permission.** | `.warnlog @b1nzy` `.warnclear` `.warnc` | Clears all warnings from a certain user. **Requires BanMembers server permission.** | `.warnclear @PoorDude` `.warnpunish` `.warnp` | Sets a punishment for a certain number of warnings. Provide no punishment to remove. **Requires BanMembers server permission.** | `.warnpunish 5 Ban` or `.warnpunish 3` @@ -173,7 +173,7 @@ Commands and aliases | Description | Usage `$shoprem` `$shoprm` | Removes an item from the shop by its color. **Requires Administrator server permission.** | `$shoprm 1` `$slotstats` | Shows the total stats of the slot command for this bot's session. **Bot owner only** | `$slotstats` `$slottest` | Tests to see how much slots payout for X number of plays. **Bot owner only** | `$slottest 1000` -`$slot` | Play Nadeko slots. Max bet is 999. 3 seconds cooldown per user. | `$slot 5` +`$slot` | Play Nadeko slots. Max bet is 9999. 1.5 second cooldown per user. | `$slot 5` `$claimwaifu` `$claim` | Claim a waifu for yourself by spending currency. You must spend at least 10% more than her current value unless she set `$affinity` towards you. | `$claim 50 @Himesama` `$divorce` | Releases your claim on a specific waifu. You will get some of the money you've spent back unless that waifu has an affinity towards you. 6 hours cooldown. | `$divorce @CheatingSloot` `$affinity` | Sets your affinity towards someone you want to be claimed by. Setting affinity will reduce their `$claim` on you by 20%. You can leave second argument empty to clear your affinity. 30 minutes cooldown. | `$affinity @MyHusband` or `$affinity` diff --git a/src/NadekoBot/Services/Impl/StatsService.cs b/src/NadekoBot/Services/Impl/StatsService.cs index 570c44ff..b567a72b 100644 --- a/src/NadekoBot/Services/Impl/StatsService.cs +++ b/src/NadekoBot/Services/Impl/StatsService.cs @@ -16,7 +16,7 @@ namespace NadekoBot.Services.Impl private readonly DiscordShardedClient _client; private readonly DateTime _started; - public const string BotVersion = "1.3"; + public const string BotVersion = "1.3a"; public string Author => "Kwoth#2560"; public string Library => "Discord.Net"; From 763bfc08bcc036d8ee464d254ba9e4ce5376f008 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Tue, 11 Apr 2017 00:46:02 +0200 Subject: [PATCH 74/98] prune bugfixes --- src/NadekoBot/Modules/Administration/Administration.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/NadekoBot/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs index 71f20464..0e175083 100644 --- a/src/NadekoBot/Modules/Administration/Administration.cs +++ b/src/NadekoBot/Modules/Administration/Administration.cs @@ -392,13 +392,18 @@ namespace NadekoBot.Modules.Administration [RequireContext(ContextType.Guild)] [RequireUserPermission(ChannelPermission.ManageMessages)] [RequireBotPermission(GuildPermission.ManageMessages)] + [Priority(0)] public async Task Prune(int count) { if (count < 1) return; await Context.Message.DeleteAsync().ConfigureAwait(false); - int limit = (count < 100) ? count : 100; + int limit = (count < 100) ? count + 1 : 100; var enumerable = (await Context.Channel.GetMessagesAsync(limit: limit).Flatten().ConfigureAwait(false)); + if (enumerable.FirstOrDefault()?.Id == Context.Message.Id) + enumerable = enumerable.Skip(1).ToArray(); + else + enumerable = enumerable.Take(count); await Context.Channel.DeleteMessagesAsync(enumerable).ConfigureAwait(false); } @@ -407,6 +412,7 @@ namespace NadekoBot.Modules.Administration [RequireContext(ContextType.Guild)] [RequireUserPermission(ChannelPermission.ManageMessages)] [RequireBotPermission(GuildPermission.ManageMessages)] + [Priority(1)] public async Task Prune(IGuildUser user, int count = 100) { if (count < 1) From daee24af237836d58f644f055beaeeef04c2a381 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:56:22 +0200 Subject: [PATCH 75/98] Update ResponseStrings.zh-CN.resx (POEditor.com) --- .../Resources/ResponseStrings.zh-CN.resx | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.zh-CN.resx b/src/NadekoBot/Resources/ResponseStrings.zh-CN.resx index ae22319e..b120f601 100644 --- a/src/NadekoBot/Resources/ResponseStrings.zh-CN.resx +++ b/src/NadekoBot/Resources/ResponseStrings.zh-CN.resx @@ -2385,128 +2385,128 @@ Fuzzy 竞争比赛游戏时间。 - + 频道 - + 指令 - + 已被踢出 PLURAL - + 群管 - + 第{0}页 - + 原因 - + 新启动执行命令已加 - + 启动执行命令已删 - + 启动执行命令未找到 - + 服务器 - + 该页并无启动执行命令 - + 清除所有启动执行命令 - + 用户 {0} 已被解禁 - + 该用户未找到 - + 用户{0}已被警告 - + 用户 {0} 已被警告,惩罚已执行。 - + 在 {0} 服务器上被警告 - + 在 {0} {1} 被 {2} - + {0} 的所有警告已清除。 - + 该页并无警告。 - + {0} 的警告记录。 - + 没有设定任何惩罚 - + 被{0} 清除 - + 警告惩罚记录 - + 拥有{0} 个警告已不会触动惩罚。 - + 我会给拥有 {1} 个警告的用户执行{0} 惩罚。 - + Slowmode 现在会无视 {0} 身份组。 - + Slowmode不会无视 {0} 身份组。 - + Slowmode 现在会无视用户 {0} 。 - + Slowmode 现在不会无视用户 {0} 。 - + 因下列原因无法领取奖励: - + 你可能已领取这个月的奖励。除非你的赞助金额增加,你只能领取奖励一个月一次。 - + 已被奖励 - + 你的discord账户可能未与Patreon连接。如果你并不明白或不知如何连接 - 你需要去 [Patreon account settings page] (https://patreon.com/settings/account) 然后点击'Connect to discord' 的按钮。 - + Discord账号没有连接 - + 你必须要在patreon赞助该项目才有资格领取奖励。你可以使用命令 {0} 取得网址。 - + 无法支援 - + 你需要在赞助了之后等几个小时。如果你没有,请稍后再试。 - + 稍等片刻 - + 您已领取 {0} 。感谢您支持该项目! - + 奖励只能在每月五号或五号后才能领取。 \ No newline at end of file From 2c30ad9bd94485e5d4874ee004bc4e9327f5bdfa Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:56:25 +0200 Subject: [PATCH 76/98] Update ResponseStrings.zh-TW.resx (POEditor.com) From 8a902ad212131fc1aa88cf025b6eb5b2ec016096 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:56:27 +0200 Subject: [PATCH 77/98] Update ResponseStrings.nl-NL.resx (POEditor.com) From b07d48400176f0815f7430ac1858ef1a1c7549d4 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:56:30 +0200 Subject: [PATCH 78/98] Update ResponseStrings.en-US.resx (POEditor.com) From a97ee7c0e90305dd1e983c25fee1fbb773add6d9 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:56:33 +0200 Subject: [PATCH 79/98] Update ResponseStrings.fr-FR.resx (POEditor.com) --- src/NadekoBot/Resources/ResponseStrings.fr-FR.resx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.fr-FR.resx b/src/NadekoBot/Resources/ResponseStrings.fr-FR.resx index c2ad5917..8e46bc14 100644 --- a/src/NadekoBot/Resources/ResponseStrings.fr-FR.resx +++ b/src/NadekoBot/Resources/ResponseStrings.fr-FR.resx @@ -2323,7 +2323,7 @@ ID du propriétaire: {2} Raison - Nouvelle commande au démarrage ajoutée + Nouvelle commande au démarrage ajoutée. Commande au démarrage retirée. @@ -2350,7 +2350,7 @@ ID du propriétaire: {2} L'utilisateur {0} a été averti. - L'utilisateur {0} a été averti et {1} punition a été appliquée. + L'utilisateur {0} a été averti et la punition {1} a été appliquée. Averti sur le serveur {0} @@ -2359,13 +2359,14 @@ ID du propriétaire: {2} Le {0} à {1} par {2} - Toutes les avertissements ont étés effacés pour {0}. + Tous les avertissements ont été effacés pour {0}. Pas d'avertissement sur cette page. Log d'avertissement pour {0} + Log ou historique ? Pas de punition définie. @@ -2404,7 +2405,7 @@ ID du propriétaire: {2} Déjà récompensé. - Votre compte Discord n'est peut-être pas connecté à Patreon. Si vous n'êtes pas sur de ce que ça veut dire, ou ne savez pas comment le connecter, vous devez aller à la [Page de configurations du compte Patreon](https://patreon.com/settings/account) et cliquer sur 'Connect to discord'. + Votre compte Discord n'est peut-être pas connecté à Patreon. Si vous n'êtes pas sur de ce que ça veut dire, ou ne savez pas comment le connecter, vous devez aller à la [Page de configuration du compte Patreon](https://patreon.com/settings/account) et cliquer sur 'Connect to discord'. Le compte Discord n'est pas connecté From 836a91107a17e12bb7f87da95c8110d1ac76cbc5 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:56:36 +0200 Subject: [PATCH 80/98] Update ResponseStrings.de-DE.resx (POEditor.com) --- .../Resources/ResponseStrings.de-DE.resx | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.de-DE.resx b/src/NadekoBot/Resources/ResponseStrings.de-DE.resx index 81cde44a..6b6a53c3 100644 --- a/src/NadekoBot/Resources/ResponseStrings.de-DE.resx +++ b/src/NadekoBot/Resources/ResponseStrings.de-DE.resx @@ -2451,7 +2451,7 @@ ID des Besitzers: {2} Keine Warnungen auf dieser Seite. - + Warnlog für {0} Keine Bestrafungen gesetzt. @@ -2469,34 +2469,34 @@ ID des Besitzers: {2} Ich werde die Bestrafung {0} an Benutzern mit {1} Warnungen ausführen. - + Slow mode wird jetzt die Rolle {0} ignorieren. - + Slow mode wird nicht mehr die Rolle {0} ignorieren. - + Slow mod witrd jetzt den Benutzer {0} ignorieren. - + Slow mod witrd nicht mehr Benutzer {0} ignorieren. - + Belohnungen konnten nicht beansprucht werden wegen einer dieser Gründe: - + Eventuell haben Sie ihre Belohnung für diesen Monat schon bekommen. Sie können Belohnungen nur einmal pro Monat beanspruchen, außer sie erhören ihre Unterstützung. - + Belohnung schon beansprucht - + Ihr Discord Account ist eventuell nicht mit Patreon verbunden. Wenn Sie unsicher sind was dies bedeutet, oder nicht wissen wie man es verbinded - Sie müssen zu der [Patreon Account Einstellungs Seite](https://patreon.com/settings/account) gehen und den 'Zu Discord verbinden' Knopf betätigen. - + Discord Account nicht verbunden - + Um berechtigt für die Belohnung zu sein, müssen Sie das Projekt auf Patreon unterstützen. Sie können den Befehl {0} benutzen um den Link zu kriegen. Keine Unterstützung @@ -2506,13 +2506,13 @@ ID des Besitzers: {2} Fuzzy - + Bitte warten Sie eine weile - + Sie haben {0} erhalten. Danke für das unterstützen des Projektes! - + Belohnungen können am or nach dem fünften tag jedes Monats beansprucht werden. \ No newline at end of file From d970603317e7c8612d0a76dd3c5572e9d2551021 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:56:39 +0200 Subject: [PATCH 81/98] Update ResponseStrings.he-IL.resx (POEditor.com) From 95012a5e462b5051e25da693b4425ef775483f64 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:56:41 +0200 Subject: [PATCH 82/98] Update ResponseStrings.id-ID.resx (POEditor.com) From e87633b3dd811b76aa7dfd52bdc654e974d728c7 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:56:44 +0200 Subject: [PATCH 83/98] Update ResponseStrings.it-IT.resx (POEditor.com) --- .../Resources/ResponseStrings.it-IT.resx | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.it-IT.resx b/src/NadekoBot/Resources/ResponseStrings.it-IT.resx index 5247c7a6..b675d6a7 100644 --- a/src/NadekoBot/Resources/ResponseStrings.it-IT.resx +++ b/src/NadekoBot/Resources/ResponseStrings.it-IT.resx @@ -751,11 +751,9 @@ Fuzzy Modalità lenta disattivata - Fuzzy Modalità lenta attivata - Fuzzy Ammonizione (Espulso) @@ -883,7 +881,8 @@ Motivo : {1} Errore durante il trasferimento, guarda la console del bot per più informazioni. - + Aggiornamenti sulla presenza + Fuzzy Utente ammonito @@ -935,7 +934,7 @@ Motivo : {1} Classifica - + Premiati con {0} {1} utenti con il ruolo {2}. Non puoi puntare più di {0} @@ -1431,7 +1430,8 @@ Fuzzy Canzone iniziata - + `#{0}` - **{1}** da *{2}* ({3} canzoni) + Fuzzy Pagina {0} della playlist salvata @@ -1614,7 +1614,8 @@ Fuzzy Pagina dei comandi {0} - + Attualmente i permessi del ruolo sono {0}. + Fuzzy Gli utenti ora devono avere il ruolo di {0} per modificare i permessi. @@ -1716,7 +1717,6 @@ Fuzzy Rango competitivo - Fuzzy Competitive Vinte. @@ -1777,7 +1777,8 @@ Fuzzy Fallito a trovare questo film. - + Fonte o lingua non valida. + Fuzzy Scherzo non caricato. @@ -1965,9 +1966,10 @@ Fuzzy Entrato - + `{0}.` {1} [{2:F2}/s] - {3} totali /s and total need to be localized to fit the context - -`1.` +`1.` +Fuzzy Pagina attivitá #{0} @@ -2009,10 +2011,12 @@ Fuzzy Creato a - + Entrato nel canale tra server. + Fuzzy - + Uscito dal canale tra server. + Fuzzy Questo é il tuo token CSC @@ -2193,7 +2197,8 @@ ID del proprietario: {2} Fuzzy - + Il frammento **#{0}** é nello stato {1} con {2} server + Fuzzy **Nome:** {0} **Link:** {1} @@ -2407,19 +2412,15 @@ ID del proprietario: {2} La modalitá lenta ignorerá il ruolo {0}. - Fuzzy La modalitá lenta non ignorerá piú il ruolo {0}. - Fuzzy La modalitá lenta ignorerá l'utente {0}. - Fuzzy La modalitá lenta non ignorerá piú l'utente {0}. - Fuzzy Errore nella richiesta dei premi per le seguenti ragioni: @@ -2444,8 +2445,7 @@ ID del proprietario: {2} Fuzzy - Devi aspettae un po' di ore dopo aver fatto la tua donazione, se non lo hai fatto, prova di nuovo piú tardi - Fuzzy + Devi aspettare un po' di ore dopo aver donato, se non lo hai fatto, prova di nuovo piú tardi. Aspetta un po' di tempo From 5eb725bc288fe9c63ee0c540996765283cad8f99 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:56:47 +0200 Subject: [PATCH 84/98] Update ResponseStrings.ja-JP.resx (POEditor.com) From 295fb6f4c17700b8bf59f1bf32fb0071ef8c3b2a Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:56:49 +0200 Subject: [PATCH 85/98] Update ResponseStrings.ko-KR.resx (POEditor.com) --- .../Resources/ResponseStrings.ko-KR.resx | 587 ++++++++---------- 1 file changed, 245 insertions(+), 342 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.ko-KR.resx b/src/NadekoBot/Resources/ResponseStrings.ko-KR.resx index 239484e4..de5bb4e7 100644 --- a/src/NadekoBot/Resources/ResponseStrings.ko-KR.resx +++ b/src/NadekoBot/Resources/ResponseStrings.ko-KR.resx @@ -127,25 +127,25 @@ 기지가 요청당하지 않았습니다. - {1} 와의 전쟁에서 #{0} 번 기지가 **파괴**되었습니다. + {1}와의 전쟁에서 #{0}번 기지가 **파괴**되었습니다. - {2} 와의 전쟁에서 {0} 가 #{1} 번 기지를 **요청**하지 못했습니다. + {2}와의 전쟁에서 {0}가 #{1}번 기지를 **요청**하지 못했습니다. - {2} 와의 전쟁에서 #{1} 번 기지를 {0} 가 요청하였습니다. + {2}와의 전쟁에서 #{1}번 기지를 {0}가 요청하였습니다. - @{0} 이미 #{1} 번 기지를 요청했습니다. 새로운 기지를 요청 할 수 없습니다. + @{0} 이미 #{1}번 기지를 요청했습니다. 새로운 기지를 요청 할 수 없습니다. - {1} 와의 전쟁에서 @{0} 의 요청이 만료되었습니다. + {1}와의 전쟁에서 @{0}의 요청이 만료되었습니다. - {0} 와의 전쟁에 대한 정보 + {0}와의 전쟁에 대한 정보 유효하지 않은 기지 숫자입니다. @@ -172,13 +172,13 @@ 크기 - {0} 에 대한 전쟁이 이미 시작되었습니다. + {0}에 대한 전쟁이 이미 시작되었습니다. - {0} 에 대한 전쟁이 생성되었습니다. + {0}에 대한 전쟁이 생성되었습니다. - {0} 와의 전쟁이 종료되었습니다. + {0}와의 전쟁이 종료되었습니다. 전쟁이 존재하지않습니다. @@ -212,20 +212,18 @@ 반응 - Fuzzy 커스텀 리액션 통계 - {0} 에 대한 커스텀 리액션 통계가 삭제되었습니다. + {0}에 대한 커스텀 리액션 통계가 삭제되었습니다. 해당 트리거에 대한 통계를 찾지 못했으며, 아무런 행동도 취하지 않았습니다. 트리거 - Fuzzy Autohentai 기능이 정지되었습니다. @@ -234,16 +232,16 @@ 결과를 찾지 못했습니다. - {0} 이(가) 이미 기절했습니다. + {0}이(가) 이미 기절했습니다. - {0} 은(는) 이미 최대 체력입니다. + {0}은(는) 이미 최대 체력입니다. 당신은 이미 {0} 타입 입니다. - 님이 {2}{3} 에게 {0}{1} 을(를) 사용하여서 {4} 의 피해를 입혔습니다. + 님이 {2}{3}에게 {0}{1}을(를) 사용하여서 {4}의 피해를 입혔습니다. Kwoth used punch:type_icon: on Sanity:type_icon: for 50 damage. @@ -253,35 +251,34 @@ 자신을 공격 할 수 없습니다. - {0} 이(가) 기절했습니다! + {0}이(가) 기절했습니다! - {1} 을(를) 사용하여서 {0} 을(를) 치료했습니다. + {1}을(를) 사용하여서 {0}을(를) 치료했습니다. - {0} 의 HP가 {1} 남아 있습니다. + {0}의 HP가 {1} 남아 있습니다. - {0} 을(를) 사용 할 수 없습니다. `{1}ml` 을(를) 입력해서 사용할 수 있는 움직임들의 리스트를 확인하세요. + {0}을(를) 사용 할 수 없습니다. `{1}ml`을(를) 입력해서 사용할 수 있는 움직임들의 리스트를 확인하세요. - {0} 종류 의 공격표 - Fuzzy + {0}의 종류 공격표 효과적이지 않았다. - 당신은 충분한 {0} 가 없습니다. + 당신은 충분한 {0}가 없습니다. - {1} 을(를) 사용하여서 {0} 을(를) 소생했습니다. + {1}을(를) 사용하여서 {0}을(를) 소생했습니다. - {0} 을(를) 사용해서 자기자신을 소생시켰습니다. + {0}을(를) 사용해서 자기자신을 소생시켰습니다. - 당신의 타입이 {0} 에서 {1} 으로 변경되었습니다. + 당신의 타입이 {0}에서 {1}으로 변경되었습니다. 어느정도 효과가 있었다. @@ -293,7 +290,7 @@ 너무 많은 공격을 연속해서 사용했으므로 이동할 수 없습니다! - {0} 의 종류는 {1} 입니다. + {0}의 종류는 {1}입니다. 사용자를 찾을 수 없습니다. @@ -319,38 +316,31 @@ - PLURAL -Fuzzy + PLURAL 사용자 밴 - Fuzzy - 봇의 이름이 {0} 으로 변경되었습니다. + 봇의 이름이 {0}으로 변경되었습니다. - 봇의 상태가 {0} 으로 변경되었습니다. + 봇의 상태가 {0}으로 변경되었습니다. 퇴장 메시지의 자동삭제가 비활성화되었습니다. - Fuzzy - 퇴장 메시지는 앞으로 {0} 초 후에 삭제됩니다. - Fuzzy + 퇴장 메시지는 앞으로 {0}초 후에 삭제됩니다. 현재 퇴장 메시지: {0} - Fuzzy - 퇴장 메시지를 활성화하기 위해서는 {0} 를 입력하십시오. - Fuzzy + 퇴장 메시지를 활성화하기 위해서는 {0}를 입력하세요. 새로운 퇴장 메시지가 설정되었습니다. - Fuzzy 퇴장 알림이 비활성화되었습니다. @@ -377,10 +367,10 @@ Fuzzy {0} 역할을 성공적으로 생성하였습니다. - 텍스트 채널 {0} 이(가) 생성되었습니다. + 텍스트 채널 {0}이(가) 생성되었습니다. - 음성 채널 {0} 이(가) 생성되었습니다. + 음성 채널 {0}이(가) 생성되었습니다. 음소거되었습니다. @@ -396,14 +386,13 @@ Fuzzy 이제 성공적으로 처리된 명령어를 자동삭제합니다. - 텍스트 채널 {0} 를 삭제했습니다. + 텍스트 채널 {0}을(를) 삭제했습니다. - 음성 채널 {0} 를 삭제했습니다. + 음성 채널 {0}을(를) 삭제했습니다. 개인 메시지 - Fuzzy 성공적으로 새로운 기부자를 추가했습니다. 이 유저의 총 기부량은 {0} 👑 입니다. @@ -427,13 +416,13 @@ Fuzzy 환영 메시지에 대한 자동삭제가 비활성화되었습니다. - 환영 메시지는 {0} 초 후에 삭제될 것입니다. + 환영 메시지는 {0}초 후에 삭제될 것입니다. 현재 DM 환영 메시지: {0} - {0} 을(를) 입력하여서 DM 환영 메시지를 활성화시킵니다. + {0}을(를) 입력해서 DM 환영 메시지를 활성화시킵니다. 새로운 DM 환영 메시지가 설정되었습니다. @@ -449,7 +438,7 @@ Fuzzy 현재 환영 메시지: {0} - {0} 를 입력하여서 환영 메시지를 활성화시킵니다. + {0}을(를) 입력해서 환영 메시지를 활성화시킵니다. 새로운 환영 메시지가 설정되었습니다. @@ -464,8 +453,7 @@ Fuzzy 당신은 이 명령어를 당신보다 상위나 동등한 권한관계를 가진 사람에게 쓸 수 없습니다. - 이미지가 {0} 초 후에 생성되었습니다! - Fuzzy + 이미지가 {0}초 후에 생성되었습니다! 유효하지않은 입력 포맷입니다. @@ -474,7 +462,7 @@ Fuzzy 유효하지않은 파라미터입니다. - {0} 님이 {1} 에 입장하였습니다. + {0}님이 {1}에 입장하였습니다. 당신은 {0} 서버에서 퇴장당했습니다. @@ -482,28 +470,27 @@ Fuzzy 사용자 강제퇴장 - Fuzzy 언어 목록 - 서버의 지역이 {0} - {1} 로 변경되었습니다. + 서버의 지역이 {0} - {1}로 변경되었습니다. - 봇의 기본 지역이 {0} - {1} 로 변경되었습니다. + 봇의 기본 지역이 {0} - {1}로 변경되었습니다. - 봇의 언어가 {0} - {1} 로 설정되었습니다. + 봇의 언어가 {0} - {1}로 설정되었습니다. - 지역 설정에 실패했습니다. 이 명령어의 도움말을 참고하십시오. + 지역 설정에 실패했습니다. 이 명령어의 도움말을 참고하십세요. - 이 서버의 언어가 {0} - {1} 로 변경되었습니다. + 이 서버의 언어가 {0} - {1}로 변경되었습니다. - {0} 님이 {1} 에서 퇴장하셨습니다. + {0}님이 {1}에서 퇴장하셨습니다. {0} 서버에서 퇴장하였습니다. @@ -521,42 +508,39 @@ Fuzzy 구독 할 수 있는 로그 이벤트 : - 로그는 앞으로 {0} 을(를) 무시합니다. + 로그는 앞으로 {0}을(를) 무시합니다. - 로그는 {0} 을(를) 더 이상 무시하지 않습니다. + 로그는 {0}을(를) 더 이상 무시하지 않습니다. {0} 이벤트에 대한 로그를 중지하였습니다. - {0} 이(가) 다음 역할에 대한 언급을 요청했습니다. + {0}이(가) 다음 역할에 대한 언급을 요청했습니다. {0} `[봇의 소유자]` 로부터 메시지: - Fuzzy 메시지가 전송되었습니다. - {0} 이(가) {1} 에서 {2} 로 이동했습니다. + {0}이(가) {1}에서 {2}로 이동했습니다. - #{0} 에서 메시지가 삭제되었습니다. + #{0}에서 메시지가 삭제되었습니다. - #{0} 에서 메시지가 업데이트되었습니다. + #{0}에서 메시지가 업데이트되었습니다. 음소거 - PLURAL (users have been muted) -Fuzzy + PLURAL (users have been muted) 음소거 - singular "User muted." -Fuzzy + singular "User muted." 명령어를 수행하기 위한 권한이 부족합니다. @@ -604,10 +588,10 @@ Fuzzy 보호기능 활성화 - {0} 은(는) 이 서버에서 **비활성화**되었습니다. + {0}은(는) 이 서버에서 **비활성화**되었습니다. - {0} 가 활성화되었습니다. + {0}이(가) 활성화되었습니다. 오류. 관리자 권한이 필요합니다. @@ -616,18 +600,16 @@ Fuzzy 활성화된 보호기능이 없습니다. - 사용자의 값은 반드시 {0} 과 {1} 사이의 값이여야 합니다. - Fuzzy + 사용자의 값은 반드시 {0}와(과) {1}사이의 값이여야 합니다. - 만약 {0} 명 이상의 사용자가 {1} 초안에 접속한다면 {2} 합니다. - Fuzzy + 만약 {0}명 이상의 사용자가 {1}초안에 접속한다면 {2} 합니다. - 시간은 {0} 초와 {1} 초 사이의 값이여야 합니다. + 시간은 {0}초와 {1}초 사이의 값이여야 합니다. - {0} 유저의 모든 역할을 성공적으로 삭제했습니다. + {0}의 모든 역할을 성공적으로 삭제했습니다. 역할 삭제에 실패했습니다. 권한이 부족합니다. @@ -642,11 +624,10 @@ Fuzzy 지정된 파라미터가 유효하지 않습니다. - 유효하지 않은 색이거나 권한이 부족하여서 오류가 발생했습니다. - Fuzzy + 유효하지 않은 색이거나 권한이 부족해서 오류가 발생했습니다. - {1} 사용자에 대한 {0} 역할을 성공적으로 제거했습니다. + {1}의 {0} 역할을 성공적으로 제거했습니다. 역할 제거에 실패했습니다. 권한이 부족합니다. @@ -662,14 +643,12 @@ Fuzzy 다루고있었던 메시지를 치웠습니다: {0} - Fuzzy {0} 역할을 리스트에 추가했습니다. - {0} 을(를) 찾을 수 없기때문에 삭제했습니다. - Fuzzy + {0}을(를) 찾을 수 없기때문에 삭제했습니다. {0} 역할은 이미 리스트에 추가된 상태입니다. @@ -694,16 +673,13 @@ Fuzzy 당신은 이미 {0} 역할이 있습니다. - 당신은 이미 독점 자가 배정 역할 {0} 가 있습니다. - Fuzzy + 당신은 이미 독점 자가 배정 역할 {0}이(가) 있습니다. 자가 배정 역할은 이제 하나만 선택 할 수 있습니다! - Fuzzy - {0} 개의 자가 배정 역할이 있습니다. - Fuzzy + {0}개의 자가 배정 역할이 있습니다. 그 역할은 자신이 적용 할 수 없습니다. @@ -713,13 +689,12 @@ Fuzzy 자가 배정 역할은 이제 복수 선택 할 수 있습니다! - Fuzzy 그 역할을 당신에게 추가 할 수 없습니다. `당신보다 상위나 동등한 권한관계를 가진 사람에게 역할을 추가 할 수 없습니다.` - {0} 은(는) 자신이 적용 할 수 있는 역할 목록에서 삭제되었습니다. + {0}은(는) 자신이 적용 할 수 있는 역할 목록에서 삭제되었습니다. 당신은 더 이상 {0} 역할이 아닙니다. @@ -728,7 +703,7 @@ Fuzzy 당신은 이제 {0} 역할입니다. - {1} 유저에게 {0} 역할을 성공적으로 추가했습니다. + {1}님에게 {0} 역할을 성공적으로 추가했습니다. 역할 추가에 실패했습니다. 권한이 부족합니다. @@ -747,19 +722,18 @@ Fuzzy 새로운 채널 주제를 설정했습니다. - Fuzzy - Shard {0} 가 다시 연결되었습니다. + Shard {0}이(가) 다시 연결되었습니다. - Shard {0} 를 다시 연결 중입니다. + Shard {0}을(를) 다시 연결 중입니다. 종료 중... - 사용자는 {1} 초마다 {0} 개 이상의 메시지를 보낼 수 없습니다. + 사용자는 {1}초마다 {0}개 이상의 메시지를 보낼 수 없습니다. 슬로우 모드가 비활성화되었습니다. @@ -769,17 +743,16 @@ Fuzzy 소프트 밴 (강제퇴장) - PLURAL -Fuzzy + PLURAL - {0} 은(는) 이 채널을 무시할 것입니다. + {0}은(는) 이 채널을 무시할 것입니다. - {0} 은(는) 더 이상 이 채널을 무시하지 않을 것입니다. + {0}은(는) 더 이상 이 채널을 무시하지 않을 것입니다. - 만약 사용자가 {0} 개 이상의 같은 메시지를 보내면 {1} 합니다. + 만약 사용자가 {0}개 이상의 같은 메시지를 보내면 {1} 합니다. __무시하는 채널들__: {2} @@ -805,17 +778,15 @@ Fuzzy 사용자 - Fuzzy 사용자 밴 - Fuzzy - {0} 님이 채팅으로부터 **음소거**되었습니다. + {0}님이 채팅으로부터 **음소거**되었습니다. - {0} 님이 채팅으로부터 **음소거 해제**되었습니다. + {0}님이 채팅으로부터 **음소거 해제**되었습니다. 사용자 입장 @@ -824,36 +795,34 @@ Fuzzy 사용자 퇴장 - {0} 은(는) 텍스트와 음성 채팅으로부터 **차단**되었습니다. + {0}님이 텍스트와 음성 채팅으로부터 **차단**되었습니다. 사용자의 역할이 추가되었습니다. - Fuzzy 사용자의 역할이 제거되었습니다. - Fuzzy - {0} 님은 상태는 {1} 입니다. + {0}님의 상태는 {1} 입니다. - {0} 은(는) 텍스트와 음성 채팅으로부터 **차단해제**되었습니다. + {0}님이 텍스트와 음성 채팅으로부터 **차단해제**되었습니다. - {0} 님이 음성채널 {1} 에 입장하셨습니다. + {0}님이 음성채널 {1}에 입장하셨습니다. - {0} 님이 음성채널 {1} 에서 퇴장하셨습니다. + {0}님이 음성채널 {1}에서 퇴장하셨습니다. - {0}님이 음성채널 {1} 에서 {2} 로 이동되었습니다. + {0}님이 음성채널 {1}에서 {2}로 이동되었습니다. - {0} 님이 **음성 음소거**되었습니다. + {0}님이 **음성 음소거**되었습니다. - {0} 님이 **음성 음소거 해제**되었습니다. + {0}님이 **음성 음소거 해제**되었습니다. 음성 채널이 생성되었습니다. @@ -871,36 +840,32 @@ Fuzzy **관리 역할** 혹은 **채널 관리 권한**이 부족해서 {0} 서버에서 `음성 + 텍스트` 기능을 실행 할 수 없습니다. - 당신은 **봇이 관리자 권한이 없음에도** 이 기능을 활성화/비활성화 하고 있습니다. 이로 인해서 문제가 발생 할 수 있으며 이후에 직접 텍스트 채널을 정리해야합니다. + 당신은 **봇이 관리자 권한이 없음에도** 이 기능을 활성화/비활성화 하려고 하고 있습니다. 이로 인해서 문제가 발생 할 수 있으며 이후에 직접 텍스트 채널을 정리해야합니다. 이 기능을 활성화시키기 위해서는 **역할 관리**과 **채널 관리** 권한이 필요합니다. - Fuzzy - 사용자가 텍스트 채팅으로부터 {0} 됐습니다. + 사용자가 텍스트 채팅으로부터 {0} 되었습니다. - 사용자가 텍스트와 음성 채팅으로부터 {0} 됐습니다. + 사용자가 텍스트와 음성 채팅으로부터 {0} 되었습니다. - 사용자가 음성 채팅으로부터 {0} 됐습니다. + 사용자가 음성 채팅으로부터 {0} 되었습니다. - 당신은 {0} 서버에서 soft-밴을 당했습니다. + 당신은 {0} 서버에서 소프트밴을 당했습니다. 사유: {1} - Fuzzy 사용자 밴 해제 - Fuzzy 이전 완료! - Fuzzy - 이전 과정에서 오류가 발생했습니다. 자세한 정보는 봇의 콘솔을 통해서 확인하십시오. + 이전 과정에서 오류가 발생했습니다. 자세한 정보는 봇의 콘솔을 통해서 확인하세요. 현재 상태 업데이트 @@ -909,67 +874,61 @@ Fuzzy 사용자 소프트 밴 - 님이 {1} 에게 {0} 개를 지급했습니다. + 님이 {1}에게 {0}개를 지급했습니다. 다음 기회에 ^_^ - 축하합니다! 당신은 {1} 이상을 굴려서 {0} 을 획득했습니다. - Fuzzy + 축하합니다! 당신은 {1}이상을 굴려서 {0}을(를) 획득했습니다. 덱이 섞였습니다. - Fuzzy - 동전뒤집기의 결과는 {0}. - User flipped tails. -Fuzzy + 동전뒤집기의 결과는 {0} 입니다. + User flipped tails. - 맞췄습니다! 당신은 {0} 을(를) 획득했습니다. + 맞췄습니다! 당신은 {0}을(를) 획득했습니다. - 유효하지 않은 숫자입니다. 당신은 1개부터 {0} 개까지만 동전을 뒤집을 수 있습니다. - Fuzzy + 유효하지 않은 숫자입니다. 당신은 1개부터 {0}개까지만 동전을 뒤집을 수 있습니다. - {1} 을(를) 받으려면 이 메시지에 {0} 리액션을 추가하세요. - Fuzzy + {1}을(를) 받으려면 이 메시지에 {0} 리액션을 추가하세요. - 이 이벤트는 최대 {0} 시간 동안 활성화됩니다. + 이 이벤트는 최대 {0}시간 동안 활성화됩니다. 플라워 리액션 이벤트가 시작되었습니다. - 님이 {1} 에게 {0} 개를 선물하셨습니다. + 님이 {1}에게 {0}개를 선물하셨습니다. X has gifted 15 flowers to Y - {0} 님은 {1} 개를 보유중입니다. + {0}님은 {1}개를 보유중입니다. X has Y flowers - + 앞면 리더보드 - {2} 역할의 {1} 명의 사용자에게 {0} 를 보상하였습니다. - Fuzzy + {2} 역할의 {1}명의 사용자에게 {0}을(를) 보상하였습니다. - {0} 보다 더 배팅 할 수 없습니다. + {0}보다 더 배팅 할 수 없습니다. - {0} 보다 적게 배팅 할 수 없습니다. + {0}보다 적게 배팅 할 수 없습니다. - 당신은 충분한 {0} 이(가) 없습니다. + 당신은 충분한 {0}이(가) 없습니다. 덱에 더 이상 카드가 없습니다. @@ -983,47 +942,42 @@ Fuzzy 배팅 - Fuzzy 대박!!! 축하합니다!!! x{0} - 한 {0}, x{1} - Fuzzy + {0} 한 개를 맞추셨네요! x{1} - 와! 운이 좋습니다! 같은 종류의 세개! x{0} - Fuzzy + 와! 운이 좋습니다! 트리플입니다! x{0} - 잘 했습니다! {0} 두게 - x{1} + 잘했습니다! {0} 두 개를 맞추셨습니다! - x{1} Fuzzy 얻은 액수 - Fuzzy - 사용자는 반드시 {0} 를 얻기 위해서 비밀 코드를 입력해야합니다. + 사용자는 {0}을(를) 얻기 위해서 비밀 코드를 입력해야합니다. +{1}초 동안 유효합니다. 아무에게도 알려주지 마세요. - SneakyGame 이벤트가 종료되었습니다. {0} 명의 사용자들이 보상을 받았습니다. + SneakyGame 이벤트가 종료되었습니다. {0}명의 사용자들이 보상을 받았습니다. SneakyGameStatus 이벤트가 시작되었습니다. - Fuzzy 뒷면 - {1} 에게서 {0} 을(를) 성공적으로 빼앗았습니다 + {1}에게서 {0}을(를) 성공적으로 빼앗았습니다. - {1} 님이 {2} 만큼을 가지고있지 않기 때문에 {0} 을(를) 회수 할 수 없습니다. - Fuzzy + {1}님이 {2}만큼을 가지고있지 않기 때문에 {0}을(를) 회수 할 수 없습니다. 목차로 돌아가기 @@ -1036,11 +990,9 @@ Fuzzy Patreon( <0> )이나 Paypal( <1> )을 통해서 프로젝트를 후원 할 수 있습니다. - Fuzzy 명령어와 가명 - Fuzzy 명령어 목록이 재생성되었습니다. @@ -1050,17 +1002,16 @@ Fuzzy 예시 : `{0}h >8ball` - 입력하신 명령어를 찾을 수 없습니다. 입력하시기 전에 유효한 명령어인지 확인해주십시오. + 입력하신 명령어를 찾을 수 없습니다. 입력하시기 전에 유효한 명령어인지 확인해주세요. 설명 - Fuzzy - Patreon <{0}> 이나 -Paypal <{1}> 에서 + Patreon <{0}>이나 +Paypal <{1}>에서 NadekoBot 프로젝트를 지원할 수 있습니다. -Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시오. +Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마세요. **감사합니다** ♥️ @@ -1082,68 +1033,56 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 그 모듈은 존재하지 않습니다. - {0} 서버의 권한이 필요합니다. + 서버의 {0} 권한이 필요합니다. 목차 사용법 - Fuzzy - Autohentai 기능이 활성화되었습니다. 다음의 태그와 함께 {0} 초마다 사진이 올라옵니다. -태그 : -{1} - Fuzzy + Autohentai 기능이 활성화되었습니다. 다음의 태그와 함께 {0}초마다 사진이 올라옵니다. +태그 : {1} 태그 - Fuzzy - 동물 경주 - Fuzzy + 동물 레이스 참가자가 충분히 없어서 시작하지 못했습니다. 참가자가 모두 모였습니다! 즉시 시작하겠습니다. - Fuzzy - {0} 이(가) {1} (으)로 참가했습니다. - Fuzzy + {0}이(가) {1}(으)로 참가했습니다. - {0} 님이 {1} 으로써 참가하였고, {2} 을(를) 걸었습니다! - Fuzzy + {0}님이 {1}(으)로 참가하였고, {2}을(를) 걸었습니다! - {0}jr 를 입력해서 레이스에 참가합니다. + {0}jr을 입력해서 레이스에 참가합니다. 20초 동안 기다리거나, 방이 가득 차면 시작됩니다. - Fuzzy - {0} 명의 참가자와 함께 시작합니다. + {0}명의 참가자와 함께 시작합니다. - {0} 이(가) {1} (으)로 레이스를 이겼습니다! - Fuzzy + {0}이(가) {1}(으)로 레이스를 이겼습니다! - {0} 이(가) {1} (으)로 레이스를 이겼고 {2} 을 획득했습니다! - Fuzzy + {0}이(가) {1}(으)로 레이스를 이겼고 {2}을(를) 획득했습니다! - 유효하지 않은 숫자입니다. 한번에 {0}-{1} 의 주사위를 던질 수 있습니다. - Fuzzy + 유효하지 않은 숫자입니다. 한번에 {0}-{1}개의 주사위를 던질 수 있습니다. - 님이 {0} 를 굴렸습니다. + 님이 {0}을(를) 굴렸습니다. Someone rolled 35 @@ -1152,51 +1091,45 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 레이스 시작에 실패했습니다. 다른 레이스가 진행중입니다. - Fuzzy 이 서버에 레이스가 존재하지 않습니다. 두번째 숫자는 첫번째 숫자보다 큰 숫자여야 합니다. - Fuzzy 마음의 변화 - Fuzzy 요구한 사람 - Fuzzy 이혼 좋아하는 사람 - Fuzzy - 아무 와이프도 클레임되지 않았습니다. - Fuzzy + 아무 와이프도 요청되지 않았습니다. 최고의 와이프 - 당신의 친밀감이 이미 그 와이프로 설정 했거나 당신에게 친밀감이 없는 상태의 와이프에게 친밀감 삭제를 시도했습니다. + 당신의 친밀감이 이미 그 와이프로 설정 되었거나 당신에게 친밀감이 없는 상태의 와이프에게 친밀감 삭제를 시도했습니다. - 친밀감이 {0} 에서 {1} 으로 변경되었습니다. + 친밀감이 {0}에서 {1}(으)로 변경되었습니다. *도덕성이 의심스럽습니다.*🤔 Make sure to get the formatting right, and leave the thinking emoji - 친밀감을 다시 바꾸기 위해서는 {0} 시간 {1} 분을 기다려야합니다. + 친밀감을 다시 바꾸기 위해서는 {0}시간 {1}분을 기다려야합니다. 당신의 친밀감은 초기화되었습니다. 당신이 좋아하는 사람은 더 이상 없습니다. @@ -1205,17 +1138,17 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 님이 {0}의 와이프가 되고싶어합니다. - 님이 {1} 에 {0} 님을 와이프로 요구했습니다. + 님이 {1}에 {0}님을 와이프로 요구했습니다. - 당신을 좋아하는 와이프와 이혼했습니다. {0} 님이 보상금으로 {1} 만큼을 받았습니다. + 당신을 좋아하는 와이프와 이혼했습니다. {0}님이 보상금으로 {1}을(를) 받았습니다. 자기 자신에게 친밀감을 설정 할 수 없습니다. 🎉 그들의 사랑이 성취되었습니다! 🎉 -{0} 의 새로운 가치는 {1} 입니다! +{0}의 새로운 가치는 {1} 입니다! 그렇게 싼 와이프는 없습니다. 와이프를 얻기 위해서는 실제 가치보다 낮더라도 {0} 만큼을 지불해야합니다. @@ -1228,11 +1161,9 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 자기자신을 클레임 할 수 없습니다. - Fuzzy 당신은 최근에 이혼하셨습니다. 다시 이혼하려면 {0} 시간 {1} 분을 기다려야 합니다. - Fuzzy 아무도 없음 @@ -1241,12 +1172,10 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 당신을 좋아하지 않는 와이프와 이혼했습니다. 당신은 {0}을 돌려받았습니다. - 8ball - Fuzzy + 아크로포비아 - Fuzzy 아무런 제출 없이 게임이 끝났습니다. @@ -1261,36 +1190,35 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 아크로포비아 게임이 이미 이 채널에서 진행 중입니다. - 게임이 시작되었습니다. {0} 머리글자를 사용해서 문장 만드십시오. - Fuzzy + 게임이 시작되었습니다. {0} 머리글자를 사용해서 문장 만드세요. - 제출까지 {0} 초 남았습니다. + 제출까지 {0}초 남았습니다. - {0} 가 그의 문장을 입력했습니다. (합계: {1}) + {0}이(가) 그의 문장을 입력했습니다. (합계: {1}) - 제출번호를 입력해서 투표를 하십시오. + 제출하고자 하는 번호를 입력해서 투표를 하세요. - {0} 가 투표했습니다! + {0}이(가) 투표했습니다! - 우승자는 {1} 포인트를 가진 {0} 입니다. + 우승자는 {1}포인트를 가진 {0} 입니다. - {0} 님이 서버에서 유일한 제출자이기 때문에 승리했습니다. + {0}님이 서버에서 유일한 제출자이기 때문에 승리했습니다. - 문제 + 질문 - 비겼습니다! 둘다 {0} 을(를) 선택했습니다. + 비겼습니다! 둘다 {0}을(를) 선택했습니다. - {0} 가 승리했습니다! {1} 은(는) {2} 을(를) 이겼습니다. + {0}이(가) 승리했습니다! {1}은(는) {2}을(를) 이겼습니다. 제출이 마감되었습니다. @@ -1317,12 +1245,11 @@ Discord 닉네임이나 ID를 메시지에 남겨 두는 것을 잊지 마십시 이 채널에서 통화 생성이 활성화되었습니다. - {0} 무작위 {1} 가 등장했습니다! - plural -Fuzzy + {0} 무작위 {1}이(가) 등장했습니다! + plural - 무작위 {0} 가 등장했습니다! + 무작위 {0}이(가) 등장했습니다! 질문 로딩에 실패하였습니다. @@ -1344,20 +1271,19 @@ Fuzzy 리더 보드 - Fuzzy - 당신은 충분한 {0} 이(가) 없습니다. + 당신은 충분한 {0}이(가) 없습니다. 결과가 없습니다. - 이(가) {0} 을(를) 뽑았습니다. + 이(가) {0}을(를) 뽑았습니다. Kwoth picked 5* - {0} 이(가) {1} 을(를) 설치했습니다. + {0}이(가) {1}을(를) 심었습니다. Kwoth planted 5* @@ -1367,24 +1293,22 @@ Fuzzy 트리비아 게임 - {0} 님이 맞췄습니다! 답은 {1} 입니다. + {0}님이 맞췄습니다! 답은 {1} 입니다. 이 서버에서 진행중인 트리비아 게임이 없습니다. - {0} 이(가) {1} 포인트를 갖고있습니다. + {0}이(가) {1}포인트를 갖고있습니다. 이 질문 후에 중지합니다. 시간초과! 정확한 답은 {0} 입니다. - Fuzzy - {0} 님이 맞춰서 게임을 이겼습니다! 답은 {1} 입니다. - Fuzzy + {0}님이 맞춰서 게임을 이겼습니다! 답은 {1} 입니다. 당신을 상대로 플레이 할 수 없습니다. @@ -1399,7 +1323,7 @@ Fuzzy 님이 TicTacToe 게임을 생성하였습니다. - {0} 님이 이겼습니다! + {0}님이 이겼습니다! 3개 일치 @@ -1418,7 +1342,7 @@ Fuzzy {0} 대 {1} - {0} 개의 곡을 대기열에 추가하는 중... + {0}개의 곡을 대기열에 추가하는 중... 자동재생이 비활성화되었습니다. @@ -1431,7 +1355,6 @@ Fuzzy 디렉토리 대기열 추가가 완료되었습니다. - Fuzzy 페어플레이 @@ -1458,13 +1381,13 @@ Fuzzy 이제 최대 재생시간에 제한이 없습니다. - 최대 재생시간이 {0} 초로 설정되었습니다. + 최대 재생시간이 {0}초로 설정되었습니다. 이제 음악 대기열 크기는 제한이 없습니다. - 음악 대기열 크기가 {0} 곡으로 변경되었습니다. + 음악 대기열 크기가 {0}곡으로 변경되었습니다. 당신은 이 서버의 음성채널에 있어야 합니다. @@ -1491,10 +1414,10 @@ Fuzzy 노래 재생 중 - `#{0}` - {2} 님의 재생목록 **{1}** ({3} 곡) + `#{0}` - {2}님의 재생목록 **{1}** ({3} 곡) - 저장된 재생목록의 {0} 번째 페이지 + 저장된 재생목록의 {0}번째 페이지 재생목록이 삭제되었습니다. @@ -1512,7 +1435,7 @@ Fuzzy 재생목록이 저장되었습니다. - {0} 초 한계 + {0}초 한계 대기열 @@ -1524,7 +1447,7 @@ Fuzzy 음악 대기열이 초기화되었습니다. - 대기열이 {0}/{0} 으(로) 가득찼습니다. + 대기열이 {0}/{0}으(로) 가득찼습니다. 곡 삭제됨 @@ -1556,7 +1479,6 @@ Fuzzy `{0}:{1}`로 이동하였습니다. - Fuzzy 곡을 섞었습니다. @@ -1569,7 +1491,6 @@ Fuzzy 바뀐 위치 - Fuzzy 무제한 @@ -1588,7 +1509,6 @@ Fuzzy 허락함 - Fuzzy {0} 역할에게 모든 모듈의 사용을 비활성화했습니다. @@ -1612,10 +1532,10 @@ Fuzzy {0} (ID {1})님을 블랙리스트했습니다 - 명령어 {0} 은(는) 이제 {1}초 재사용 대기시간이 있습니다. + 명령어 {0}은(는) 이제 {1}초 재사용 대기시간이 있습니다. - 이제 명령어 {0} 이 재사용 대기시간이 없고 기존의 모든 재사용 대기시간이 삭제되었습니다. + 이제 명령어 {0}이(가) 재사용 대기시간이 없고 기존의 모든 재사용 대기시간이 삭제되었습니다. 명령어 재사용 대기시간이 설정되지 않았습니다. @@ -1624,28 +1544,25 @@ Fuzzy 명령어 값 - 채널 {2} 에서 {0} {1} 의 사용을 비활성화시켰습니다. + 채널 {2}에서 {0} {1}의 사용을 비활성화시켰습니다. - 채널 {2} 에서 {0} {1} 의 사용을 활성화시켰습니다. + 채널 {2}에서 {0} {1}의 사용을 활성화시켰습니다. 거절함 - Fuzzy - 필터링 된 단어 목록에 {0} 을 추가했습니다. - Fuzzy + 필터링 된 단어 목록에 {0}을(를) 추가했습니다. 필터링 된 단어 목록 - 필터링 된 단어 목록에서 {0} 을 삭제했습니다. - Fuzzy + 필터링 된 단어 목록에서 {0}을(를) 삭제했습니다. - 유효하지 않은 두번째 파라미터입니다. ( {0} 와(과) {1} 사이의 숫자여야 합니다.) + 유효하지 않은 두번째 파라미터입니다. ({0}와(과) {1}사이의 숫자여야 합니다.) 초대 필터링이 이 채널에서 비활성화되었습니다. @@ -1660,10 +1577,10 @@ Fuzzy 초대 필터링이 이 서버에서 활성화되었습니다. - {0} 권한을 #{1} 에서 #{2} (으)로 이동했습니다. + {0} 권한을 #{1}에서 #{2}(으)로 이동했습니다. - 색인 #{0} 에 대한 권한을 찾을 수 없습니다. + 색인 #{0}에 대한 권한을 찾을 수 없습니다. 아무런 값이 설정되지 않았습니다. @@ -1692,33 +1609,32 @@ Fuzzy #{0} - {1} 권한을 삭제했습니다. - {2} 역할에 대한 {0} {1} 의 사용을 비활성화했습니다. + {2} 역할에 대한 {0} {1}의 사용을 비활성화했습니다. - {2} 역할에 대한 {0} {1} 의 사용을 활성화했습니다. + {2} 역할에 대한 {0} {1}의 사용을 활성화했습니다. 초. Short of seconds. - 이 서버에서 {0} {1} 의 사용을 비활성화했습니다. + 이 서버에서 {0} {1}의 사용을 비활성화했습니다. - 이 서버에서 {0} {1} 의 사용을 활성화했습니다. + 이 서버에서 {0} {1}의 사용을 활성화했습니다. - {0} (ID {1} ) 님을 블랙리스트에서 해제하였습니다. - Fuzzy + {0} (ID {1} )님을 블랙리스트에서 해제하였습니다. 수정불가 - {2} 사용자의 {0} {1} 의 사용을 비활성화했습니다. + {2} 사용자의 {0} {1}의 사용을 비활성화했습니다. - {2} 사용자의 {0} {1} 의 사용을 활성화했습니다. + {2} 사용자의 {0} {1}의 사용을 활성화했습니다. 더 이상 권한 경고를 표시하지 않습니다. @@ -1751,7 +1667,7 @@ Fuzzy 당신의 자동번역 언어가 제거되었습니다. - 당신의 자동번역 언어가 {0}>{1} 로 설정되었습니다. + 당신의 자동번역 언어가 {0}>{1}으(로) 설정되었습니다. 이 채널의 자동번역을 시작합니다. @@ -1800,11 +1716,9 @@ Fuzzy 정의: - Fuzzy 시청 종료 - Fuzzy 에피소드 @@ -1844,7 +1758,6 @@ Fuzzy 유효하지 않은 소스 또는 언어입니다. - Fuzzy 농담이 로드되지 않았습니다. @@ -1869,7 +1782,7 @@ Fuzzy {0}의 MAL 프로필 - 봇의 소유자가 MashapeApiKey을 설정하지 않아서 이 기능을 사용 할 수 없습니다. + 봇의 소유자가 MashapeApiKey를 설정하지 않아서 이 기능을 사용 할 수 없습니다. 최소/최대 @@ -1893,11 +1806,10 @@ Fuzzy osu! 정보 검색에 실패했습니다. - {0} 개 이상의 이미지가 발견되었습니다. 무작위로 {0}개를 표시합니다. - Fuzzy + {0}개 이상의 이미지가 발견되었습니다. 무작위로 {0}개를 표시합니다. - 사용자를 찾을 수 없습니다! 다시 시도하기 전에 지역과 배틀태그를 확인해주십시오 + 사용자를 찾을 수 없습니다! 다시 시도하기 전에 지역과 배틀태그를 확인해주세요. 볼 예정 @@ -1943,28 +1855,24 @@ Fuzzy 검색어를 입력해주세요. - Fuzzy 상태 - 저장된 Url - Fuzzy + 상점 url - 스트리머 {0} 은(는) 오프라인입니다. + 스트리머 {0}은(는) 오프라인입니다. - 스트리머 {0} 은(는) {1} 명의 시청자와 함께 온라인입니다. - Fuzzy + 스트리머 {0}은(는) {1}명의 시청자와 함께 온라인입니다. - 당신은 이 서버에서 {0} 개의 스트리밍을 팔로우 중입니다. + 당신은 이 서버에서 {0}개의 스트리밍을 팔로우 중입니다. 당신은 이 서버에서 어떠한 스트리밍도 팔로우하지 않았습니다. - Fuzzy 스트리밍이 없습니다. @@ -2010,13 +1918,12 @@ Fuzzy 시청중 - Fuzzy 해당 용어에 대한 특정 Wikia를 찾지 못했습니다. - 목적 Wikia를 입력하고 검색 쿼리를 입력하십시오. + 목적 Wikia를 입력하고 검색 쿼리를 입력하세요. 페이지를 찾지 못했습니다. @@ -2025,7 +1932,7 @@ Fuzzy 바람의 속도 - {0} 번째로 많은 밴을 당한 챔피언 + {0}번째로 많은 밴을 당한 챔피언 당신의 문장을 Yodify하지 못했습니다. @@ -2042,7 +1949,7 @@ Fuzzy 활성 페이지 #{0} - 총 {0} 명의 사용자. + 총 {0}명의 사용자. 저자 @@ -2054,7 +1961,7 @@ Fuzzy {0}calc 명령어의 기능 목록 - 이 채널의 {0} 은 {1} 입니다. + 이 채널의 {0}은(는) {1} 입니다. 채널 주제 @@ -2063,31 +1970,28 @@ Fuzzy 실행된 명령어 - {0} {1} 은(는) {2} {3} 와(과) 같습니다. + {0} {1}은(는) {2} {3}와(과) 같습니다. 변환기에서 사용할수있는 단위 - 단위를 찾지 못해서 {0} 을(를) {1} (으)로 변환 할 수 없습니다. - Fuzzy + 단위를 찾지 못해서 {0}을(를) {1}(으)로 변환 할 수 없습니다. - 단위의 종류가 같지 않기때문에 {0} 을(를) {1} (으)로 변환 할 수 없습니다. - Fuzzy + 단위의 종류가 같지 않기때문에 {0}을(를) {1}(으)로 변환 할 수 없습니다. - 작성 시간: + 작성 시간 크로스 서버 채널에 입장했습니다. - Fuzzy 크로스 서버 채널에서 퇴장했습니다. - 이것은 당신의 CSC 토큰입니다. + 이것이 당신의 CSC 토큰입니다. 커스텀 이모지 @@ -2103,7 +2007,6 @@ Fuzzy 색인이 범위를 벗어났습니다. - Fuzzy {0} 역할의 사용자 목록 @@ -2116,10 +2019,10 @@ Fuzzy Invalid months value/ Invalid hours value - 디스코드 입장 + 디스코드 가입일 - 서버 입장 + 서버 가입일 ID: {0} @@ -2130,7 +2033,7 @@ Fuzzy 이 페이지에서 서버를 찾을 수 없습니다. - 리피터 목록 + 메시지 반복 목록 맴버 @@ -2142,7 +2045,7 @@ Fuzzy 메시지 - 메시지 리피터 + 메시지 반복 이름 @@ -2195,7 +2098,7 @@ Fuzzy 인용구가 추가되었습니다. - 인용구 #{0} 가 삭제되었습니다. + 인용구 #{0}이(가) 삭제되었습니다. 지역 @@ -2204,16 +2107,16 @@ Fuzzy 가입 날짜 - 제가 {2} `({3:d.M.yyyy.} at {4:HH:mm})`에 {0} 에게 {1}을(를) 상기시킬 것입니다. + {2}마다 {0}에게 {1}을(를) 상기시킵니다. `({3:d.M.yyyy.} {4:HH:mm})` - 유효하지않은 시간 포맷입니다. 명령어 목록을 확인하십시오. + 유효하지 않은 시간 포맷입니다. 명령어 목록을 확인하세요. 새로운 상기 템플릿이 설정되었습니다. - {0} 을 {1} 일 {2} 시간 {3} 분마다 반복합니다. + {0}을(를) {1}일 {2}시간 {3}분마다 반복합니다. 반복 메시지 목록 @@ -2222,7 +2125,7 @@ Fuzzy 이 서버에 반복 메시지가 실행하고있지 않습니다. - #{0} 이 정지되었습니다. + #{0}이(가) 정지되었습니다. 이 서버에서 반복 메시지를 찾을 수 없습니다. @@ -2240,17 +2143,16 @@ Fuzzy {1} 역할에 대한 페이지 #{0} - 색상 포맷이 정확하지 않습니다. `#00FF00`을 사용해보십시오. + 색상 포맷이 정확하지 않습니다. 예를들어 `#00FF00`을 사용해보세요. {0} 역할의 색상 로테이션을 시작했습니다. - Fuzzy {0} 역할의 색상 로테이션을 중지했습니다. - 이 서버의 {0} 은 {1} 입니다. + 이 서버의 {0}은(는) {1} 입니다. 서버 정보 @@ -2262,7 +2164,7 @@ Fuzzy Shard 통계 - Shard **#{0}** 이 {1} 상태이고 {2} 서버에 있습니다. + Shard **#{0}**이 {1} 상태이고 {2} 서버에 있습니다. **이름:** {0} **링크:** {1} @@ -2271,7 +2173,7 @@ Fuzzy 특수 이모지를 찾을 수 없습니다. - {0} 개의 곡을 재생중이며, {1} 개의 대기열이 있습니다. + {0}개의 곡을 재생중이며, {1}개의 대기열이 있습니다. 텍스트 채널 @@ -2283,7 +2185,7 @@ Fuzzy 작동 시간 - {1} 의 {0} 은(는) {2} 입니다. + {1}의 {0}은(는) {2} 입니다. Id of the user kwoth#1234 is 123123123123 @@ -2305,38 +2207,38 @@ Fuzzy 이 서버에서 이미 투표가 진행되고있습니다. - 📃 {0} 님이 투표를 생성하였습니다. + 📃 {0}님이 투표를 생성하였습니다. - `{0}.` {2} 표를 가진 {1}. + `{0}.` {2}표를 획득한 {1}이(가) 되었습니다. - {0} 님이 투표하였습니다. + {0}님이 투표하였습니다. Kwoth voted. - 해당 답변 번호와 함께 개인 메시지를 보내십시오. + 해당 답변 번호와 함께 개인 메시지를 보내세요. - 해당 답변 번호와 함께 여기에 메시지를 보내십시오. + 해당 답변 번호와 함께 여기에 메시지를 보내세요. - {0} 님, 투표해주셔서 감사합니다 + {0}님, 투표해주셔서 감사합니다 - {0} 개의 표가 투표되었습니다. + {0}개의 표가 투표되었습니다. - `{0}pick`을 입력해서 획득하십시오. + `{0}pick`을 입력해서 획득하세요. - `{0}pick`을 입력해서 획득하십시오. + `{0}pick`을 입력해서 획득하세요. 사용자를 찾지 못했습니다. - {0} 페이지 + {0}페이지 이 서버의 음성 채널에 있어야합니다. @@ -2345,13 +2247,13 @@ Fuzzy 음성채널 역할이 없습니다. - {0} 은(는) 음성과 텍스트 채팅으로 부터 {1} 분간 **음소거**되었습니다. + {0}은(는) 음성과 텍스트 채팅으로 부터 {1} 분간 **음소거**되었습니다. - 음성채널 {0} 에 입장하는 사용자는 {1} 역할을 얻게됩니다. + 음성채널 {0}에 입장하는 사용자는 {1} 역할을 얻게됩니다. - 음성채널 {0} 에 입장하는 사용자는 더이상 {1} 역할을 얻지 못합니다. + 음성채널 {0}에 입장하는 사용자는 더이상 {1} 역할을 얻지 못합니다. 음성채널 역할 @@ -2372,16 +2274,16 @@ Fuzzy 가명을 찾지 못했습니다. - {0} 을(를) 입력하면 이제 {1} 의 가명입니다. + {0}을(를) 입력하면 이제 {1}이(가) 입력됩니다. 가명 목록 - 트리거 {0} 의 가명을 삭제했습니다. + 트리거 {0}의 가명을 삭제했습니다. - 트리거 {0} 은(는) 가명이 없었습니다. + 트리거 {0}은(는) 가명이 없었습니다. 경쟁전 플레이 시간 @@ -2400,7 +2302,7 @@ Fuzzy 관리자 - {0} 페이지 + {0}페이지 사유 @@ -2424,46 +2326,46 @@ Fuzzy 모든 시작 명령어를 삭제했습니다. - 사용자 {0} 님이 밴에서 해제되었습니다. + 사용자 {0}님이 밴에서 해제되었습니다. 사용자를 찾을 수 없습니다. - 사용자 {0} 님이 경고를 받았습니다. + 사용자 {0}님이 경고를 받았습니다. - 사용자 {0} 님이 경고를 받았고, {1} 처벌이 적용되었습니다. + 사용자 {0}님이 경고를 받았고, {1} 처벌이 적용되었습니다. {0} 서버에 경고했습니다. - {0} {1} 에 {2} 이(가) + {0} {1}에 {2}이(가) - {0} 님이 모든 경고를 삭제했습니다. + {0}님이 모든 경고를 삭제했습니다. 이 페이지에는 경고가 없습니다. - {0} 의 경고 기록 + {0}의 경고 기록 처벌이 설정되지 않았습니다. - {0} 이(가) 제거했습니다. + {0}님이 초기화했습니다. 경고 처벌 목록 - {0} 개의 경고를 받은 사용자에 대한 처벌을 하지않습니다. + {0}개의 경고를 받은 사용자에 대한 처벌을 하지않습니다. - {1} 개의 경고를 받은 사용자에게 {0} 처벌을 내립니다. + {1}개의 경고를 받은 사용자에게 {0} 처벌을 내립니다. 이제 슬로우모드는 {0} 역할에게 적용되지 않습니다. @@ -2472,40 +2374,41 @@ Fuzzy 이제 슬로우모드는 {0} 역할에게 적용됩니다. - 이제 슬로우모드는 {0} 님에게 적용되지 않습니다. + 이제 슬로우모드는 {0}님에게 적용되지 않습니다. - 이제 슬로우모드는 {0} 님에게 적용됩니다. + 이제 슬로우모드는 {0}님에게 적용됩니다. - 다음과 같은 이유로 인해서 보상을 요청하지 못했습니다: + 다음과 같은 이유로 인해서 보상을 요청하지 못했습니다. 당신은 이미 이번달의 보상을 받은 것 같습니다. 당신의 후원금을 올리지 않는 이상 한 달에 한 번만 보상을 받을 수 있습니다. - 이미 지급되었습니다. + 이미 지급되었습니다 - 당신의 디스코드 계정이 Patreon에 연결되지 않았습니다. 이것이 무슨 뜻인지 모르거나, 어떻게 연결하는지 모른다면 - [Patreon 계정 설정 페이지] (https://patreon.com/settings/account) 에 접속해서 'Connect to discord' 버튼을 클릭하십시오. + 당신의 디스코드 계정이 Patreon에 연결되지 않았습니다. 이것이 무슨 뜻인지 모르거나, 어떻게 연결하는지 모른다면, +[Patreon 계정 설정 페이지] (https://patreon.com/settings/account)에 접속해서 'Connect to discord' 버튼을 클릭하세요. - 디스코드 계정이 연결되지 않았습니다. + 디스코드 계정이 연결되지 않았습니다 보상을 받을 수 있는 자격을 얻기 위해서는 Patreon에서 프로젝트를 후원해야 합니다. {0} 명령어를 이용해서 링크를 얻을 수 있습니다. - 후원 중이지 않습니다. + 후원 중이지 않습니다 - 다시 시도하지 않았다면, 후원을 한 후에 몇 시간을 기다려야합니다. + 후원을 한 후에 몇 시간을 기다려야합니다, 그렇지 않다면 나중에 다시 시도해주세요. - 잠시만 기다려주십시오. + 잠시만 기다려주세요 - {0} 을 받았습니다. 프로젝트를 후원 해주셔서 감사합니다! + {0}을(를) 받았습니다. 프로젝트를 후원 해주셔서 감사합니다! 보상은 매 달 5일에 요구 할 수 있습니다. From bad80381bd6456ffe9ee6f9f978462dae5a22de1 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:56:52 +0200 Subject: [PATCH 86/98] Update ResponseStrings.nb-NO.resx (POEditor.com) From 373753b40fe646de1779469e6937beb0ae2c7e89 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:56:55 +0200 Subject: [PATCH 87/98] Update ResponseStrings.pl-PL.resx (POEditor.com) From 2ed450944165a7007ab7031871ffbf2b0386ce86 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:56:58 +0200 Subject: [PATCH 88/98] Update ResponseStrings.pt-BR.resx (POEditor.com) --- src/NadekoBot/Resources/ResponseStrings.pt-BR.resx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.pt-BR.resx b/src/NadekoBot/Resources/ResponseStrings.pt-BR.resx index a416a95e..f5819b5a 100644 --- a/src/NadekoBot/Resources/ResponseStrings.pt-BR.resx +++ b/src/NadekoBot/Resources/ResponseStrings.pt-BR.resx @@ -2391,7 +2391,7 @@ OwnerID: {2} Comando de Texto - Chutado + Kickados PLURAL @@ -2485,7 +2485,7 @@ OwnerID: {2} Já recompensado - Sua conta do discord pode não estar conectada ao Patreon. Se você não tem certeza do que isso significa, ou não sabe como conectá-la - Você deve ir para [Página de configurações de conta do Patreon)(https://patreon.com/settings/account) e clicar em 'Connect to discord' button. + Sua conta do discord pode não estar conectada ao Patreon. Se você não tem certeza do que isso significa, ou não sabe como conectá-la - Você deve ir para [Página de configurações de conta do Patreon](https://patreon.com/settings/account) e clicar no botão 'Connect to discord'. Conta do discord não conectada From d2d10f2c9d889d3d2fad3bb0362ded04a84c62d7 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:57:00 +0200 Subject: [PATCH 89/98] Update ResponseStrings.ru-RU.resx (POEditor.com) From 48ab3150ef7bbcd42ccfd1953967b1f946c60b9c Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:57:03 +0200 Subject: [PATCH 90/98] Update ResponseStrings.sr-cyrl-rs.resx (POEditor.com) From 6ffc2a041d54b7546f7131882d8e3ccd1bd8e39a Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:57:06 +0200 Subject: [PATCH 91/98] Update ResponseStrings.es-ES.resx (POEditor.com) --- src/NadekoBot/Resources/ResponseStrings.es-ES.resx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NadekoBot/Resources/ResponseStrings.es-ES.resx b/src/NadekoBot/Resources/ResponseStrings.es-ES.resx index b5813634..a57dff77 100644 --- a/src/NadekoBot/Resources/ResponseStrings.es-ES.resx +++ b/src/NadekoBot/Resources/ResponseStrings.es-ES.resx @@ -2391,7 +2391,7 @@ IDs de dueños: {2} No apoyando - Tienes que esperar algunas horas después de hacer tu colaboración, sino, trata otra vez. + Tienes que esperar algunas horas después de hacer tu colaboración, sino, trata otra vez más tarde. Espera un tiempo From a4d09dc31f9079dfa76d77a0923c47e2797eaebb Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:57:08 +0200 Subject: [PATCH 92/98] Update ResponseStrings.sv-SE.resx (POEditor.com) From de65173fd00c92eaf53e8f88ba0a08f7fc9912d2 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Tue, 11 Apr 2017 00:57:11 +0200 Subject: [PATCH 93/98] Update ResponseStrings.tr-TR.resx (POEditor.com) From a283c3d73f40535e07ef4214f3558ae828f00cb7 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Tue, 11 Apr 2017 01:55:19 +0200 Subject: [PATCH 94/98] Arabic is added but not working properly, waiting for translators to fix --- .../Commands/LocalizationCommands.cs | 1 + .../Resources/ResponseStrings.ar.resx | 2424 +++++++++++++++++ 2 files changed, 2425 insertions(+) create mode 100644 src/NadekoBot/Resources/ResponseStrings.ar.resx diff --git a/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs b/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs index 2eb70e4c..c3de5bd8 100644 --- a/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/LocalizationCommands.cs @@ -20,6 +20,7 @@ namespace NadekoBot.Modules.Administration //Bahasa Indonesia, Indonesia private ImmutableDictionary supportedLocales { get; } = new Dictionary() { + //{"ar", "العربية" }, {"zh-TW", "繁體中文, 台灣" }, {"zh-CN", "简体中文, 中华人民共和国"}, {"nl-NL", "Nederlands, Nederland"}, diff --git a/src/NadekoBot/Resources/ResponseStrings.ar.resx b/src/NadekoBot/Resources/ResponseStrings.ar.resx new file mode 100644 index 00000000..ffb1ba85 --- /dev/null +++ b/src/NadekoBot/Resources/ResponseStrings.ar.resx @@ -0,0 +1,2424 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + تم الاسنيلاء على القاعدة ,او مدمرة + + + القاعدة مدمرة + + + تلك القاعدة غير محتلة + + + ** تدمير** القاعدة #{0} في الحرب ضد {1} + + + {0}**قد تنازل**عن قاعدة #{1} في الحرب ضد {2} + + + {0} استولى على قاعدة #{1} في الحرب ضد {2} + + + @{0} أنت استوليت بالفعل قاعدة # {1}. لا يمكنك المطالبة بوحدة جديدة. + + + الاستولى من @{0} في الحرب ضد {1} قد انته. + + + عدو + + + معلومات عن الحرب ضد {0} + + + رقم القاعدة خطأ. + + + غير متاح حجم الحرب. + + + قائمة الحرب القائمة + + + غير محتلة + + + انت لست مدرج في هذه الحرب + + + @{0} لست مشارك في الحرب , او ان القاعدة قد تدمرت + + + لا توجد حروب ناشطة + + + حجم + + + الحرب ضد {0} قد بدأت + + + أنشئت حرب ضد {0}. + + + الحرب ضد {0} قد انتهت + + + هذه الحرب لا توجد + + + الحرب ضد {0} قد بدأت + + + كل خصائص الرموز التعبيرية المخصصى خالية + + + تم محي الرمز التعبيري المخصص + + + أذونات غير كافية. البوت بحاجة الى تصريح المالك لتعديل الرد التفاعلي , وايضا المدير لتخصيص الرد التفاعلي + + + فائمة الرموز التعبيرية المخصصة + + + الرموز التعبيرية المخصصة + + + رمز تعبيري مخصص جديد + + + لم يوجد هذا الرمز + + + الرمز التعبيري المخصص ليس موجود حسب المدخل + + + الإستجاب + + + احصائيات الرموز التعبيرية مخصصة + + + الخصائص خالية (0) للترميز التفاعلي + + + لا يوجد خصائص مفعلة متاحة , لم يتم اتخاذ اي اجراء. + + + تفعيل + + + Autohentai توقف + Fuzzy + + + لا توجد نتائج. + + + {0} قد اغمي عليه + + + (0) عنده من قبل HP كامل + Fuzzy + + + لديك النوع التالي (0). + + + استخدام (0)(1) على (2)(3) لضرر (4). + Kwoth used punch:type_icon: on Sanity:type_icon: for 50 damage. + + + لا يمكنك الهجوم مرة أخرى دون انتقام! + + + لا يمكنك الهجوم على نفسك. + + + (0) اغمى عليه. + + + عالج (0) باستخدام واحد (1) . + + + (0) لديه (1) HP متبقي. + + + لا يمكنك استخدام (0). اكتب "(1)ml" لروئية لائحة التحريكات التي يمكنك استخدمها. + + + حرك القائمة الى (0) نوع . + + + غير فعالة. + + + لاتملك ما يكفي (0) . + + + أحيا (0) باستخدام (1) . + + + لقد احبيبت تقسك باستخدام واحد (0). + + + لقد تم تغير النوع الى (0) مقابل (1) . + + + انها فعالة إلى حد ما. + + + انها فعالة جدا . + + + لقد استخدمت اكثر من حركة في صف . لا تستطيع التحرك . + + + نوع (0) هو (1) . + + + المستخدم غير متاح . + + + لقد اغمى عليك , لا تيستطيع التحرك ! + + + **تعين دور ** على ضخول مستخدم**تم تعطيله **. + + + **تعين دور ** على ضخول مستخدم**تم تشغيله **. + + + مرفق . + + + تغير المظهر . + + + تم طردك من السيرفر (0) . +السبب : (1) . + + + تم طردك . + PLURAL + + + المستخدم مطرود . + + + تغير اسم البوت الى (0) . + + + خصائص البوت غيرت الى (0). + + + تم تعطيل الحذف الالي لرسالة الوداع. + + + سيتم حذف رسالة الوداع بعد {0} ثواني . + + + رسالة الوداع حاليا : (0) . + + + تفعيل رسالة الوداع بكتابة (0) . + + + وضع رسالة وداع جديدة . + + + اعلان رسالة الوداع غير مفعلة . + + + اعلان رسالة الوداع مفعلة في هذه القناة . + + + تم تغير اسم القناة . + + + الاسم القديم . + + + تم تغير موضوع القناة. + + + تم تنظيف المحتوى . + + + المحتوى . + + + تم انشاء دور (0). + + + تم انشاء قناة رسائل (0) . + + + تم أنشاء قناة الصوت {0}. + + + تم الطرش بنجاح . + + + حذف السيرفر {0}. + + + تم وقف الحذف الالي لأوامر الاستدعاء الناجحة. + + + سيتم الغاء الامر تلقائيا بعد التنفيذ . + + + تم حذف قناة الرسائل {0}. + + + قناة الصوت {0} قد أحذفت. + + + رسالة خاصة من + + + تم اضافة متبرع جديد بنجاح . اجمالي تبرعات هذا المستخدم (0) 👑 + + + شكرا للجميع في القائمة التالية على مساهمتهم في تحقيق هذا المشروع! + + + سوف ارسل الرسائل الخاصة الى جميع المالكين. + + + سوف ارسل الرسائل الخاصة الى المالك الأول فقط. + + + من الان فصاعدا سوف أرسل الرسائل الخاصة. + + + من الان فصاعدا سوف أتوقف عن أرسال الرسائل الخاصة. + + + تم تعطيل الحذف الالي لرسائل التحية. + + + سوف يتم حذف رسائل التحية بعد {0} ثانية. + + + الرسالة الخاصة الحالية للتحية : {0} + + + تمكين DM رسائل التحية عن طريق كتابة {0} + + + تم تثبيت رسالة التحية عبر رسالة خاصة. + + + تم تعطيل الإعلان عن التحية عبر الرسائل الخاصة. + + + تم تفعيل الإعلان عن التحية عبر الرسائل الخاصة. + + + رسالة التحية الحالية : {0} + + + يتم تفعيل رسائل التحية بكتابة {0} + + + وضع رسالة تحية جديدة. + + + اعلان التحية غير مفعل . + + + اعلان التحية مفعل في هذه القناة . + + + ليس باستطاعتك ان تستخدم هذا الأمر على المستخدمين بدور اعلى من دورك او مساوا له في سلم الأدوار. + + + تحميل الصور بعد {0} ثواني! + + + ادخال خاطئ . + + + معلمات غير صالحة. + + + + انضم {0} الى {1} + + + لقد تم طردك من {0} السيرفر. +السبب: {1} + + + تم طرد المستخدم . + + + قائمة اللغات . + + + لغة سيرفرك الان {0}-{1} + + + لغة الألي إفتراضياً الآن {0} - {1} + Fuzzy + + + تم ضبط لغة البوت الى (0) - (1) . + + + فشل الضبط المحلي . قم بزيارة قائمة مساعدة الاوامر . + + + لغة السيرفر مضبوطة الى (0) - (1) . + + + {0} ترك {1} + + + خرج من السيرفر (0) + + + تسجيل هذا الحدث في القناة (0) . + + + تسجيل جميع الاحداث في هذه القناة . + + + تم تعطيل التسجيل. + + + قائمة الاحداث التي يمكنك التسجيل بها . + + + التسجيل سيتجاهل {0} + + + التسجيل لن يتجاهل {0} + + + تم ايقاف تسجيل الحدث (0). + + + (0) قد استند إلى ذكر الأدوار التالية + + + رسالة من (0) '[ مالك البوت ]' . + + + تم ارسال الرسالة . + + + (0) تم تحريك من (1) الى (2) . + + + تم حذف الرسالة في {0}# + + + تم تحديث الرسالة في {0}# + + + صامتة . + PLURAL (users have been muted) + + + صامتة . + singular "User muted." + + + ليس لدي الأذن الازم لذلك على ما يبدو. + + + ضبط اسكات لدور جديد . + + + أحتاج الى الأذن "Administrator" للقيام بذلك. + + + رسالة جديدة . + + + لقب جديد . + + + موضوع جديد . + + + تغير اللقب . + + + لم أجد هذا السيرجر + + + لم يوجد مشاركة مع صاحب ID + + + رسائل قديمة . + + + لقب قديم . + + + موضوع قديم . + + + خطأ . على الاغلب لا امتلك الصلاحيات الكافية . + + + جميع الأذون في السيرفر أعاد تعيينهم. + + + الحماية فعالة . + + + تم تعطيل {0} على هذا السيرفر. + + + {0} مفعل + + + خطأ. أحتاج الى الأذن ManageRoles + + + لس هنالك حماية فغالة. + + + يجب أن يكون المستخدم عتبة بين {0} و {1}. + + + إذا {0} أو أكثر من المستخدمين الانضمام في {1} ثواني، سوف {2} لهم. + + + يجب أن يكون الوقت بين {0} و {1} ثواني. + + + تم حذف جميع الادوار من هذا المستخدم (0) . + + + فشل حذف الدور . لا امتلك الصلاحيات الكافية . + + + تم تغيير لون الدور{0} . + + + الدور غير موجود. + + + المعلمات المحددة غير صالحة. + + + حدث خطأ بسبب لون غير صالح أو أذونات غير كافية. + + + تم ازالة دور {0} من المستخدم {1} + + + فشل حذف الدور. لا امتلك الصلاحيات الكافية . + + + تغير اسم الدور . + + + فشل تغير الاسم . لا امتلك الصلاحيات الكافية . + + + لا يمكنك تعديل أدوار أعلى من أعلى دورك + + + إزالة رسالة اللعب: {0} + + + دور {0} تم أضيفت إلى القائمة. + + + {0} لم يتم العثور.تم تنظيفه + + + دور {0} موجود بالفعل في القائمة. + + + اضافة . + + + تعطيل دوار وضع اللعب + + + تشغيل دوار وضع اللعب + + + هذه قائمة من الحالات الدورية:(0) + + + لم يتعين اوضاع اللعب الدوري. + + + لديك بالفعل الدور{0}. + + + لديك بالفعل دور{0} الحصري المعين لك. + + + الادوار المخصصة للتعين الذاتي الان اصبحت خاصة! + + + هنالك (0) ادور مخصصة للتعين الذاتي . + + + الدور غير مخصص للتعين الذاتي . + + + ليس لديك دور {0}. + + + الادوار المخصصة للتعين الذاتي الان اصبحت غير خاصة! + + + لا أست + + + {0} تمت إزالته من قائمة الأدوار الذاتية التعيين. + + + انت لا تملك هذا الدور (0) بعد الان. + + + لقد اصبحت تملك هذا الدور (0) . + + + تم اضافة الدور (0) بنجاح الى مستخدم (1). + + + فشل اضافة الدور . لا امتلك الاذن الكافي . + + + مظهر جديد ضبط . + + + ضبط اسم قناة جديد. + + + تم اضافة لعبة جديدة ! + + + تم اضافة بث جديد ! + + + اسند موضوع جديد للقناة. + + + شارد {0} اعيدت أتصالها. + + + شارد {0} يعادة الاتصال. + + + جاري الأغلاق. + + + لا يمكن للمستخدمين إرسال أكثر من {0} رسائل كل {1} ثواني. + + + الوضع البطيئ تم ايقافه . + + + الوضع البطيئ تم تفعيله . + + + حظر ناعم (رفض) + PLURAL +Fuzzy + + + {0} سيتجاهل هذه القناة. + + + {0} لم يعد يتجاهل هذه القناة. + + + + + + قناة كتبه صنعت + + + تدمير قناة المراسلة . + + + ازالة عدم السماع بنجاح . + + + إلغاء الصامت + singular + + + اسم المستخدم + + + اسم المستخدم تغير + + + المستخدمين . + + + المستخدم مطرود . + + + {0} تم **صامتة** من الدردشة. + + + {0} تم **إلغاء صامتة** من الدردشة. + + + تم اضافة مستخدم . + + + المستخدم غادر + + + {0} تم **صامتة** من الدردشة والدردشة الصوتية. + + + أضافة دور المستخدم + + + إزالة دور المستخدم + + + (0) اصبح الان (1) + + + (0) اصبح ** صامت ** في المراسلة والمحادثة . + + + (0) اشترك ب (1) قناة الصوت . + + + (0) خرج من (1) قناة الصوت . + + + {0} تغير من {1} الى {2} قناة الصوتية. + + + (0) تم **اسكات الصوت** + + + (0) تم ازالة **اسكات الصوت** + + + انشاء قناة صوت + + + تدمير قناة الصوت + + + ايقاف خصائص الصوت والكتابة + + + تفعيل خصائص الصوت والكتابة + + + + + + + + + + + + المستخدم (0) من كتابة الرسائل + + + المستخدم (0) من الكتابة ومحادثة الصوت + + + المستخدم (0) من محادثة الصوت + + + لقد تم حظرك من {0} مزود. +السبب: {1} + Fuzzy + + + ازالة الطرد عن المستخدم + + + تمت الهجرة ! + + + حدث خطأ أثناء الترحيل، راجع وحدة تحكم بوت للحصول على مزيد من المعلومات. + + + التحديث الحالي + + + المستخدم طرد-مخفض + + + تم منح (0) الى (1) + + + حظا اوفر المرة القادمة ^_^ + + + مبارك لقد فزت (0) دحرجة فوق (1) + + + خلط ورق اللعب مرة ثانية + + + قلب (0) + User flipped tails. + + + لقد خمنتها ! فزت (0) + + + رقم خطأ غير مخصص . بأمكانك قلب 1 الى (0) عملة نقدية + + + اضف الى (0) للحصول على الرمز التفاعلي ل(1) + + + الحدث مستمر لغاية (0) ساعة + + + وردة الرمز التفاعلي بدأت ! + + + لقد اهدا (0) الى (1) + X has gifted 15 flowers to Y + + + (0) يملك (1) + X has Y flowers + + + رأس + + + قائمة المتصدرين + + + تم مكافئة {0} الى {1} المستخدم من دور {2}. + + + لايمكنك المزايدة اكثر من (0) + + + لا يمكنك المزايدة اقل من (0) + + + انت لا تملك ما يكفي (0) + + + لا مزيد للورق على الطاولة + + + بيع المستخدم يانصيب + + + لقد دحرجت (0) + + + المزايدة + + + WOAAHHHHHH!!! مبارك !!! * (0) + + + اشارة (0) , *(1) + + + واو ! محظوظ! ثلاثة من نوع ! * (0) + + + عمل جيد ! اثنين (0) - مزايدة *(1) + + + فزت + + + + + + + + + + + + ذيل + + + بنجاح اخذت (0) من (1) + + + لم استطع اخذ (0) من (1) بسبب المستخدم لا يملك ما يكفي من (2)! + + + العودة الى TOC + Fuzzy + + + فقط مالك البوت + + + مطلوب (0) للسماح بالقناة + + + يمكنك بدعم المشروع في <{patreon: <{0 او في <{1}> :paypal + + + الأوامر والأسماء المستعارة + + + قائمة الأوامر مجددة. + + + + + + لا استطيع ان اجد الامر . الرجاء تأكد من وجود الامر قبل المحاولة التالية + + + وصف + + + يمكنكم الدعم مشروع NadekoBot في <{Patreon <{0 او في <{1}> PayPal +لا تنسى تترك اسمك في ديسكورد او الID في علبة الرسالة. + +** شكراً لكم **♥️ + + + + + + قاىمة الأوامر + + + قائمة الوحدات + + + + + + تلك الوحدة غير موجودة. + + + يتطلب (0) أذن من السيرفر + + + جدول المحتويات + + + الأستعمال + + + + + + ربط + + + سباق الحيوانات + + + فشل في البدء لعدم وجود مشاركين كفاية + + + امتلئ السباق ! البدء فورا. + + + (0) انضم بصفة (1) + + + (0) انضم بصفة (1) و راهن (2)! + + + اكتب {0}jr للانضمام إلى السباق. + Not sure whether to use the actual Arabic letters here to just use the English ones. + + + البدء خلال 20 ثانية او عند اكتمال العدد في الغرفة + + + البدء مع (0) مشتركين. + + + (0) بصفة (1) فاز بالسباق! + + + (0) بصفة (1) فاز بالسباق وايضا (2)! + + + + + + دحرج (0) + Someone rolled 35 + + + دحرج النرد : (0) + Dice Rolled: 5 + + + فشل بداية السباق. ربما سباق آخر في طور الحدوت. + + + لا يوجد سباق على هذا الموزع + + + الرقم الثانيي يجب ان يكون اكبر من الرقم الاول. + + + تغير بالخاطر + + + المطالبة + + + طلاق + + + اعجاب + + + ثمن + + + لم يتم المطلبة بأي waifus بعد. + + + + + + + + + تغير إنجذابهم من {0} الى {1} +*هذا مشكوك فيه أدبياً.*🤔 + Make sure to get the formatting right, and leave the thinking emoji + + + يجب ان تنتظر {0} ساعات و {1} دقائق إذا اردت تغيير انجذابك مرة أخرى. + + + تم إعادته إنجذابك. ليس لديك أي شخص تحبه. + + + يريد ان يكون {0} وايفو. كيوووت 3> + + + + + + + + + لا يمكنك تعيين تقارب لنفسك، انت إغومانياك. + + + 🎉 يتم الوفاء بحبهم! 🎉 +قيمة (0) الجديدة (1)! + + + + + + + + + هذه ليست زوجنك + + + لا يمكنك المطالبة بنفسك. + + + + + + لا أحد + + + + + + 8 كرة + + + رهاب الأجسام. + + + اللعبة انتهت بدون اي اخضاع. + + + لم يحتسب الاصوات . اللعبة انتهت بدون فائز. + + + كان الاختصار (0) + + + + + + بدأت اللعبة. إنشاء جملة مع الاختصار التالي : (0). + + + لديك (0) ثانية لعمل اخضاع. + + + (0) اعتمد حكمهم .((1) الاجمالي) + + + تصويت بكتابة رقم من الاخضاع. + + + (0) وضعوا اصواتهم ! + + + الفائز هو (0) مع (1) من النقاط. + + + + + + سؤال + + + انها التعادل! اختار كلاهما {0}. + + + {0} فاز! {1} هزم على {2}. + + + اغلاق الاخضاع + + + سباق الحيوانات جاهز للركض. + + + المجموع: {0} المعدل: {1} + + + قوائم + + + ايقاف البوت الذكي في هذا السيرفر + + + تفعيل البوت الذكي في هذا السيرفر + + + + + + + + + + plural + + + + + + فشل في تحميل السؤال + + + بدأت اللعبة + + + بدأت لعبة Hangman + + + + + + + + + + + + قائمة المتصدرين + + + انت لا تملك ما يكفي من(0) + + + لا يوجد ناتج + + + حمل (0) + Kwoth picked 5* + + + (0) زرع (1) + Kwoth planted 5* + + + لعبة Trivia تعمل على هذا السيرفر. + + + لعبة Trivia + + + (0) لقد حزرها ! الجواب كان :(1) + + + Trivia لا تعمل على هذا السيرفر. + + + (0) لديه (1) نقطة + + + التوقف بعد هذا السؤال + + + انتهى الوقت ! الاجابة الصحيحة كانت (0) + + + (0) حزر الاجابة وفاز باللعبة ! الاجابة كانت : (1) + + + لا يمكنك اللعب ضد نفسك. + + + + + + تعادل ! + + + تم انتاج لعبة TicTacToe. + + + (0) لقد فاز! + + + تطابق ثلاث + + + لا تحركات متبقية! + + + نفذ الوقت ! + + + حركة {0}. + + + (0) ضد (1) + + + + + + تم تعطيل التشغيل التلقائي. + + + تم تفعيلل التشغيل التلقائي. + + + + + + + + + اللعب العادل + + + انتهت الاغنية + + + تم تعطيل اللعب العادل. + + + تم تفعيل اللعب العادل. + + + من الوضع + + + + + + مدخل غير صالح. + + + + + + + + + + + + + + + + + + اسم الاغنية + + + الان تسمع اغنية + + + لايوجد موسيقى + + + لم يتم ايجاد البحث + + + + + + + + + تشغيل الاغنية + + + + + + + + + تم حذف قائمة التشغيل. + + + + + + + + + + + + حفظ قائمة التشغيل + + + (0) ث الحد + + + + + + + + + تم حذف قائمة انتظار الموسيقى. + + + + + + ازالة الاغنية + context: "removed song #5" + + + اعادة تشغيل الاغنية الحالية + + + تكرار قائمة التشغيل + + + تكرار المسار للموسيقى + + + توقيف تكرار المسار الحالي + + + تم استئناف تشغيل الموسيقى. + + + تم تعطيل قائمة التشغيل المتكررة. + + + تم تمكين قائمة التشغيل المتكرر. + + + + + + تخطي الى '(0):(1)' + + + خلط الاغاني + + + تحريك الاغنية + + + (0 س (1)د (2)ث + + + الى مكان + + + غير محدود + + + يجب أن يكون درجة الصوت بين 0 و 100 + + + ضبط درجة الصوت الى (0)% + + + + + + + + + السماح + + + + + + + + + + + + + + + + + + + + + + + + الامر (0) الان لديه (1)ث ليصبح جاهز. + + + + + + لم يتم تعيين أي تهدئة الأوامر. + + + تكلفة الامر + + + ايقاف الاستخدام في (0) (1) على قناة (2). + + + تفعيل الاستخدام في (0) (1) على قناة (2). + + + رفض + + + تم اضافة الكلمة (0) الى قائمة الكلمات المصفاة. + + + قائمة الكلمات المصفاة. + + + ازالة الكلمة (0) من لائحة الكلمات المصفاة . + + + + + + الدعوات المصفاة تم ايقافها في هذه القناة. + + + الدعوات المصفاة مفعلة في هذه القناة. + + + الدعوات المصفاة تم ايقافها في هذا السيرفر. + + + الدعوات المصفاة مفعلة في هذا السيرفر. + + + تحريك الاذن (0) من #(1) الى #(2) + + + لا استطيع ايجاد الاذن في الدليل + + + لم يوضع تكلفة. + + + الامر + Gen (of command) + + + وحدة + Gen. (of module) + + + صفحة السماحات (0) + + + وضع السماح للدور هو (0) + + + المستخدم يتطلب (0) دور للتمكن من تعديل الاذونات. + + + لم اجد الاذن في القائمة. + + + ازالة الاذن #(0) - (1) + + + ايقاف الاستخدام (0) (1) للدور (2) + + + تفعيل الاستخدام (0) (1) للدور (2) + + + ثواني. + Short of seconds. +Fuzzy + + + ايقاف استخدام (0) (1) في هذا السيرفر + + + تفعيل استخدام (0) (1) في هذا السيرفر + + + + + + لا يتعدل + + + ايقاف الاستخدام (0) (1) للمستخدم (2) + + + تفعيل الاستخدام (0) (1) للمستخدم (2) + + + لن اقوم بأظهار اي تحذير للاذونات. + + + سوف اظهر تحذير الاذونات. + + + ايقاف تصفية الكلمات في هذه القناة. + + + تفعيل تصفية الكلمات في هذه القناة. + + + ايقاف تصفية الكلمات في هذا السيرفر. + + + تفعيل تصفية الكلمات في هذا السيرفر. + + + قدرات + + + لا يوجد انمي مفضل بعد + + + البدء بالترجمة الفورية للمسجات في هذه القناة . رسائل المستخدم سيتم الغائها تلقائيا. + + + تمت إزالة لغة الترجمة التلقائية. + + + تم تعيين لغة الترجمة التلقائية إلى (0)>(1) + + + بدء الترجمة التلقائية للرسائل على هذه القناة. + + + تم إيقاف الترجمة التلقائية للرسائل على هذه القناة. + + + ادخال خطأ للصيغة, او شيء ما حدث بالخطأ. + + + لم استطع ايجاد هذه البطاقة. + + + واقعية + + + فصول + + + رسوم متحركة # + + + خسائر تنافسية + + + لعب تنافسي + + + مرتبة تنافسية + + + فوز تنافسي + + + منتهي + + + شرط + + + تكلفة + + + موعد + + + تحديد: + + + اسقاط + + + حلقة + + + حدث خطأ + + + مثال + + + فشل ايجاد ذلك الانمي + + + فشل ايجاد ذلك المانجا + + + الانواع + + + فشل العثور على تعريف لهذه العلامة. + + + طول/وزن + + + (0) م / (1) كجم + + + رطوبة + + + بحث الصورة في: + + + فشل ايجاد ذلك الفيلم. + + + لغة المصدر أو الهدف غير صالحة + + + النكت غير محملة + + + خط العرض/طول + + + مستوى + + + قائمة (0) الامان المعلمة + Don't translate {0}place + + + المكان + + + + + + + + + + + + ادنى/ اعلى + + + القناة غير موجودة + + + لا توجد نتائج. + + + على- الانتظار + + + الرابط الاصلي + + + + + + فشل استرداد أوسو! التوقيع. + Fuzzy + + + تم ايجاد اكثر من (0) صورة . عرض عشوائي(0). + + + + + + خطط للمشاهدة + + + منصة + Fuzzy + + + لم يتم العثور على أي قدرة. + + + لم اجد اليوكمون. + + + رابط الملف الشخصي: + + + الجودة: + + + وقت اللعب السريع + + + الفوز السريع + + + الترتيب + + + مجموع النقاط: + + + البحث عن: + + + فشل تقصير الربط + + + عنوان الرابط قصير + Fuzzy + + + هناك خطأ ما. + + + يرجى تحديد معلمات البحث. + + + الحالة + + + حفظ الرابط + + + ستريمر {0} غير متواجد حاليا. + Fuzzy + + + ستريمر (0) على الإنترنت مع (1) من المشاهدين. + Fuzzy + + + انت تتابع (0) بث على هذا السيرفر + + + انت لا تتابع اي بث على هذا السيرفر + Fuzzy + + + لا يوجد مثل هذا البث. + + + البث على الاغلب غير موجود. + + + + + + سوف اعلم هذه القناة عند تغير الحالة. + + + شروق الشمس + + + غروب الشمس + + + درجة الحرارة + + + عنوان: + + + اعلى 3 أنيمي مفضلة: + + + ترجمة: + + + الأنواع + + + فشل العثور على تعريف لهذا المصطلح. + + + رابط + + + متابعين + + + مشاهدة + + + فشل العثور على هذا المصطلح على wikia المحدد. + + + الرجاء إدخال وتحديد wikia ، يليه طلب البحث. + + + الصفحة غير موجودة. + + + سرعة الرياح + + + معظم الأبطال المحظورة (0) + + + أخفق تعديل الجملة. + Fuzzy + + + انضم + + + {0} .` {1} [{2: F2} / s] - {3} ألمجموع + /s and total need to be localized to fit the context - +`1.` + + + صفحة النشاط #(0) + + + {0} مجموع المستخدمين. + + + مؤلف + + + بوت ID + + + قائمة الوظائف في الأمر (0) كلك + Fuzzy + + + (0) من هذه القناة هو (1) + + + موضوع القناة + + + تم تشغيل الأوامر + + + {0} {1} يساوي {2} {3} + + + الوحدات التي يمكن استخدامها من قبل المحول + + + لا يمكنني تحويل (0) الى (1): الوحة غير موجودة + + + لا يمكن تحويل (0) إلى (1): أنواع الوحدات غير متساوية + + + أنشئت في + + + انضممت الى قناة تقاطع السيرفارات + Fuzzy + + + مغادرة قناة تقاطع السيرفارات + + + هذا csc قطعة + Fuzzy + + + الرمز التعبيري المخصص + In Arabic, we do have instances where we add "AL" (the) to a sentence since at times it might not make sense without it. It really depends on the sentence wording. + + + خطأ + + + الميزات + + + + الهوية + + + + القائمة خارج النطاق. + + + قائمة المستخدمين في {0} دور + + + لا يسمح لك باستخدام هذا الأمر في الأدوار التي تملك الكثير من المستخدمين فيها لكي تمنع الإساءة + + + قيمة {0} غير صالحة + Invalid months value/ Invalid hours value + + + انضم إلى ديسكورد + + + انضم إلى السيرفر + There are two terms that can be used here other than what is already used. +مُزَوِّد and خادم. +خادم could be mistaken for another word so I avoided it. + + + الهوية: {0} +الأعضاء: {1} +هوية المالك: {2} + + + لم يتم ايجاد سيرفر على تلك الصفحة + + + قائمة المكررين + + + اعضاء + + + ذاكرة + + + رسالة + + + مكرر رسائل + + + الاسم + + + الاسم المستعار + + + لا احد يلعب تلك اللعبة + + + لا نشاط للمكريرن + Fuzzy + + + لا يوجد ادوار في هذه الصفحة + + + + + + لم يضبط الموضوع + + + مالك + + + صاحب IDs + + + حضور + + + (0) سيرفرز +(1) قناة الرسائل +(2) قناة الصوت + + + تم حذف جميع علامات الاقتباس باستخدام كلمة رئيسية (0) + + + صفحة (0) من علامات الاقتباس + + + لا توجد علامات اقتباس في هذه الصفحة. + + + لم يتم العثور على علامات الاقتباس التي يمكنك إزالة. + + + تمت إضافة اقتباس + + + تم حذف الاقتباس # (0) + + + منطقة + + + مسجل في + + + + + + تنسيق الوقت ليس صالحا. تحقق من قائمة الأوامر. + + + تذكير جديد قالب مضبوط + + + + + + قائمة المكررين + + + لا يوجد مكررين على هذا السيرفر + + + #(0) توقف + + + لم اجد رسائل مكررة على هذا السيرفر + + + ناتج + + + دور + + + صفحة #(0) لجميع الادوار على هذا السيرفر + + + صفحة #(0) من الادوار ل (1) + Fuzzy + + + لا توجد ألوان بالتنسيق الصحيح. استخدم `# 00ff00` على سبيل المثال. + + + بدأ تدوير لون الدور (0) + + + توقف الألوان الدورية لدور (0) + + + (0) من هذا السيرفر(1) + + + معلومات السيرفر + + + + + + + + + + + + **الاسم:** (0) **الرابط:**(1) + + + لم يتم العثور على رموز تعبيرية خاصة. + + + تشغيل الأغاني (0). (1) في قائمة الانتظار. + + + قناة الرسائل + + + إليك رابط غرفتك: + + + مدة التشغيل + + + (0) للمستخدم (1) هو (2) + Id of the user kwoth#1234 is 123123123123 + + + المستخدمين + + + قناة الصوت + + + لقد انضممت بالفعل لهذا السباق! + + + نتائج الاستطلاع الحالية + + + لا اصوات وضعت + + + يتم تشغيل الاستطلاع بالفعل على هذا السيرفر + + + 📃 (0) قام بإنشاء استطلاع يتطلب انتباهك: + + + `{0}.` {1} مع {2} اصوات. + + + (0) صوت. + Kwoth voted. + + + + + + + + + شكرا للتصويت (0) + + + مجموع الاصوات (0) + + + + + + + + + لم يتم العثور على مستخدم + + + صفحة (0) + + + يجب أن تكون في قناة الصوت على هذا السيرفر + + + لا توجد أدوار لقنوات الصوت + + + + + + + + + + + + ادوار قناة الصوت + + + + + + + + + + + + + + + لم يتم العثور على اسم مستعار + + + + + + + + + + + + + + + + + + + + + + + + + PLURAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 522d7d53f8f83a6e2b3ceba3b6fc20d5bbe4c57c Mon Sep 17 00:00:00 2001 From: Mirai Date: Sat, 15 Apr 2017 00:32:49 +0200 Subject: [PATCH 95/98] Added Google Maps --- docs/guides/Windows Guide.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/guides/Windows Guide.md b/docs/guides/Windows Guide.md index 0f141fad..d6c7d0de 100644 --- a/docs/guides/Windows Guide.md +++ b/docs/guides/Windows Guide.md @@ -1,5 +1,5 @@ ________________________________________________________________________________ -*Thanks to @Flatbread and Mirai for making this guide* +*Thanks to @Flatbread and @Mirai for making this guide* ________________________________________________________________________________ ## Setting Up NadekoBot on Windows @@ -106,7 +106,7 @@ In order to have a functioning music module, you need to install ffmpeg and setu - Follow these steps on how to setup Google API keys: - Go to [Google Console][Google Console] and log in. - Create a new project (name does not matter). Once the project is created, go into "Enable and manage APIs." - - Under the "Other Popular APIs" section, enable `URL Shortener API` and `Custom Search Api`. Under the `YouTube APIs` section, enable `YouTube Data API`. + - Under the "Other Popular APIs" section, enable `URL Shortener API` and `Custom Search API`. Under the `YouTube APIs` section, enable `YouTube Data API`. - On the left tab, access `Credentials`. Click `Create Credentials` button. Click on `API Key`. A new window will appear with your `Google API key`. - Copy the key. - Open up `credentials.json`. @@ -118,6 +118,10 @@ In order to have a functioning music module, you need to install ffmpeg and setu - All requests for an API key must go through the review process, where applications will be reviewed on a case by case basis, in line with Soundcloud API Terms of Use. If your application is successful, you will receive an API key. - **Restart your computer** +### Setting Up NadekoBot For GoogleMaps + - Go to [Google Console][Google Console] and log in. + - Under the "Google Maps APIs" section, enable `Google Maps Geocoding API` and `Google Maps Time Zone API`. + [.NET Core SDK]: https://github.com/dotnet/core/blob/master/release-notes/download-archives/1.1-preview2.1-download.md From db962f8e76a874d992324e3cb9922d2a76ab8521 Mon Sep 17 00:00:00 2001 From: Mirai Date: Sat, 15 Apr 2017 00:35:29 +0200 Subject: [PATCH 96/98] Google Mapso --- docs/guides/Windows Guide.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/guides/Windows Guide.md b/docs/guides/Windows Guide.md index d6c7d0de..5902c062 100644 --- a/docs/guides/Windows Guide.md +++ b/docs/guides/Windows Guide.md @@ -107,6 +107,7 @@ In order to have a functioning music module, you need to install ffmpeg and setu - Go to [Google Console][Google Console] and log in. - Create a new project (name does not matter). Once the project is created, go into "Enable and manage APIs." - Under the "Other Popular APIs" section, enable `URL Shortener API` and `Custom Search API`. Under the `YouTube APIs` section, enable `YouTube Data API`. + - Under the "Google Maps APIs" section, enable `Google Maps Geocoding API` and `Google Maps Time Zone API`. - On the left tab, access `Credentials`. Click `Create Credentials` button. Click on `API Key`. A new window will appear with your `Google API key`. - Copy the key. - Open up `credentials.json`. @@ -118,9 +119,7 @@ In order to have a functioning music module, you need to install ffmpeg and setu - All requests for an API key must go through the review process, where applications will be reviewed on a case by case basis, in line with Soundcloud API Terms of Use. If your application is successful, you will receive an API key. - **Restart your computer** -### Setting Up NadekoBot For GoogleMaps - - Go to [Google Console][Google Console] and log in. - - Under the "Google Maps APIs" section, enable `Google Maps Geocoding API` and `Google Maps Time Zone API`. + From bb12c12df7eda5ddaf471214d1348a99631deb9b Mon Sep 17 00:00:00 2001 From: DogeOps97 Date: Mon, 17 Apr 2017 12:26:41 -0700 Subject: [PATCH 97/98] Changing pause to timeout - latest Well, with pause, the autorun requires you to press some key to get it running. A little bit of change --- scripts/Latest.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/Latest.bat b/scripts/Latest.bat index 13248a96..36c5b3be 100644 --- a/scripts/Latest.bat +++ b/scripts/Latest.bat @@ -162,5 +162,5 @@ GOTO end ECHO. ECHO Installation complete! ECHO. - PAUSE - del Latest.bat \ No newline at end of file + timeout /t 5 + del Latest.bat From db824d23b0e98576db6ce18b238d18fca8ddf386 Mon Sep 17 00:00:00 2001 From: DogeOps97 Date: Mon, 17 Apr 2017 12:35:09 -0700 Subject: [PATCH 98/98] Changing PAUSE to timeout - stable Making things smoother for auto-update --- scripts/Stable.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/Stable.bat b/scripts/Stable.bat index a3ffb6f4..43f8cf23 100644 --- a/scripts/Stable.bat +++ b/scripts/Stable.bat @@ -162,5 +162,5 @@ GOTO end ECHO. ECHO Installation complete! ECHO. - PAUSE - del Stable.bat \ No newline at end of file + timeout /t 5 + del Stable.bat