diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..46c56a22 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM microsoft/dotnet:sdk +MAINTAINER Poag + +WORKDIR /opt/ + +#Install required software +RUN echo "deb http://www.deb-multimedia.org jessie main non-free" | tee /etc/apt/sources.list.d/debian-backports.list \ + && apt-get update \ + && apt-get install -y --force-yes deb-multimedia-keyring \ + && apt-get update \ + && apt-get install -y git libopus0 opus-tools libopus-dev libsodium-dev ffmpeg + +#Download and install stable version of Nadeko +RUN curl -L https://github.com/Kwoth/NadekoBot-BashScript/raw/master/nadeko_installer_latest.sh | sh \ + && curl -L https://github.com/Kwoth/NadekoBot-BashScript/raw/master/nadeko_autorestart.sh > nadeko.sh \ + && chmod 755 nadeko.sh + +VOLUME ["/opt"] + +CMD ["/opt/nadeko.sh"] diff --git a/discord.net b/discord.net index 321f6bb2..508026d5 160000 --- a/discord.net +++ b/discord.net @@ -1 +1 @@ -Subproject commit 321f6bb2155dcece696d93c6be4023b457b3eaa2 +Subproject commit 508026d5d4f4d8780d983c63ab25e4c15ad69e59 diff --git a/docs/Commands List.md b/docs/Commands List.md index bf31a9d1..593c326f 100644 --- a/docs/Commands List.md +++ b/docs/Commands List.md @@ -364,7 +364,7 @@ Command and aliases | Description | Usage `..` | Adds a new quote with the specified name and message. | `.. sayhi Hi` `.deletequote` `.delq` | Deletes a random quote with the specified keyword. You have to either be server Administrator or the creator of the quote to delete it. | `.delq abc` `.delallq` `.daq` | Deletes all quotes on a specified keyword. **Requires Administrator server permission.** | `.delallq kek` -`.remind` | Sends a message to you or a channel after certain amount of time. First argument is me/here/'channelname'. Second argument is time in a descending order (mo>w>d>h>m) example: 1w5d3h10m. Third argument is a (multiword)message. | `.remind me 1d5h Do something` or `.remind #general Start now!` +`.remind` | Sends a message to you or a channel after certain amount of time. First argument is me/here/'channelname'. Second argument is time in a descending order (mo>w>d>h>m) example: 1w5d3h10m. Third argument is a (multiword)message. | `.remind me 1d5h Do something` or `.remind #general 1m Start now!` `.remindtemplate` | Sets message for when the remind is triggered. Available placeholders are %user% - user who ran the command, %message% - Message specified in the remind, %target% - target channel of the remind. **Bot Owner only.** | `.remindtemplate %user%, do %message%!` `.convertlist` | List of the convertible dimensions and currencies. | `.convertlist` `.convert` | Convert quantities. Use `.convertlist` to see supported dimensions and currencies. | `.convert m km 1000` diff --git a/docs/Custom Reactions.md b/docs/Custom Reactions.md index e5e9cc34..803485d3 100644 --- a/docs/Custom Reactions.md +++ b/docs/Custom Reactions.md @@ -27,6 +27,14 @@ There's no special requirement for the formatting of the response, so we could j Now, if that command was ran in a server, anyone on that server can make the bot mention them, saying `It sure is, @Username` anytime they say "Nice Weather". If the command is ran in a direct message with the bot, then the custom reaction can be used on every server the bot is connected to. +###Block global Custom Reactions +If you want to disable some global custom reactions which you do not like, and you do not want to remove them or you are not the bot owner you can do so by adding a new Custom Reaction with the same trigger on your server, and set the response to `-`. + +For example: +`.acr /o/ -` + +Now if you try to trigger `/o/`, it won't print anything. + ###Placeholders! There are currently three different placeholders which we will look at, with more placeholders potentially coming in the future. diff --git a/docs/guides/Docker Guide.md b/docs/guides/Docker Guide.md index 00a13a99..ff369e4e 100644 --- a/docs/guides/Docker Guide.md +++ b/docs/guides/Docker Guide.md @@ -1,3 +1,34 @@ -# Docker Guide with DigitalOcean +# NadekoBot a Discord bot +Nadeko is written in C# and Discord.net for more information visit https://github.com/Kwoth/NadekoBot -## There is no docker image for 1.0 nadeko right now. Soon. \ No newline at end of file +## Install Docker +Follow the respective guide for your operating system found here https://docs.docker.com/engine/installation/ + +## Nadeko Setup Guide +For this guide we will be using the folder /nadeko as our config root folder. + +``` +docker create --name=nadeko -v /nadeko/data:/opt/NadekoBot/src/NadekoBot/bin/Release/netcoreapp1.0/data -v /nadeko/credentials.json:/opt/NadekoBot/src/NadekoBot/credentials.json kwoth/nadeko:dev +``` +-If you are coming from a previous version of nadeko (the old docker) make sure your crednetials.json has been copied into this directory and is the only thing in this folder. + +-If you are making a fresh install, create your credentials.json from the following guide and palce it in the /nadeko folder +http://nadekobot.readthedocs.io/en/latest/JSON%20Explanations/ + +Next start the docker up with + +```docker run nadeko; docker logs -f nadeko``` + +The docker will start and the log file will start scrolling past. Depending on hardware the bot start can take up to 5 minutes on a small DigitalOcean droplet. +Once the log ends with "NadekoBot | Starting NadekoBot v1.0-rc2" the bot is ready and can be invited to your server. Ctrl+C at this point to stop viewing the logs. + +After a few moments you should be able to invite Nadeko to your server. If you cannot check the log file for errors + +## Updates / Monitoring + +* Upgrade to the latest version of Nadeko simply `docker restart nadeko`. +* Monitor the logs of the container in realtime `docker logs -f nadeko`. + +If you have any issues with the docker setup, please ask in #help but indicate you are using the docker. + +For information about configuring your bot or its functionality, please check the http://nadekobot.readthedocs.io/en/latest guides. diff --git a/src/NadekoBot/Migrations/20161213025624_mutedusers.Designer.cs b/src/NadekoBot/Migrations/20161213025624_mutedusers.Designer.cs new file mode 100644 index 00000000..af021dfc --- /dev/null +++ b/src/NadekoBot/Migrations/20161213025624_mutedusers.Designer.cs @@ -0,0 +1,825 @@ +๏ปฟ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("20161213025624_mutedusers")] + partial class mutedusers + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { + modelBuilder + .HasAnnotation("ProductVersion", "1.1.0-rtm-22752"); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("ItemId"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("BlacklistItem"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.BotConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BufferSize"); + + b.Property("CurrencyGenerationChance"); + + b.Property("CurrencyGenerationCooldown"); + + b.Property("CurrencyName"); + + b.Property("CurrencyPluralName"); + + b.Property("CurrencySign"); + + b.Property("DMHelpString"); + + b.Property("ForwardMessages"); + + b.Property("ForwardToAllOwners"); + + b.Property("HelpString"); + + b.Property("MigrationVersion"); + + b.Property("RemindMessageFormat"); + + b.Property("RotatingStatuses"); + + b.HasKey("Id"); + + b.ToTable("BotConfig"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BaseDestroyed"); + + b.Property("CallUser"); + + b.Property("ClashWarId"); + + b.Property("SequenceNumber"); + + b.Property("Stars"); + + b.Property("TimeAdded"); + + b.HasKey("Id"); + + b.HasIndex("ClashWarId"); + + b.ToTable("ClashCallers"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashWar", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("EnemyClan"); + + b.Property("GuildId"); + + b.Property("Size"); + + b.Property("StartedAt"); + + b.Property("WarState"); + + b.HasKey("Id"); + + b.ToTable("ClashOfClans"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("CommandName"); + + b.Property("GuildConfigId"); + + b.Property("Seconds"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("CommandCooldown"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ConvertUnit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("InternalTrigger"); + + b.Property("Modifier"); + + b.Property("UnitType"); + + b.HasKey("Id"); + + b.ToTable("ConversionUnits"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Currency", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Amount"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("Currency"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CurrencyTransaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Amount"); + + b.Property("Reason"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.ToTable("CurrencyTransactions"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CustomReaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("GuildId"); + + b.Property("IsRegex"); + + b.Property("OwnerOnly"); + + b.Property("Response"); + + b.Property("Trigger"); + + b.HasKey("Id"); + + b.ToTable("CustomReactions"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Donator", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Amount"); + + b.Property("Name"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("Donators"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("Text"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("EightBallResponses"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("GuildConfigId"); + + b.Property("GuildConfigId1"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.HasIndex("GuildConfigId1"); + + b.ToTable("FilterChannelId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("GuildConfigId"); + + b.Property("Word"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("FilteredWord"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("GuildConfigId"); + + b.Property("GuildId"); + + b.Property("Type"); + + b.Property("Username"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("FollowedStream"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("GuildConfigId"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("GCChannelId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AutoAssignRoleId"); + + b.Property("AutoDeleteByeMessages"); + + b.Property("AutoDeleteByeMessagesTimer"); + + b.Property("AutoDeleteGreetMessages"); + + b.Property("AutoDeleteGreetMessagesTimer"); + + b.Property("AutoDeleteSelfAssignedRoleMessages"); + + b.Property("ByeMessageChannelId"); + + b.Property("ChannelByeMessageText"); + + b.Property("ChannelGreetMessageText"); + + b.Property("CleverbotEnabled"); + + b.Property("DefaultMusicVolume"); + + b.Property("DeleteMessageOnCommand"); + + b.Property("DmGreetMessageText"); + + b.Property("ExclusiveSelfAssignedRoles"); + + b.Property("FilterInvites"); + + b.Property("FilterWords"); + + b.Property("GreetMessageChannelId"); + + b.Property("GuildId"); + + b.Property("LogSettingId"); + + b.Property("MuteRoleName"); + + b.Property("PermissionRole"); + + b.Property("RootPermissionId"); + + b.Property("SendChannelByeMessage"); + + b.Property("SendChannelGreetMessage"); + + b.Property("SendDmGreetMessage"); + + b.Property("VerbosePermissions"); + + b.Property("VoicePlusTextEnabled"); + + b.HasKey("Id"); + + b.HasIndex("GuildId") + .IsUnique(); + + b.HasIndex("LogSettingId"); + + b.HasIndex("RootPermissionId"); + + b.ToTable("GuildConfigs"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("LogSettingId"); + + b.HasKey("Id"); + + b.HasIndex("LogSettingId"); + + b.ToTable("IgnoredLogChannels"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("LogSettingId"); + + b.HasKey("Id"); + + b.HasIndex("LogSettingId"); + + b.ToTable("IgnoredVoicePresenceCHannels"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelCreated"); + + b.Property("ChannelDestroyed"); + + b.Property("ChannelId"); + + b.Property("ChannelUpdated"); + + b.Property("IsLogging"); + + b.Property("LogUserPresence"); + + b.Property("LogVoicePresence"); + + b.Property("MessageDeleted"); + + b.Property("MessageUpdated"); + + b.Property("UserBanned"); + + b.Property("UserJoined"); + + b.Property("UserLeft"); + + b.Property("UserPresenceChannelId"); + + b.Property("UserUnbanned"); + + b.Property("UserUpdated"); + + 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("ModuleName"); + + b.Property("Prefix"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("ModulePrefixes"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlaylist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Author"); + + b.Property("AuthorId"); + + b.Property("Name"); + + b.HasKey("Id"); + + b.ToTable("MusicPlaylists"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + 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("NextId"); + + b.Property("PrimaryTarget"); + + b.Property("PrimaryTargetId"); + + b.Property("SecondaryTarget"); + + b.Property("SecondaryTargetName"); + + b.Property("State"); + + b.HasKey("Id"); + + b.HasIndex("NextId") + .IsUnique(); + + b.ToTable("Permission"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("Status"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("PlayingStatus"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("MusicPlaylistId"); + + b.Property("Provider"); + + b.Property("ProviderType"); + + b.Property("Query"); + + b.Property("Title"); + + b.Property("Uri"); + + b.HasKey("Id"); + + b.HasIndex("MusicPlaylistId"); + + b.ToTable("PlaylistSong"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AuthorId"); + + b.Property("AuthorName") + .IsRequired(); + + b.Property("GuildId"); + + b.Property("Keyword") + .IsRequired(); + + b.Property("Text") + .IsRequired(); + + b.HasKey("Id"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("Icon"); + + b.Property("Name"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("RaceAnimals"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("IsPrivate"); + + b.Property("Message"); + + b.Property("ServerId"); + + b.Property("UserId"); + + b.Property("When"); + + b.HasKey("Id"); + + b.ToTable("Reminders"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Repeater", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("GuildId"); + + b.Property("Interval"); + + b.Property("Message"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId") + .IsUnique(); + + b.ToTable("Repeaters"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("GuildId"); + + b.Property("RoleId"); + + b.HasKey("Id"); + + b.HasIndex("GuildId", "RoleId") + .IsUnique(); + + b.ToTable("SelfAssignableRoles"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.UserPokeTypes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("UserId"); + + b.Property("type"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("PokeGame"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("Blacklist") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ClashWar", "ClashWar") + .WithMany("Bases") + .HasForeignKey("ClashWarId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("CommandCooldowns") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("EightBallResponses") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("FilterInvitesChannelIds") + .HasForeignKey("GuildConfigId"); + + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("FilterWordsChannelIds") + .HasForeignKey("GuildConfigId1"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("FilteredWords") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("FollowedStreams") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("GenerateCurrencyChannelIds") + .HasForeignKey("GuildConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b => + { + b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting") + .WithMany() + .HasForeignKey("LogSettingId"); + + b.HasOne("NadekoBot.Services.Database.Models.Permission", "RootPermission") + .WithMany() + .HasForeignKey("RootPermissionId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b => + { + b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting") + .WithMany("IgnoredChannels") + .HasForeignKey("LogSettingId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b => + { + b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting") + .WithMany("IgnoredVoicePresenceChannelIds") + .HasForeignKey("LogSettingId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("ModulePrefixes") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.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.PlayingStatus", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("RotatingStatusMessages") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b => + { + b.HasOne("NadekoBot.Services.Database.Models.MusicPlaylist") + .WithMany("Songs") + .HasForeignKey("MusicPlaylistId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("RaceAnimals") + .HasForeignKey("BotConfigId"); + }); + } + } +} diff --git a/src/NadekoBot/Migrations/20161213025624_mutedusers.cs b/src/NadekoBot/Migrations/20161213025624_mutedusers.cs new file mode 100644 index 00000000..ec97cac5 --- /dev/null +++ b/src/NadekoBot/Migrations/20161213025624_mutedusers.cs @@ -0,0 +1,43 @@ +๏ปฟusing System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace NadekoBot.Migrations +{ + public partial class mutedusers : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "MutedUserId", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + GuildConfigId = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_MutedUserId", x => x.Id); + table.ForeignKey( + name: "FK_MutedUserId_GuildConfigs_GuildConfigId", + column: x => x.GuildConfigId, + principalTable: "GuildConfigs", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_MutedUserId_GuildConfigId", + table: "MutedUserId", + column: "GuildConfigId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "MutedUserId"); + } + } +} diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index d209fb74..6b7ef481 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -492,6 +492,22 @@ namespace NadekoBot.Migrations b.ToTable("MusicPlaylists"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + 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") @@ -663,7 +679,7 @@ namespace NadekoBot.Migrations b.Property("Id") .ValueGeneratedOnAdd(); - b.Property("UserId"); + b.Property("UserId"); b.Property("type"); @@ -768,6 +784,13 @@ namespace NadekoBot.Migrations .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") diff --git a/src/NadekoBot/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs index b2866ff6..196aaea5 100644 --- a/src/NadekoBot/Modules/Administration/Administration.cs +++ b/src/NadekoBot/Modules/Administration/Administration.cs @@ -16,6 +16,8 @@ using System.IO; using static NadekoBot.Modules.Permissions.Permissions; using System.Collections.Concurrent; using NLog; +using NadekoBot.Services.Database; +using Microsoft.EntityFrameworkCore; namespace NadekoBot.Modules.Administration { @@ -25,7 +27,7 @@ namespace NadekoBot.Modules.Administration private static ConcurrentDictionary GuildMuteRoles { get; } = new ConcurrentDictionary(); - private static Logger _log { get; } + private new static Logger _log { get; } public Administration() : base() { @@ -36,13 +38,7 @@ namespace NadekoBot.Modules.Administration _log = LogManager.GetCurrentClassLogger(); NadekoBot.CommandHandler.CommandExecuted += DelMsgOnCmd_Handler; - using (var uow = DbHandler.UnitOfWork()) - { - var configs = NadekoBot.AllGuildConfigs; - GuildMuteRoles = new ConcurrentDictionary(configs - .Where(c=>!string.IsNullOrWhiteSpace(c.MuteRoleName)) - .ToDictionary(c => c.GuildId, c => c.MuteRoleName)); - } + } private static async Task DelMsgOnCmd_Handler(IUserMessage msg, Command cmd) @@ -69,39 +65,6 @@ namespace NadekoBot.Modules.Administration } } - private static async Task GetMuteRole(IGuild guild) - { - const string defaultMuteRoleName = "nadeko-mute"; - - var muteRoleName = GuildMuteRoles.GetOrAdd(guild.Id, defaultMuteRoleName); - - var muteRole = guild.Roles.FirstOrDefault(r => r.Name == muteRoleName); - if (muteRole == null) - { - - //if it doesn't exist, create it - try { muteRole = await guild.CreateRoleAsync(muteRoleName, GuildPermissions.None).ConfigureAwait(false); } - catch - { - //if creations fails, maybe the name is not correct, find default one, if doesn't work, create default one - muteRole = guild.Roles.FirstOrDefault(r => r.Name == muteRoleName) ?? - await guild.CreateRoleAsync(defaultMuteRoleName, GuildPermissions.None).ConfigureAwait(false); - } - - foreach (var toOverwrite in guild.GetTextChannels()) - { - try - { - await toOverwrite.AddPermissionOverwriteAsync(muteRole, new OverwritePermissions(sendMessages: PermValue.Deny, attachFiles: PermValue.Deny)) - .ConfigureAwait(false); - } - catch { } - await Task.Delay(200).ConfigureAwait(false); - } - } - return muteRole; - } - [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.Administrator)] @@ -124,7 +87,7 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync(); } - await channel.SendMessageAsync($"{imsg.Author.Mention} ๐Ÿ†— **Permissions for this server are reset.**"); + await channel.SendConfirmAsync($"{imsg.Author.Mention} ๐Ÿ†— **Permissions for this server are reset.**"); } [NadekoCommand, Usage, Description, Aliases] @@ -142,9 +105,9 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync(); } if (enabled) - await channel.SendMessageAsync("โœ… **Now automatically deleting successful command invokations.**").ConfigureAwait(false); + await channel.SendConfirmAsync("โœ… **Now automatically deleting successful command invokations.**").ConfigureAwait(false); else - await channel.SendMessageAsync("โ—**Stopped automatic deletion of successful command invokations.**").ConfigureAwait(false); + await channel.SendConfirmAsync("โ—**Stopped automatic deletion of successful command invokations.**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -156,11 +119,11 @@ namespace NadekoBot.Modules.Administration try { await usr.AddRolesAsync(role).ConfigureAwait(false); - await channel.SendMessageAsync($"โ„น๏ธ Successfully added role **{role.Name}** to user **{usr.Username}**").ConfigureAwait(false); + await channel.SendConfirmAsync($"โ„น๏ธ Successfully added role **{role.Name}** to user **{usr.Username}**").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendMessageAsync("โš ๏ธ Failed to add role. **Bot has insufficient permissions.**\n").ConfigureAwait(false); + await channel.SendErrorAsync("โš ๏ธ Failed to add role. **Bot has insufficient permissions.**\n").ConfigureAwait(false); Console.WriteLine(ex.ToString()); } } @@ -174,11 +137,11 @@ namespace NadekoBot.Modules.Administration try { await usr.RemoveRolesAsync(role).ConfigureAwait(false); - await channel.SendMessageAsync($"โ„น๏ธ Successfully removed role **{role.Name}** from user **{usr.Username}**").ConfigureAwait(false); + await channel.SendConfirmAsync($"โ„น๏ธ Successfully removed role **{role.Name}** from user **{usr.Username}**").ConfigureAwait(false); } catch { - await channel.SendMessageAsync("โš ๏ธ Failed to remove role. Most likely reason: **Insufficient permissions.**").ConfigureAwait(false); + await channel.SendErrorAsync("โš ๏ธ Failed to remove role. Most likely reason: **Insufficient permissions.**").ConfigureAwait(false); } } @@ -192,15 +155,15 @@ namespace NadekoBot.Modules.Administration { if (roleToEdit.Position > (await channel.Guild.GetCurrentUserAsync().ConfigureAwait(false)).Roles.Max(r => r.Position)) { - await channel.SendMessageAsync("๐Ÿšซ You can't edit roles higher than your highest role.").ConfigureAwait(false); + await channel.SendErrorAsync("๐Ÿšซ You can't edit roles higher than your highest role.").ConfigureAwait(false); return; } await roleToEdit.ModifyAsync(g => g.Name = newname).ConfigureAwait(false); - await channel.SendMessageAsync("โœ… Role renamed.").ConfigureAwait(false); + await channel.SendConfirmAsync("โœ… Role renamed.").ConfigureAwait(false); } catch (Exception) { - await channel.SendMessageAsync("โš ๏ธ Failed to rename role. Probably **insufficient permissions.**").ConfigureAwait(false); + await channel.SendErrorAsync("โš ๏ธ Failed to rename role. Probably **insufficient permissions.**").ConfigureAwait(false); } } @@ -214,11 +177,11 @@ namespace NadekoBot.Modules.Administration try { await user.RemoveRolesAsync(user.Roles).ConfigureAwait(false); - await channel.SendMessageAsync($"๐Ÿ—‘ Successfully removed **all** roles from user **{user.Username}**").ConfigureAwait(false); + await channel.SendConfirmAsync($"๐Ÿ—‘ Successfully removed **all** roles from user **{user.Username}**").ConfigureAwait(false); } catch { - await channel.SendMessageAsync("โš ๏ธ Failed to remove roles. Most likely reason: **Insufficient permissions.**").ConfigureAwait(false); + await channel.SendErrorAsync("โš ๏ธ Failed to remove roles. Most likely reason: **Insufficient permissions.**").ConfigureAwait(false); } } @@ -235,11 +198,11 @@ namespace NadekoBot.Modules.Administration try { var r = await channel.Guild.CreateRoleAsync(roleName).ConfigureAwait(false); - await channel.SendMessageAsync($"โœ… Successfully created role **{r.Name}**.").ConfigureAwait(false); + await channel.SendConfirmAsync($"โœ… Successfully created role **{r.Name}**.").ConfigureAwait(false); } catch (Exception) { - await channel.SendMessageAsync("โš ๏ธ Unspecified error.").ConfigureAwait(false); + await channel.SendErrorAsync("โš ๏ธ Unspecified error.").ConfigureAwait(false); } } @@ -252,7 +215,7 @@ namespace NadekoBot.Modules.Administration if (args.Count() != 2 && args.Count() != 4) { - await channel.SendMessageAsync("โŒ The parameters specified are **invalid.**").ConfigureAwait(false); + await channel.SendErrorAsync("โŒ The parameters specified are **invalid.**").ConfigureAwait(false); return; } var roleName = args[0].ToUpperInvariant(); @@ -260,7 +223,7 @@ namespace NadekoBot.Modules.Administration if (role == null) { - await channel.SendMessageAsync("๐Ÿšซ That role **does not exist.**").ConfigureAwait(false); + await channel.SendErrorAsync("๐Ÿšซ That role **does not exist.**").ConfigureAwait(false); return; } try @@ -273,11 +236,11 @@ namespace NadekoBot.Modules.Administration var blue = Convert.ToByte(rgb ? int.Parse(args[3]) : Convert.ToInt32(arg1.Substring(4, 2), 16)); await role.ModifyAsync(r => r.Color = new Discord.Color(red, green, blue).RawValue).ConfigureAwait(false); - await channel.SendMessageAsync($"โ˜‘๏ธ Role **{role.Name}'s** color has been changed.").ConfigureAwait(false); + await channel.SendConfirmAsync($"โ˜‘๏ธ Role **{role.Name}'s** color has been changed.").ConfigureAwait(false); } catch (Exception) { - await channel.SendMessageAsync("โš ๏ธ Error occured, most likely **invalid parameters** or **insufficient permissions.**").ConfigureAwait(false); + await channel.SendErrorAsync("โš ๏ธ Error occured, most likely **invalid parameters** or **insufficient permissions.**").ConfigureAwait(false); } } @@ -293,12 +256,12 @@ namespace NadekoBot.Modules.Administration } if (umsg.Author.Id != user.Guild.OwnerId && user.Roles.Select(r=>r.Position).Max() >= ((IGuildUser)umsg.Author).Roles.Select(r => r.Position).Max()) { - await channel.SendMessageAsync("โš ๏ธ You can't use this command on users with a role higher or equal to yours in the role hierarchy."); + await channel.SendErrorAsync("โš ๏ธ You can't use this command on users with a role higher or equal to yours in the role hierarchy."); return; } try { - await (await user.CreateDMChannelAsync()).SendMessageAsync($"โ›”๏ธ **You have been BANNED from `{channel.Guild.Name}` server.**\n" + + await (await user.CreateDMChannelAsync()).SendErrorAsync($"โ›”๏ธ **You have been BANNED from `{channel.Guild.Name}` server.**\n" + $"โš– *Reason:* {msg}").ConfigureAwait(false); await Task.Delay(2000).ConfigureAwait(false); } @@ -307,11 +270,11 @@ namespace NadekoBot.Modules.Administration { await channel.Guild.AddBanAsync(user, 7).ConfigureAwait(false); - await channel.SendMessageAsync("โ›”๏ธ **Banned** user **" + user.Username + "** ID: `" + user.Id + "`").ConfigureAwait(false); + await channel.SendConfirmAsync("โ›”๏ธ **Banned** user **" + user.Username + "** ID: `" + user.Id + "`").ConfigureAwait(false); } catch { - await channel.SendMessageAsync("โš ๏ธ **Error.** Most likely I don't have sufficient permissions.").ConfigureAwait(false); + await channel.SendErrorAsync("โš ๏ธ **Error.** Most likely I don't have sufficient permissions.").ConfigureAwait(false); } } @@ -328,12 +291,12 @@ namespace NadekoBot.Modules.Administration } if (umsg.Author.Id != user.Guild.OwnerId && user.Roles.Select(r => r.Position).Max() >= ((IGuildUser)umsg.Author).Roles.Select(r => r.Position).Max()) { - await channel.SendMessageAsync("โš ๏ธ You can't use this command on users with a role higher or equal to yours in the role hierarchy."); + await channel.SendErrorAsync("โš ๏ธ You can't use this command on users with a role higher or equal to yours in the role hierarchy."); return; } try { - await user.SendMessageAsync($"โ˜ฃ **You have been SOFT-BANNED from `{channel.Guild.Name}` server.**\n" + + await user.SendErrorAsync($"โ˜ฃ **You have been SOFT-BANNED from `{channel.Guild.Name}` server.**\n" + $"โš– *Reason:* {msg}").ConfigureAwait(false); await Task.Delay(2000).ConfigureAwait(false); } @@ -344,11 +307,11 @@ namespace NadekoBot.Modules.Administration try { await channel.Guild.RemoveBanAsync(user).ConfigureAwait(false); } catch { await channel.Guild.RemoveBanAsync(user).ConfigureAwait(false); } - await channel.SendMessageAsync("โ˜ฃ **Soft-Banned** user **" + user.Username + "** ID: `" + user.Id + "`").ConfigureAwait(false); + await channel.SendConfirmAsync("โ˜ฃ **Soft-Banned** user **" + user.Username + "** ID: `" + user.Id + "`").ConfigureAwait(false); } catch { - await channel.SendMessageAsync("โš ๏ธ Error. Most likely I don't have sufficient permissions.").ConfigureAwait(false); + await channel.SendErrorAsync("โš ๏ธ Error. Most likely I don't have sufficient permissions.").ConfigureAwait(false); } } @@ -361,20 +324,20 @@ namespace NadekoBot.Modules.Administration if (user == null) { - await channel.SendMessageAsync("โ—๏ธUser not found.").ConfigureAwait(false); + await channel.SendErrorAsync("โ—๏ธUser not found.").ConfigureAwait(false); return; } if (umsg.Author.Id != user.Guild.OwnerId && user.Roles.Select(r => r.Position).Max() >= ((IGuildUser)umsg.Author).Roles.Select(r => r.Position).Max()) { - await channel.SendMessageAsync("โš ๏ธ You can't use this command on users with a role higher or equal to yours in the role hierarchy."); + await channel.SendErrorAsync("โš ๏ธ You can't use this command on users with a role higher or equal to yours in the role hierarchy."); return; } if (!string.IsNullOrWhiteSpace(msg)) { try { - await user.SendMessageAsync($"โ€ผ๏ธ**You have been KICKED from `{channel.Guild.Name}` server.**\n" + + await user.SendErrorAsync($"โ€ผ๏ธ**You have been KICKED from `{channel.Guild.Name}` server.**\n" + $"โš– *Reason:* {msg}").ConfigureAwait(false); await Task.Delay(2000).ConfigureAwait(false); } @@ -383,150 +346,11 @@ namespace NadekoBot.Modules.Administration try { await user.KickAsync().ConfigureAwait(false); - await channel.SendMessageAsync("โ€ผ๏ธ**Kicked** user **" + user.Username + "** ID: `" + user.Id + "`").ConfigureAwait(false); + await channel.SendConfirmAsync("โ€ผ๏ธ**Kicked** user **" + user.Username + "** ID: `" + user.Id + "`").ConfigureAwait(false); } catch { - await channel.SendMessageAsync("โš ๏ธ Error. Most likely I don't have sufficient permissions.").ConfigureAwait(false); - } - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - [Priority(1)] - public async Task SetMuteRole(IUserMessage imsg, [Remainder] string name) - { - var channel = (ITextChannel)imsg.Channel; - name = name.Trim(); - if (string.IsNullOrWhiteSpace(name)) - return; - - using (var uow = DbHandler.UnitOfWork()) - { - var config = uow.GuildConfigs.For(channel.Guild.Id, set => set); - config.MuteRoleName = name; - GuildMuteRoles.AddOrUpdate(channel.Guild.Id, name, (id, old) => name); - await uow.CompleteAsync().ConfigureAwait(false); - } - await channel.SendMessageAsync("โ˜‘๏ธ **New mute role set.**").ConfigureAwait(false); - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - [Priority(0)] - public Task SetMuteRole(IUserMessage imsg, [Remainder] IRole role) - => SetMuteRole(imsg, role.Name); - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - [RequirePermission(GuildPermission.MuteMembers)] - public async Task Mute(IUserMessage umsg, IGuildUser user) - { - var channel = (ITextChannel)umsg.Channel; - - try - { - await user.ModifyAsync(usr => usr.Mute = true).ConfigureAwait(false); - await user.AddRolesAsync(await GetMuteRole(channel.Guild).ConfigureAwait(false)).ConfigureAwait(false); - await channel.SendMessageAsync($"๐Ÿ”‡ **{user}** has been **muted** from text and voice chat successfully.").ConfigureAwait(false); - } - catch - { - await channel.SendMessageAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); - } - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - [RequirePermission(GuildPermission.MuteMembers)] - public async Task Unmute(IUserMessage umsg, IGuildUser user) - { - var channel = (ITextChannel)umsg.Channel; - - try - { - await user.ModifyAsync(usr => usr.Mute = false).ConfigureAwait(false); - await user.RemoveRolesAsync(await GetMuteRole(channel.Guild).ConfigureAwait(false)).ConfigureAwait(false); - await channel.SendMessageAsync($"๐Ÿ”‰ **{user}** has been **unmuted** from text and voice chat successfully.").ConfigureAwait(false); - } - catch - { - await channel.SendMessageAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); - } - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task ChatMute(IUserMessage umsg, IGuildUser user) - { - var channel = (ITextChannel)umsg.Channel; - - try - { - await user.AddRolesAsync(await GetMuteRole(channel.Guild).ConfigureAwait(false)).ConfigureAwait(false); - await channel.SendMessageAsync($"โœ๏ธ๐Ÿšซ **{user}** has been **muted** from chatting successfully.").ConfigureAwait(false); - } - catch - { - await channel.SendMessageAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); - } - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.ManageRoles)] - public async Task ChatUnmute(IUserMessage umsg, IGuildUser user) - { - var channel = (ITextChannel)umsg.Channel; - - try - { - await user.RemoveRolesAsync(await GetMuteRole(channel.Guild).ConfigureAwait(false)).ConfigureAwait(false); - await channel.SendMessageAsync($"โœ๏ธโœ… **{user}** has been **unmuted** from chatting successfully.").ConfigureAwait(false); - } - catch - { - await channel.SendMessageAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); - } - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.MuteMembers)] - public async Task VoiceMute(IUserMessage umsg, IGuildUser user) - { - var channel = (ITextChannel)umsg.Channel; - - try - { - await user.ModifyAsync(usr => usr.Mute = true).ConfigureAwait(false); - await channel.SendMessageAsync($"๐ŸŽ™๐Ÿšซ **{user}** has been **voice muted** successfully.").ConfigureAwait(false); - } - catch - { - await channel.SendMessageAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); - } - } - - [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] - [RequirePermission(GuildPermission.MuteMembers)] - public async Task VoiceUnmute(IUserMessage umsg, IGuildUser user) - { - var channel = (ITextChannel)umsg.Channel; - try - { - await user.ModifyAsync(usr => usr.Mute = false).ConfigureAwait(false); - await channel.SendMessageAsync($"๐ŸŽ™โœ… **{user}** has been **voice unmuted** successfully.").ConfigureAwait(false); - } - catch - { - await channel.SendMessageAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + await channel.SendErrorAsync("โš ๏ธ Error. Most likely I don't have sufficient permissions.").ConfigureAwait(false); } } @@ -545,11 +369,11 @@ namespace NadekoBot.Modules.Administration { await u.ModifyAsync(usr=>usr.Deaf = true).ConfigureAwait(false); } - await channel.SendMessageAsync("๐Ÿ”‡ **Deafen** successful.").ConfigureAwait(false); + await channel.SendConfirmAsync("๐Ÿ”‡ **Deafen** successful.").ConfigureAwait(false); } catch { - await channel.SendMessageAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + await channel.SendErrorAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); } } @@ -568,11 +392,11 @@ namespace NadekoBot.Modules.Administration { await u.ModifyAsync(usr=> usr.Deaf = false).ConfigureAwait(false); } - await channel.SendMessageAsync("๐Ÿ”Š **Undeafen** successful.").ConfigureAwait(false); + await channel.SendConfirmAsync("๐Ÿ”Š **Undeafen** successful.").ConfigureAwait(false); } catch { - await channel.SendMessageAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + await channel.SendErrorAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); } } @@ -582,7 +406,7 @@ namespace NadekoBot.Modules.Administration public async Task DelVoiChanl(IUserMessage umsg, [Remainder] IVoiceChannel voiceChannel) { await voiceChannel.DeleteAsync().ConfigureAwait(false); - await umsg.Channel.SendMessageAsync($"๐Ÿ—‘ Removed voice channel **{voiceChannel.Name}** successfully.").ConfigureAwait(false); + await umsg.Channel.SendConfirmAsync($"๐Ÿ—‘ Removed voice channel **{voiceChannel.Name}** successfully.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -592,7 +416,7 @@ namespace NadekoBot.Modules.Administration { var channel = (ITextChannel)umsg.Channel; var ch = await channel.Guild.CreateVoiceChannelAsync(channelName).ConfigureAwait(false); - await channel.SendMessageAsync($"โœ… Created voice channel **{ch.Name}**. ID: `{ch.Id}`").ConfigureAwait(false); + await channel.SendConfirmAsync($"โœ… Created voice channel **{ch.Name}**. ID: `{ch.Id}`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -601,7 +425,7 @@ namespace NadekoBot.Modules.Administration public async Task DelTxtChanl(IUserMessage umsg, [Remainder] ITextChannel toDelete) { await toDelete.DeleteAsync().ConfigureAwait(false); - await umsg.Channel.SendMessageAsync($"๐Ÿ—‘ Removed text channel **{toDelete.Name}**. ID: `{toDelete.Id}`").ConfigureAwait(false); + await umsg.Channel.SendConfirmAsync($"๐Ÿ—‘ Removed text channel **{toDelete.Name}**. ID: `{toDelete.Id}`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -611,7 +435,7 @@ namespace NadekoBot.Modules.Administration { var channel = (ITextChannel)umsg.Channel; var txtCh = await channel.Guild.CreateTextChannelAsync(channelName).ConfigureAwait(false); - await channel.SendMessageAsync($"โœ… Added text channel **{txtCh.Name}**. ID: `{txtCh.Id}`").ConfigureAwait(false); + await channel.SendConfirmAsync($"โœ… Added text channel **{txtCh.Name}**. ID: `{txtCh.Id}`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -622,7 +446,7 @@ namespace NadekoBot.Modules.Administration var channel = (ITextChannel)umsg.Channel; topic = topic ?? ""; await channel.ModifyAsync(c => c.Topic = topic); - await channel.SendMessageAsync("๐Ÿ†— **New channel topic set.**").ConfigureAwait(false); + await channel.SendConfirmAsync("๐Ÿ†— **New channel topic set.**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -633,7 +457,7 @@ namespace NadekoBot.Modules.Administration var channel = (ITextChannel)umsg.Channel; await channel.ModifyAsync(c => c.Name = name).ConfigureAwait(false); - await channel.SendMessageAsync("๐Ÿ†— **New channel name set.**").ConfigureAwait(false); + await channel.SendConfirmAsync("๐Ÿ†— **New channel name set.**").ConfigureAwait(false); } @@ -677,38 +501,30 @@ namespace NadekoBot.Modules.Administration } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] public async Task Die(IUserMessage umsg) { - var channel = (ITextChannel)umsg.Channel; - - try { await channel.SendMessageAsync("โ„น๏ธ **Shutting down.**").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } + try { await umsg.Channel.SendConfirmAsync("โ„น๏ธ **Shutting down.**").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } await Task.Delay(2000).ConfigureAwait(false); Environment.Exit(0); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] - public async Task Setname(IUserMessage umsg, [Remainder] string newName) + public async Task SetName(IUserMessage umsg, [Remainder] string newName) { - var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(newName)) return; await (await NadekoBot.Client.GetCurrentUserAsync()).ModifyAsync(u => u.Username = newName).ConfigureAwait(false); - await channel.SendMessageAsync($"โ„น๏ธ Successfully changed name to **{newName}**").ConfigureAwait(false); + await umsg.Channel.SendConfirmAsync($"โ„น๏ธ Successfully changed name to **{newName}**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] public async Task SetAvatar(IUserMessage umsg, [Remainder] string img = null) { - var channel = (ITextChannel)umsg.Channel; - if (string.IsNullOrWhiteSpace(img)) return; @@ -724,44 +540,35 @@ namespace NadekoBot.Modules.Administration } } - await channel.SendMessageAsync("๐Ÿ†’ **New avatar set.**").ConfigureAwait(false); + await umsg.Channel.SendConfirmAsync("๐Ÿ†’ **New avatar set.**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] public async Task SetGame(IUserMessage umsg, [Remainder] string game = null) { - var channel = (ITextChannel)umsg.Channel; - game = game ?? ""; await NadekoBot.Client.SetGame(game).ConfigureAwait(false); - await channel.SendMessageAsync("๐Ÿ‘พ **New game set.**").ConfigureAwait(false); + await umsg.Channel.SendConfirmAsync("๐Ÿ‘พ **New game set.**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] public async Task SetStream(IUserMessage umsg, string url, [Remainder] string name = null) { - var channel = (ITextChannel)umsg.Channel; - name = name ?? ""; await NadekoBot.Client.SetStream(name, url).ConfigureAwait(false); - await channel.SendMessageAsync("โ„น๏ธ **New stream set.**").ConfigureAwait(false); + await umsg.Channel.SendConfirmAsync("โ„น๏ธ **New stream set.**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] public async Task Send(IUserMessage umsg, string where, [Remainder] string msg = null) { - var channel = (ITextChannel)umsg.Channel; - if (string.IsNullOrWhiteSpace(msg)) return; @@ -796,25 +603,22 @@ namespace NadekoBot.Modules.Administration } else { - await channel.SendMessageAsync("โš ๏ธ Invalid format.").ConfigureAwait(false); + await umsg.Channel.SendErrorAsync("โš ๏ธ Invalid format.").ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] public async Task Announce(IUserMessage umsg, [Remainder] string message) { - var channel = (ITextChannel)umsg.Channel; - var channels = await Task.WhenAll(NadekoBot.Client.GetGuilds().Select(g => g.GetDefaultChannelAsync() )).ConfigureAwait(false); - await Task.WhenAll(channels.Select(c => c.SendMessageAsync($"๐Ÿ†• **Message from {umsg.Author} `(Bot Owner)`:** " + message))) + await Task.WhenAll(channels.Select(c => c.SendConfirmAsync($"๐Ÿ†• Message from {umsg.Author} `[Bot Owner]`:", message))) .ConfigureAwait(false); - await channel.SendMessageAsync("๐Ÿ†—").ConfigureAwait(false); + await umsg.Channel.SendConfirmAsync("๐Ÿ†—").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -857,7 +661,7 @@ namespace NadekoBot.Modules.Administration { var channel = (ITextChannel)umsg.Channel; - string send = $"โ•{umsg.Author.Mention} __`has invoked a mention on the following roles`__โ•"; + string send = $"โ•{umsg.Author.Mention} has invoked a mention on the following roles โ•"; foreach (var role in roles) { send += $"\n**{role.Name}**\n"; @@ -877,19 +681,15 @@ namespace NadekoBot.Modules.Administration IGuild nadekoSupportServer; [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] public async Task Donators(IUserMessage umsg) { - var channel = (ITextChannel)umsg.Channel; IEnumerable donatorsOrdered; using (var uow = DbHandler.UnitOfWork()) { donatorsOrdered = uow.Donators.GetDonatorsOrdered(); } - - string str = $"**Thanks to the people listed below for making this project happen!**\n"; - await channel.SendMessageAsync(str + string.Join("โญ", donatorsOrdered.Select(d => d.Name))).ConfigureAwait(false); + await umsg.Channel.SendConfirmAsync("Thanks to the people listed below for making this project happen!", string.Join("โญ", donatorsOrdered.Select(d => d.Name))).ConfigureAwait(false); nadekoSupportServer = nadekoSupportServer ?? NadekoBot.Client.GetGuild(117523346618318850); @@ -901,17 +701,14 @@ namespace NadekoBot.Modules.Administration return; var usrs = nadekoSupportServer.GetUsers().Where(u => u.Roles.Contains(patreonRole)); - await channel.SendMessageAsync("\n`Patreon supporters:`\n" + string.Join("โญ", usrs.Select(d => d.Username))).ConfigureAwait(false); + await umsg.Channel.SendConfirmAsync("Patreon supporters", string.Join("โญ", usrs.Select(d => d.Username))).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] public async Task Donadd(IUserMessage umsg, IUser donator, int amount) { - var channel = (ITextChannel)umsg.Channel; - Donator don; using (var uow = DbHandler.UnitOfWork()) { @@ -919,7 +716,7 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync(); } - await channel.SendMessageAsync($"Successfuly added a new donator. Total donated amount from this user: {don.Amount} ๐Ÿ‘‘").ConfigureAwait(false); + await umsg.Channel.SendConfirmAsync($"Successfuly added a new donator. Total donated amount from this user: {don.Amount} ๐Ÿ‘‘").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/AntiRaidCommands.cs b/src/NadekoBot/Modules/Administration/Commands/AntiRaidCommands.cs index 3003a00f..29f465df 100644 --- a/src/NadekoBot/Modules/Administration/Commands/AntiRaidCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/AntiRaidCommands.cs @@ -1,6 +1,7 @@ ๏ปฟusing Discord; using Discord.Commands; using NadekoBot.Attributes; +using NadekoBot.Extensions; using NLog; using System; using System.Collections.Concurrent; @@ -105,7 +106,7 @@ namespace NadekoBot.Modules.Administration { if (spamSettings.UserStats.TryRemove(msg.Author.Id, out stats)) { - await PunishUsers(spamSettings.Action, await GetMuteRole(channel.Guild), ProtectionType.Spamming, (IGuildUser)msg.Author) + await PunishUsers(spamSettings.Action, ProtectionType.Spamming, (IGuildUser)msg.Author) .ConfigureAwait(false); } } @@ -136,7 +137,7 @@ namespace NadekoBot.Modules.Administration var users = settings.RaidUsers.ToArray(); settings.RaidUsers.Clear(); - await PunishUsers(settings.Action, await GetMuteRole(usr.Guild), ProtectionType.Raiding, users).ConfigureAwait(false); + await PunishUsers(settings.Action, ProtectionType.Raiding, users).ConfigureAwait(false); } await Task.Delay(1000 * settings.Seconds).ConfigureAwait(false); @@ -148,7 +149,7 @@ namespace NadekoBot.Modules.Administration }; } - private static async Task PunishUsers(PunishmentAction action, IRole muteRole, ProtectionType pt, params IGuildUser[] gus) + private static async Task PunishUsers(PunishmentAction action, ProtectionType pt, params IGuildUser[] gus) { foreach (var gu in gus) { @@ -157,21 +158,21 @@ namespace NadekoBot.Modules.Administration case PunishmentAction.Mute: try { - await gu.AddRolesAsync(muteRole); + await MuteCommands.Mute(gu).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex, "I can't apply punishement"); } break; case PunishmentAction.Kick: try { - await gu.Guild.AddBanAsync(gu, 7); + await gu.Guild.AddBanAsync(gu, 7).ConfigureAwait(false); try { - await gu.Guild.RemoveBanAsync(gu); + await gu.Guild.RemoveBanAsync(gu).ConfigureAwait(false); } catch { - await gu.Guild.RemoveBanAsync(gu); + await gu.Guild.RemoveBanAsync(gu).ConfigureAwait(false); // try it twice, really don't want to ban user if // only kick has been specified as the punishement } @@ -181,7 +182,7 @@ namespace NadekoBot.Modules.Administration case PunishmentAction.Ban: try { - await gu.Guild.AddBanAsync(gu, 7); + await gu.Guild.AddBanAsync(gu, 7).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex, "I can't apply punishment"); } break; @@ -202,23 +203,23 @@ namespace NadekoBot.Modules.Administration if (userThreshold < 2 || userThreshold > 30) { - await channel.SendMessageAsync("โ—๏ธUser threshold must be between **2** and **30**.").ConfigureAwait(false); + await channel.SendErrorAsync("โ—๏ธUser threshold must be between **2** and **30**.").ConfigureAwait(false); return; } if (seconds < 2 || seconds > 300) { - await channel.SendMessageAsync("โ—๏ธTime must be between **2** and **300** seconds.").ConfigureAwait(false); + await channel.SendErrorAsync("โ—๏ธTime must be between **2** and **300** seconds.").ConfigureAwait(false); return; } try { - await GetMuteRole(channel.Guild).ConfigureAwait(false); + await MuteCommands.GetMuteRole(channel.Guild).ConfigureAwait(false); } catch (Exception ex) { - await channel.SendMessageAsync("โš ๏ธ Failed creating a mute role. Give me ManageRoles permission" + + await channel.SendConfirmAsync("โš ๏ธ Failed creating a mute role. Give me ManageRoles permission" + "or create 'nadeko-mute' role with disabled SendMessages and try again.") .ConfigureAwait(false); _log.Warn(ex); @@ -233,7 +234,7 @@ namespace NadekoBot.Modules.Administration }; antiRaidGuilds.AddOrUpdate(channel.Guild.Id, setting, (id, old) => setting); - await channel.SendMessageAsync($"โ„น๏ธ {imsg.Author.Mention} If **{userThreshold}** or more users join within **{seconds}** seconds, I will **{action}** them.") + await channel.SendConfirmAsync($"โ„น๏ธ {imsg.Author.Mention} If **{userThreshold}** or more users join within **{seconds}** seconds, I will **{action}** them.") .ConfigureAwait(false); } @@ -250,17 +251,17 @@ namespace NadekoBot.Modules.Administration AntiSpamSetting throwaway; if (antiSpamGuilds.TryRemove(channel.Guild.Id, out throwaway)) { - await channel.SendMessageAsync("๐Ÿ†— **Anti-Spam feature** has been **disabled** on this server.").ConfigureAwait(false); + await channel.SendConfirmAsync("๐Ÿ†— **Anti-Spam feature** has been **disabled** on this server.").ConfigureAwait(false); } else { try { - await GetMuteRole(channel.Guild).ConfigureAwait(false); + await MuteCommands.GetMuteRole(channel.Guild).ConfigureAwait(false); } catch (Exception ex) { - await channel.SendMessageAsync("โš ๏ธ Failed creating a mute role. Give me ManageRoles permission" + + await channel.SendErrorAsync("โš ๏ธ Failed creating a mute role. Give me ManageRoles permission" + "or create 'nadeko-mute' role with disabled SendMessages and try again.") .ConfigureAwait(false); _log.Warn(ex); @@ -272,7 +273,7 @@ namespace NadekoBot.Modules.Administration Action = action, MessageThreshold = messageCount, })) - await channel.SendMessageAsync("โœ… **Anti-Spam feature** has been **enabled** on this server.").ConfigureAwait(false); + await channel.SendConfirmAsync("โœ… **Anti-Spam feature** has been **enabled** on this server.").ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/Administration/Commands/AutoAssignRoleCommands.cs b/src/NadekoBot/Modules/Administration/Commands/AutoAssignRoleCommands.cs index 3511b454..e834e80b 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 NadekoBot.Services.Database.Models; using NLog; @@ -26,11 +27,7 @@ namespace NadekoBot.Modules.Administration { try { - GuildConfig conf; - using (var uow = DbHandler.UnitOfWork()) - { - conf = uow.GuildConfigs.For(user.Guild.Id, set => set); - } + GuildConfig conf = NadekoBot.AllGuildConfigs.FirstOrDefault(gc => gc.GuildId == user.Guild.Id); if (conf.AutoAssignRoleId == 0) return; @@ -67,11 +64,11 @@ namespace NadekoBot.Modules.Administration if (role == null) { - await channel.SendMessageAsync("๐Ÿ†— **Auto assign role** on user join is now **disabled**.").ConfigureAwait(false); + await channel.SendConfirmAsync("๐Ÿ†— **Auto assign role** on user join is now **disabled**.").ConfigureAwait(false); return; } - await channel.SendMessageAsync("โœ… **Auto assign role** on user join is now **enabled**.").ConfigureAwait(false); + await channel.SendConfirmAsync("โœ… **Auto assign role** on user join is now **enabled**.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs b/src/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs index fc71e58b..7867a078 100644 --- a/src/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs +++ b/src/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs @@ -67,7 +67,7 @@ namespace NadekoBot.Modules.Administration if (Subscribers.TryAdd(token, set)) { set.Add(channel); - await ((IGuildUser)msg.Author).SendMessageAsync("This is your CSC token:" + token.ToString()).ConfigureAwait(false); + await ((IGuildUser)msg.Author).SendConfirmAsync("This is your CSC token", token.ToString()).ConfigureAwait(false); } } @@ -82,7 +82,7 @@ namespace NadekoBot.Modules.Administration if (!Subscribers.TryGetValue(token, out set)) return; set.Add(channel); - await channel.SendMessageAsync(":ok:").ConfigureAwait(false); + await channel.SendConfirmAsync("Joined cross server channel.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -96,7 +96,7 @@ namespace NadekoBot.Modules.Administration { subscriber.Value.TryRemove(channel); } - await channel.SendMessageAsync(":ok:").ConfigureAwait(false); + await channel.SendMessageAsync("Left cross server channel.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/DMForwardCommands.cs b/src/NadekoBot/Modules/Administration/Commands/DMForwardCommands.cs index 2930ecea..fac9949e 100644 --- a/src/NadekoBot/Modules/Administration/Commands/DMForwardCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/DMForwardCommands.cs @@ -1,6 +1,7 @@ ๏ปฟusing Discord; using Discord.Commands; using NadekoBot.Attributes; +using NadekoBot.Extensions; using NadekoBot.Services; using System.Collections.Generic; using System.Linq; @@ -39,9 +40,9 @@ namespace NadekoBot.Modules.Administration uow.Complete(); } if (ForwardDMs) - await channel.SendMessageAsync("โœ… **I will forward DMs from now on.**").ConfigureAwait(false); + await channel.SendConfirmAsync("โœ… **I will forward DMs from now on.**").ConfigureAwait(false); else - await channel.SendMessageAsync("๐Ÿ†— **I will stop forwarding DMs from now on.**").ConfigureAwait(false); + await channel.SendConfirmAsync("๐Ÿ†— **I will stop forwarding DMs from now on.**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -57,9 +58,9 @@ namespace NadekoBot.Modules.Administration uow.Complete(); } if (ForwardDMsToAllOwners) - await channel.SendMessageAsync("โ„น๏ธ **I will forward DMs to all owners.**").ConfigureAwait(false); + await channel.SendConfirmAsync("โ„น๏ธ **I will forward DMs to all owners.**").ConfigureAwait(false); else - await channel.SendMessageAsync("โ„น๏ธ **I will forward DMs only to the first owner.**").ConfigureAwait(false); + await channel.SendConfirmAsync("โ„น๏ธ **I will forward DMs only to the first owner.**").ConfigureAwait(false); } @@ -67,17 +68,17 @@ namespace NadekoBot.Modules.Administration { if (ForwardDMs && ownerChannels.Any()) { - var toSend = $"```markdown\n I received a message from [{msg.Author}]({msg.Author.Id}): {msg.Content}```"; + var title = $"DM from [{msg.Author}]({msg.Author.Id})"; if (ForwardDMsToAllOwners) { var msgs = await Task.WhenAll(ownerChannels.Where(ch => ch.Recipient.Id != msg.Author.Id) - .Select(ch => ch.SendMessageAsync(toSend))).ConfigureAwait(false); + .Select(ch => ch.SendConfirmAsync(title, msg.Content))).ConfigureAwait(false); } else { var firstOwnerChannel = ownerChannels.First(); if (firstOwnerChannel.Recipient.Id != msg.Author.Id) - try { await firstOwnerChannel.SendMessageAsync(toSend).ConfigureAwait(false); } catch { } + try { await firstOwnerChannel.SendConfirmAsync(title, msg.Content).ConfigureAwait(false); } catch { } } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs index 9913c53b..06ebe4e8 100644 --- a/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs @@ -79,6 +79,73 @@ namespace NadekoBot.Modules.Administration _client.ChannelCreated += _client_ChannelCreated; _client.ChannelDestroyed += _client_ChannelDestroyed; _client.ChannelUpdated += _client_ChannelUpdated; + + MuteCommands.UserMuted += MuteCommands_UserMuted; + MuteCommands.UserUnmuted += MuteCommands_UserUnmuted; + } + + private Task MuteCommands_UserMuted(IGuildUser usr, MuteCommands.MuteType muteType) + { + LogSetting logSetting; + if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out logSetting) + || !logSetting.IsLogging) + return Task.CompletedTask; + + ITextChannel logChannel; + if ((logChannel = TryGetLogChannel(usr.Guild, logSetting)) == null) + return Task.CompletedTask; + + var task = Task.Run(async () => + { + string mutes = ""; + switch (muteType) + { + case MuteCommands.MuteType.Voice: + mutes = "voice chat"; + break; + case MuteCommands.MuteType.Chat: + mutes = "text chat"; + break; + case MuteCommands.MuteType.All: + mutes = "text and voice chat"; + break; + } + try { await logChannel.SendMessageAsync($"โ€ผ๏ธ๐Ÿ••`{prettyCurrentTime}`๐Ÿ‘ค__**{usr.Username}#{usr.Discriminator}**__๐Ÿ”‡ **| User muted from the {mutes}. |** ๐Ÿ†” `{usr.Id}`").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } + }); + + return Task.CompletedTask; + } + + private Task MuteCommands_UserUnmuted(IGuildUser usr, MuteCommands.MuteType muteType) + { + LogSetting logSetting; + if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out logSetting) + || !logSetting.IsLogging) + return Task.CompletedTask; + + ITextChannel logChannel; + if ((logChannel = TryGetLogChannel(usr.Guild, logSetting)) == null) + return Task.CompletedTask; + + var task = Task.Run(async () => + { + string mutes = ""; + switch (muteType) + { + case MuteCommands.MuteType.Voice: + mutes = "voice chat"; + break; + case MuteCommands.MuteType.Chat: + mutes = "text chat"; + break; + case MuteCommands.MuteType.All: + mutes = "text and voice chat"; + break; + } + try { await logChannel.SendMessageAsync($"โ€ผ๏ธ๐Ÿ••`{prettyCurrentTime}`๐Ÿ‘ค__**{usr.Username}#{usr.Discriminator}**__๐Ÿ”Š **| User unmuted from the {mutes}. |** ๐Ÿ†” `{usr.Id}`").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } + }); + + return Task.CompletedTask; } public static async Task TriggeredAntiProtection(IGuildUser[] users, PunishmentAction action, ProtectionType protection) @@ -470,38 +537,6 @@ namespace NadekoBot.Modules.Administration return Task.CompletedTask; } -// private Task _client_MessageReceived(IMessage imsg) -// { -// var msg = imsg as IUserMessage; -// if (msg == null || msg.IsAuthor()) -// return Task.CompletedTask; - -// var channel = msg.Channel as ITextChannel; -// if (channel == null) -// return Task.CompletedTask; - -// LogSetting logSetting; -// if (!GuildLogSettings.TryGetValue(channel.Guild.Id, out logSetting) -// || !logSetting.IsLogging -// || !logSetting.MessageReceived) -// return Task.CompletedTask; - -// ITextChannel logChannel; -// if ((logChannel = TryGetLogChannel(channel.Guild, logSetting)) == null || logChannel.Id == imsg.Channel.Id) -// return Task.CompletedTask; - -// var task = Task.Run(async () => -// { -// var str = $@"๐Ÿ•”`{prettyCurrentTime}` **New Message** `#{channel.Name}` -//๐Ÿ‘ค`{msg.Author.Username}`: {msg.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator)}"; -// if (msg.Attachments.Any()) -// str += $"{Environment.NewLine}`Attachements`: {string.Join(", ", msg.Attachments.Select(a => a.ProxyUrl))}"; -// await logChannel.SendMessageAsync(str).ConfigureAwait(false); -// }); - -// return Task.CompletedTask; -// } - private enum LogChannelType { Text, Voice, UserPresence }; private static ITextChannel TryGetLogChannel(IGuild guild, LogSetting logSetting, LogChannelType logChannelType = LogChannelType.Text) { diff --git a/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs b/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs index 8f00eded..583f0f05 100644 --- a/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs +++ b/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs @@ -2,6 +2,7 @@ using Discord.Commands; using Discord.WebSocket; using NadekoBot.Attributes; +using NadekoBot.Extensions; using NadekoBot.Services; using NadekoBot.Services.Database.Models; using NLog; @@ -88,7 +89,7 @@ namespace NadekoBot.Modules.Administration RepeatRunner rep; if (!repeaters.TryGetValue(channel.Id, out rep)) { - await channel.SendMessageAsync("โ„น๏ธ **No repeating message found on this server.**").ConfigureAwait(false); + await channel.SendErrorAsync("โ„น๏ธ **No repeating message found on this server.**").ConfigureAwait(false); return; } rep.Reset(); @@ -110,10 +111,10 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync(); } rep.Stop(); - await channel.SendMessageAsync("โœ… **Stopped repeating a message.**").ConfigureAwait(false); + await channel.SendConfirmAsync("โœ… **Stopped repeating a message.**").ConfigureAwait(false); } else - await channel.SendMessageAsync("โ„น๏ธ **No message is repeating.**").ConfigureAwait(false); + await channel.SendConfirmAsync("โ„น๏ธ **No message is repeating.**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -159,7 +160,7 @@ namespace NadekoBot.Modules.Administration return old; }); - await channel.SendMessageAsync($"๐Ÿ” Repeating **\"{rep.Repeater.Message}\"** every `{rep.Repeater.Interval.Days} day(s), {rep.Repeater.Interval.Hours} hour(s) and {rep.Repeater.Interval.Minutes} minute(s)`.").ConfigureAwait(false); + await channel.SendConfirmAsync($"๐Ÿ” Repeating **\"{rep.Repeater.Message}\"** every `{rep.Repeater.Interval.Days} day(s), {rep.Repeater.Interval.Hours} hour(s) and {rep.Repeater.Interval.Minutes} minute(s)`.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/MuteCommands.cs b/src/NadekoBot/Modules/Administration/Commands/MuteCommands.cs new file mode 100644 index 00000000..b4ce345a --- /dev/null +++ b/src/NadekoBot/Modules/Administration/Commands/MuteCommands.cs @@ -0,0 +1,280 @@ +๏ปฟ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.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.Modules.Administration +{ + public partial class Administration + { + [Group] + public class MuteCommands + { + private static ConcurrentDictionary GuildMuteRoles { get; } = new ConcurrentDictionary(); + + private static ConcurrentDictionary> MutedUsers { get; } = new ConcurrentDictionary>(); + + public static event Func UserMuted = delegate { return Task.CompletedTask; }; + public static event Func UserUnmuted = delegate { return Task.CompletedTask; }; + + + public enum MuteType { + Voice, + Chat, + All + } + + static MuteCommands() { + using (var uow = DbHandler.UnitOfWork()) + { + var configs = NadekoBot.AllGuildConfigs; + GuildMuteRoles = new ConcurrentDictionary(configs + .Where(c => !string.IsNullOrWhiteSpace(c.MuteRoleName)) + .ToDictionary(c => c.GuildId, c => c.MuteRoleName)); + + MutedUsers = new ConcurrentDictionary>(configs.ToDictionary( + k => k.GuildId, + v => new ConcurrentHashSet(v.MutedUsers.Select(m => m.UserId)) + )); + } + + NadekoBot.Client.UserJoined += Client_UserJoined; + } + + private static async Task Client_UserJoined(IGuildUser usr) + { + ConcurrentHashSet muted; + MutedUsers.TryGetValue(usr.Guild.Id, out muted); + + if (muted == null || !muted.Contains(usr.Id)) + return; + else + await Mute(usr).ConfigureAwait(false); + + } + + public static async Task Mute(IGuildUser usr) + { + await usr.ModifyAsync(x => x.Mute = true).ConfigureAwait(false); + await usr.AddRolesAsync(await GetMuteRole(usr.Guild)).ConfigureAwait(false); + using (var uow = DbHandler.UnitOfWork()) + { + var config = uow.GuildConfigs.For(usr.Guild.Id, set => set.Include(gc => gc.MutedUsers)); + config.MutedUsers.Add(new MutedUserId() + { + UserId = usr.Id + }); + ConcurrentHashSet muted; + if (MutedUsers.TryGetValue(usr.Guild.Id, out muted)) + muted.Add(usr.Id); + + await uow.CompleteAsync().ConfigureAwait(false); + } + await UserMuted(usr, MuteType.All).ConfigureAwait(false); + } + + public static async Task Unmute(IGuildUser usr) + { + await usr.ModifyAsync(x => x.Mute = false).ConfigureAwait(false); + await usr.RemoveRolesAsync(await GetMuteRole(usr.Guild)).ConfigureAwait(false); + using (var uow = DbHandler.UnitOfWork()) + { + var config = uow.GuildConfigs.For(usr.Guild.Id, set => set.Include(gc => gc.MutedUsers)); + config.MutedUsers.Remove(new MutedUserId() + { + UserId = usr.Id + }); + ConcurrentHashSet muted; + if (MutedUsers.TryGetValue(usr.Guild.Id, out muted)) + muted.TryRemove(usr.Id); + await uow.CompleteAsync().ConfigureAwait(false); + } + await UserUnmuted(usr, MuteType.All).ConfigureAwait(false); + } + + public static async Task GetMuteRole(IGuild guild) + { + const string defaultMuteRoleName = "nadeko-mute"; + + var muteRoleName = GuildMuteRoles.GetOrAdd(guild.Id, defaultMuteRoleName); + + var muteRole = guild.Roles.FirstOrDefault(r => r.Name == muteRoleName); + if (muteRole == null) + { + + //if it doesn't exist, create it + try { muteRole = await guild.CreateRoleAsync(muteRoleName, GuildPermissions.None).ConfigureAwait(false); } + catch + { + //if creations fails, maybe the name is not correct, find default one, if doesn't work, create default one + muteRole = guild.Roles.FirstOrDefault(r => r.Name == muteRoleName) ?? + await guild.CreateRoleAsync(defaultMuteRoleName, GuildPermissions.None).ConfigureAwait(false); + } + + foreach (var toOverwrite in guild.GetTextChannels()) + { + try + { + await toOverwrite.AddPermissionOverwriteAsync(muteRole, new OverwritePermissions(sendMessages: PermValue.Deny, attachFiles: PermValue.Deny)) + .ConfigureAwait(false); + } + catch { } + await Task.Delay(200).ConfigureAwait(false); + } + } + return muteRole; + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + [Priority(1)] + public async Task SetMuteRole(IUserMessage imsg, [Remainder] string name) + { + var channel = (ITextChannel)imsg.Channel; + name = name.Trim(); + if (string.IsNullOrWhiteSpace(name)) + return; + + using (var uow = DbHandler.UnitOfWork()) + { + var config = uow.GuildConfigs.For(channel.Guild.Id, set => set); + config.MuteRoleName = name; + GuildMuteRoles.AddOrUpdate(channel.Guild.Id, name, (id, old) => name); + await uow.CompleteAsync().ConfigureAwait(false); + } + await channel.SendConfirmAsync("โ˜‘๏ธ **New mute role set.**").ConfigureAwait(false); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + [Priority(0)] + public Task SetMuteRole(IUserMessage imsg, [Remainder] IRole role) + => SetMuteRole(imsg, role.Name); + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + [RequirePermission(GuildPermission.MuteMembers)] + public async Task Mute(IUserMessage umsg, IGuildUser user) + { + var channel = (ITextChannel)umsg.Channel; + + try + { + await Mute(user).ConfigureAwait(false); + await channel.SendConfirmAsync($"๐Ÿ”‡ **{user}** has been **muted** from text and voice chat.").ConfigureAwait(false); + } + catch + { + await channel.SendErrorAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + } + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + [RequirePermission(GuildPermission.MuteMembers)] + public async Task Unmute(IUserMessage umsg, IGuildUser user) + { + var channel = (ITextChannel)umsg.Channel; + + try + { + await Unmute(user).ConfigureAwait(false); + await channel.SendConfirmAsync($"๐Ÿ”‰ **{user}** has been **unmuted** from text and voice chat.").ConfigureAwait(false); + } + catch + { + await channel.SendErrorAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + } + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + public async Task ChatMute(IUserMessage umsg, IGuildUser user) + { + var channel = (ITextChannel)umsg.Channel; + + try + { + await user.AddRolesAsync(await GetMuteRole(channel.Guild).ConfigureAwait(false)).ConfigureAwait(false); + await UserMuted(user, MuteType.Chat).ConfigureAwait(false); + await channel.SendConfirmAsync($"โœ๏ธ๐Ÿšซ **{user}** has been **muted** from chatting.").ConfigureAwait(false); + } + catch + { + await channel.SendErrorAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + } + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + public async Task ChatUnmute(IUserMessage umsg, IGuildUser user) + { + var channel = (ITextChannel)umsg.Channel; + + try + { + await user.RemoveRolesAsync(await GetMuteRole(channel.Guild).ConfigureAwait(false)).ConfigureAwait(false); + await UserUnmuted(user, MuteType.Chat).ConfigureAwait(false); + await channel.SendConfirmAsync($"โœ๏ธโœ… **{user}** has been **unmuted** from chatting.").ConfigureAwait(false); + } + catch + { + await channel.SendErrorAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + } + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.MuteMembers)] + public async Task VoiceMute(IUserMessage umsg, IGuildUser user) + { + var channel = (ITextChannel)umsg.Channel; + + try + { + await user.ModifyAsync(usr => usr.Mute = true).ConfigureAwait(false); + await UserMuted(user, MuteType.Voice).ConfigureAwait(false); + await channel.SendConfirmAsync($"๐ŸŽ™๐Ÿšซ **{user}** has been **voice muted**.").ConfigureAwait(false); + } + catch + { + await channel.SendErrorAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + } + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.MuteMembers)] + public async Task VoiceUnmute(IUserMessage umsg, IGuildUser user) + { + var channel = (ITextChannel)umsg.Channel; + try + { + await user.ModifyAsync(usr => usr.Mute = false).ConfigureAwait(false); + await UserUnmuted(user, MuteType.Voice).ConfigureAwait(false); + await channel.SendConfirmAsync($"๐ŸŽ™โœ… **{user}** has been **voice unmuted**.").ConfigureAwait(false); + } + catch + { + await channel.SendErrorAsync("โš ๏ธ I most likely don't have the permission necessary for that.").ConfigureAwait(false); + } + } + } + } +} diff --git a/src/NadekoBot/Modules/Administration/Commands/PlayingRotateCommands.cs b/src/NadekoBot/Modules/Administration/Commands/PlayingRotateCommands.cs index 4490603f..2d8e7921 100644 --- a/src/NadekoBot/Modules/Administration/Commands/PlayingRotateCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/PlayingRotateCommands.cs @@ -87,12 +87,9 @@ namespace NadekoBot.Modules.Administration }; [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] public async Task RotatePlaying(IUserMessage umsg) { - var channel = (ITextChannel)umsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var config = uow.BotConfig.GetOrCreate(); @@ -101,18 +98,15 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync(); } if (RotatingStatuses) - await channel.SendMessageAsync("๐Ÿ†— **Rotating playing status enabled.**"); + await umsg.Channel.SendConfirmAsync("๐Ÿ†— **Rotating playing status enabled.**").ConfigureAwait(false); else - await channel.SendMessageAsync("โ„น๏ธ **Rotating playing status disabled.**"); + await umsg.Channel.SendConfirmAsync("โ„น๏ธ **Rotating playing status disabled.**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] public async Task AddPlaying(IUserMessage umsg, [Remainder] string status) { - var channel = (ITextChannel)umsg.Channel; - using (var uow = DbHandler.UnitOfWork()) { var config = uow.BotConfig.GetOrCreate(); @@ -122,33 +116,27 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync(); } - await channel.SendMessageAsync("โœ… **Added.**").ConfigureAwait(false); + await umsg.Channel.SendConfirmAsync("โœ… **Added.**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] public async Task ListPlaying(IUserMessage umsg) { - var channel = (ITextChannel)umsg.Channel; - - if (!RotatingStatusMessages.Any()) - await channel.SendMessageAsync("โŽ **No rotating playing statuses set.**"); + await umsg.Channel.SendErrorAsync("โŽ **No rotating playing statuses set.**"); else { var i = 1; - await channel.SendMessageAsync($"โ„น๏ธ {umsg.Author.Mention} `Here is a list of rotating statuses:`\n\n\t" + string.Join("\n\t", RotatingStatusMessages.Select(rs => $"`{i++}.` {rs.Status}"))); + await umsg.Channel.SendConfirmAsync($"โ„น๏ธ {umsg.Author.Mention} `Here is a list of rotating statuses:`\n\n\t" + string.Join("\n\t", RotatingStatusMessages.Select(rs => $"`{i++}.` {rs.Status}"))); } } [NadekoCommand, Usage, Description, Aliases] - [RequireContext(ContextType.Guild)] [OwnerOnly] public async Task RemovePlaying(IUserMessage umsg, int index) { - var channel = (ITextChannel)umsg.Channel; index -= 1; string msg = ""; @@ -163,7 +151,7 @@ namespace NadekoBot.Modules.Administration RotatingStatusMessages.RemoveAt(index); await uow.CompleteAsync(); } - await channel.SendMessageAsync($"๐Ÿ—‘ **Removed the the playing message:** {msg}").ConfigureAwait(false); + await umsg.Channel.SendConfirmAsync($"๐Ÿ—‘ **Removed the the playing message:** {msg}").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs index fe9b4639..d4e74299 100644 --- a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs @@ -94,7 +94,7 @@ namespace NadekoBot.Modules.Administration if (RatelimitingChannels.TryRemove(channel.Id, out throwaway)) { throwaway.cancelSource.Cancel(); - await channel.SendMessageAsync("โ„น๏ธ **Slow mode disabled.**").ConfigureAwait(false); + await channel.SendConfirmAsync("โ„น๏ธ Slow mode disabled.").ConfigureAwait(false); return; } } @@ -109,7 +109,7 @@ namespace NadekoBot.Modules.Administration if (msg < 1 || perSec < 1 || msg > 100 || perSec > 3600) { - await channel.SendMessageAsync("โš ๏ธ `Invalid parameters.`"); + await channel.SendErrorAsync("โš ๏ธ Invalid parameters."); return; } var toAdd = new Ratelimiter() @@ -120,8 +120,8 @@ namespace NadekoBot.Modules.Administration }; if(RatelimitingChannels.TryAdd(channel.Id, toAdd)) { - await channel.SendMessageAsync("โœ… **Slow mode initiated: " + - $"Users can't send more than `{toAdd.MaxMessages} message(s)` every `{toAdd.PerSeconds} second(s)`.**") + await channel.SendConfirmAsync("Slow mode initiated", + $"Users can't send more than `{toAdd.MaxMessages} message(s)` every `{toAdd.PerSeconds} second(s)`.") .ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs index 2e8a0b87..dfd8b0a7 100644 --- a/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs @@ -1,6 +1,7 @@ ๏ปฟusing Discord; using Discord.Commands; using NadekoBot.Attributes; +using NadekoBot.Extensions; using NadekoBot.Services; using NadekoBot.Services.Database.Models; using System; @@ -32,7 +33,7 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"โ„น๏ธ Automatic deleting of `iam` and `iamn` confirmations has been {(newval ? "**enabled**" : "**disabled**")}.") + await channel.SendConfirmAsync($"โ„น๏ธ Automatic deleting of `iam` and `iamn` confirmations has been {(newval ? "**enabled**" : "**disabled**")}.") .ConfigureAwait(false); } @@ -51,7 +52,8 @@ namespace NadekoBot.Modules.Administration roles = uow.SelfAssignedRoles.GetFromGuild(channel.Guild.Id); if (roles.Any(s => s.RoleId == role.Id && s.GuildId == role.GuildId)) { - msg = $"๐Ÿ’ข Role **{role.Name}** is already in the list."; + await channel.SendMessageAsync($"๐Ÿ’ข Role **{role.Name}** is already in the list.").ConfigureAwait(false); + return; } else { @@ -63,7 +65,7 @@ namespace NadekoBot.Modules.Administration msg = $"๐Ÿ†— Role **{role.Name}** added to the list."; } } - await channel.SendMessageAsync(msg.ToString()).ConfigureAwait(false); + await channel.SendConfirmAsync(msg.ToString()).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -81,10 +83,10 @@ namespace NadekoBot.Modules.Administration } if (!success) { - await channel.SendMessageAsync("โŽ That role is not self-assignable.").ConfigureAwait(false); + await channel.SendErrorAsync("โŽ That role is not self-assignable.").ConfigureAwait(false); return; } - await channel.SendMessageAsync($"๐Ÿ—‘ **{role.Name}** has been removed from the list of self-assignable roles.").ConfigureAwait(false); + await channel.SendConfirmAsync($"๐Ÿ—‘ **{role.Name}** has been removed from the list of self-assignable roles.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -96,10 +98,12 @@ namespace NadekoBot.Modules.Administration var toRemove = new ConcurrentHashSet(); var removeMsg = new StringBuilder(); var msg = new StringBuilder(); + var roleCnt = 0; using (var uow = DbHandler.UnitOfWork()) { - var roleModels = uow.SelfAssignedRoles.GetFromGuild(channel.Guild.Id); - msg.AppendLine($"โ„น๏ธ There are `{roleModels.Count()}` self assignable roles:"); + var roleModels = uow.SelfAssignedRoles.GetFromGuild(channel.Guild.Id).ToList(); + roleCnt = roleModels.Count; + msg.AppendLine(); foreach (var roleModel in roleModels) { @@ -119,7 +123,7 @@ namespace NadekoBot.Modules.Administration } await uow.CompleteAsync(); } - await channel.SendMessageAsync(msg.ToString() + "\n\n" + removeMsg.ToString()).ConfigureAwait(false); + await channel.SendConfirmAsync($"โ„น๏ธ There are `{roleCnt}` self assignable roles:", msg.ToString() + "\n\n" + removeMsg.ToString()).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -138,7 +142,7 @@ namespace NadekoBot.Modules.Administration await uow.CompleteAsync(); } string exl = areExclusive ? "**exclusive**." : "**not exclusive**."; - await channel.SendMessageAsync("โ„น๏ธ Self assigned roles are now " + exl); + await channel.SendConfirmAsync("โ„น๏ธ Self assigned roles are now " + exl); } [NadekoCommand, Usage, Description, Aliases] @@ -159,12 +163,12 @@ namespace NadekoBot.Modules.Administration SelfAssignedRole roleModel; if ((roleModel = roles.FirstOrDefault(r=>r.RoleId == role.Id)) == null) { - await channel.SendMessageAsync("๐Ÿ’ข That role is not self-assignable.").ConfigureAwait(false); + await channel.SendErrorAsync("That role is not self-assignable.").ConfigureAwait(false); return; } if (guildUser.Roles.Contains(role)) { - await channel.SendMessageAsync($"โŽ You already have **{role.Name}** role.").ConfigureAwait(false); + await channel.SendErrorAsync($"You already have **{role.Name}** role.").ConfigureAwait(false); return; } @@ -173,7 +177,7 @@ namespace NadekoBot.Modules.Administration var sameRoles = guildUser.Roles.Where(r => roles.Any(rm => rm.RoleId == r.Id)); if (sameRoles.Any()) { - await channel.SendMessageAsync($"โŽ You already have **{sameRoles.FirstOrDefault().Name}** `exclusive self-assigned` role.").ConfigureAwait(false); + await channel.SendErrorAsync($"You already have **{sameRoles.FirstOrDefault().Name}** `exclusive self-assigned` role.").ConfigureAwait(false); return; } } @@ -183,11 +187,11 @@ namespace NadekoBot.Modules.Administration } catch (Exception ex) { - await channel.SendMessageAsync($"โš ๏ธ I am unable to add that role to you. `I can't add roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false); + await channel.SendErrorAsync($"โš ๏ธ I am unable to add that role to you. `I can't add roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false); Console.WriteLine(ex); return; } - var msg = await channel.SendMessageAsync($"๐Ÿ†— You now have **{role.Name}** role.").ConfigureAwait(false); + var msg = await channel.SendConfirmAsync($"๐Ÿ†— You now have **{role.Name}** role.").ConfigureAwait(false); if (conf.AutoDeleteSelfAssignedRoleMessages) { @@ -217,12 +221,12 @@ namespace NadekoBot.Modules.Administration SelfAssignedRole roleModel; if ((roleModel = roles.FirstOrDefault(r => r.RoleId == role.Id)) == null) { - await channel.SendMessageAsync("๐Ÿ’ข That role is not self-assignable.").ConfigureAwait(false); + await channel.SendErrorAsync("๐Ÿ’ข That role is not self-assignable.").ConfigureAwait(false); return; } if (!guildUser.Roles.Contains(role)) { - await channel.SendMessageAsync($"โŽ You don't have **{role.Name}** role.").ConfigureAwait(false); + await channel.SendErrorAsync($"โŽ You don't have **{role.Name}** role.").ConfigureAwait(false); return; } try @@ -231,10 +235,10 @@ namespace NadekoBot.Modules.Administration } catch (Exception) { - await channel.SendMessageAsync($"โš ๏ธ I am unable to add that role to you. `I can't remove roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false); + await channel.SendErrorAsync($"โš ๏ธ I am unable to add that role to you. `I can't remove roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false); return; } - var msg = await channel.SendMessageAsync($"๐Ÿ†— You no longer have **{role.Name}** role.").ConfigureAwait(false); + var msg = await channel.SendConfirmAsync($"๐Ÿ†— You no longer have **{role.Name}** role.").ConfigureAwait(false); if (autoDeleteSelfAssignedRoleMessages) { diff --git a/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs index d153a2dd..b750a26c 100644 --- a/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs @@ -1,6 +1,7 @@ ๏ปฟusing Discord; using Discord.Commands; using NadekoBot.Attributes; +using NadekoBot.Extensions; using System.Linq; using System.Threading.Tasks; @@ -31,18 +32,18 @@ namespace NadekoBot.Modules.Administration if (server == null) { - await channel.SendMessageAsync("โš ๏ธ Cannot find that server").ConfigureAwait(false); + await channel.SendErrorAsync("โš ๏ธ Cannot find that server").ConfigureAwait(false); return; } if (server.OwnerId != _client.GetCurrentUser().Id) { await server.LeaveAsync().ConfigureAwait(false); - await channel.SendMessageAsync("โœ… Left server " + server.Name).ConfigureAwait(false); + await channel.SendConfirmAsync("โœ… Left server " + server.Name).ConfigureAwait(false); } else { await server.DeleteAsync().ConfigureAwait(false); - await channel.SendMessageAsync("Deleted server " + server.Name).ConfigureAwait(false); + await channel.SendConfirmAsync("Deleted server " + server.Name).ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommands.cs b/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommands.cs index 94d0589b..1a42e613 100644 --- a/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommands.cs @@ -112,7 +112,7 @@ namespace NadekoBot.Modules.Administration var msg = conf.DmGreetMessageText.Replace("%user%", user.Username).Replace("%server%", user.Guild.Name); if (!string.IsNullOrWhiteSpace(msg)) { - await channel.SendMessageAsync(msg).ConfigureAwait(false); + await channel.SendConfirmAsync(msg).ConfigureAwait(false); } } } @@ -134,9 +134,9 @@ namespace NadekoBot.Modules.Administration await ServerGreetCommands.SetGreetDel(channel.Guild.Id, timer).ConfigureAwait(false); if (timer > 0) - await channel.SendMessageAsync($"๐Ÿ†— Greet messages **will be deleted** after `{timer} seconds`.").ConfigureAwait(false); + await channel.SendConfirmAsync($"๐Ÿ†— Greet messages **will be deleted** after `{timer} seconds`.").ConfigureAwait(false); else - await channel.SendMessageAsync("โ„น๏ธ Automatic deletion of greet messages has been **disabled**.").ConfigureAwait(false); + await channel.SendConfirmAsync("โ„น๏ธ Automatic deletion of greet messages has been **disabled**.").ConfigureAwait(false); } private static async Task SetGreetDel(ulong id, int timer) @@ -163,9 +163,9 @@ namespace NadekoBot.Modules.Administration var enabled = await ServerGreetCommands.SetGreet(channel.Guild.Id, channel.Id).ConfigureAwait(false); if (enabled) - await channel.SendMessageAsync("โœ… Greeting messages **enabled** on this channel.").ConfigureAwait(false); + await channel.SendConfirmAsync("โœ… Greeting messages **enabled** on this channel.").ConfigureAwait(false); else - await channel.SendMessageAsync("โ„น๏ธ Greeting messages **disabled**.").ConfigureAwait(false); + await channel.SendConfirmAsync("โ„น๏ธ Greeting messages **disabled**.").ConfigureAwait(false); } private static async Task SetGreet(ulong guildId, ulong channelId, bool? value = null) @@ -196,15 +196,15 @@ namespace NadekoBot.Modules.Administration { channelGreetMessageText = uow.GuildConfigs.For(channel.Guild.Id, set => set).ChannelGreetMessageText; } - await channel.SendMessageAsync("โ„น๏ธ Current **greet** message: `" + channelGreetMessageText?.SanitizeMentions() + "`"); + await channel.SendConfirmAsync("Current greet message: ", channelGreetMessageText?.SanitizeMentions()); return; } var sendGreetEnabled = ServerGreetCommands.SetGreetMessage(channel.Guild.Id, ref text); - await channel.SendMessageAsync("๐Ÿ†— New greet message **set**.").ConfigureAwait(false); + await channel.SendConfirmAsync("๐Ÿ†— New greet message **set**.").ConfigureAwait(false); if (!sendGreetEnabled) - await channel.SendMessageAsync("โ„น๏ธ Enable greet messsages by typing `.greet`").ConfigureAwait(false); + await channel.SendConfirmAsync("โ„น๏ธ Enable greet messsages by typing `.greet`").ConfigureAwait(false); } public static bool SetGreetMessage(ulong guildId, ref string message) @@ -236,9 +236,9 @@ namespace NadekoBot.Modules.Administration var enabled = await ServerGreetCommands.SetGreetDm(channel.Guild.Id).ConfigureAwait(false); if (enabled) - await channel.SendMessageAsync("๐Ÿ†— DM Greet announcements **enabled**.").ConfigureAwait(false); + await channel.SendConfirmAsync("๐Ÿ†— DM Greet announcements **enabled**.").ConfigureAwait(false); else - await channel.SendMessageAsync("โ„น๏ธ Greet announcements **disabled**.").ConfigureAwait(false); + await channel.SendConfirmAsync("โ„น๏ธ Greet announcements **disabled**.").ConfigureAwait(false); } private static async Task SetGreetDm(ulong guildId, bool? value = null) @@ -268,15 +268,15 @@ namespace NadekoBot.Modules.Administration { config = uow.GuildConfigs.For(channel.Guild.Id); } - await channel.SendMessageAsync("โ„น๏ธ Current **DM greet** message: `" + config.DmGreetMessageText?.SanitizeMentions() + "`"); + await channel.SendConfirmAsync("โ„น๏ธ Current **DM greet** message: `" + config.DmGreetMessageText?.SanitizeMentions() + "`"); return; } var sendGreetEnabled = ServerGreetCommands.SetGreetDmMessage(channel.Guild.Id, ref text); - await channel.SendMessageAsync("๐Ÿ†— New DM greet message **set**.").ConfigureAwait(false); + await channel.SendConfirmAsync("๐Ÿ†— New DM greet message **set**.").ConfigureAwait(false); if (!sendGreetEnabled) - await channel.SendMessageAsync($"โ„น๏ธ Enable DM greet messsages by typing `{NadekoBot.ModulePrefixes[typeof(Administration).Name]}greetdm`").ConfigureAwait(false); + await channel.SendConfirmAsync($"โ„น๏ธ Enable DM greet messsages by typing `{NadekoBot.ModulePrefixes[typeof(Administration).Name]}greetdm`").ConfigureAwait(false); } public static bool SetGreetDmMessage(ulong guildId, ref string message) @@ -308,9 +308,9 @@ namespace NadekoBot.Modules.Administration var enabled = await ServerGreetCommands.SetBye(channel.Guild.Id, channel.Id).ConfigureAwait(false); if (enabled) - await channel.SendMessageAsync("โœ… Bye announcements **enabled** on this channel.").ConfigureAwait(false); + await channel.SendConfirmAsync("โœ… Bye announcements **enabled** on this channel.").ConfigureAwait(false); else - await channel.SendMessageAsync("โ„น๏ธ Bye announcements **disabled**.").ConfigureAwait(false); + await channel.SendConfirmAsync("โ„น๏ธ Bye announcements **disabled**.").ConfigureAwait(false); } private static async Task SetBye(ulong guildId, ulong channelId, bool? value = null) @@ -341,15 +341,15 @@ namespace NadekoBot.Modules.Administration { byeMessageText = uow.GuildConfigs.For(channel.Guild.Id, set => set).ChannelByeMessageText; } - await channel.SendMessageAsync("โ„น๏ธ Current **bye** message: `" + byeMessageText?.SanitizeMentions() + "`"); + await channel.SendConfirmAsync("โ„น๏ธ Current **bye** message: `" + byeMessageText?.SanitizeMentions() + "`"); return; } var sendByeEnabled = ServerGreetCommands.SetByeMessage(channel.Guild.Id, ref text); - await channel.SendMessageAsync("๐Ÿ†— New bye message **set**.").ConfigureAwait(false); + await channel.SendConfirmAsync("๐Ÿ†— New bye message **set**.").ConfigureAwait(false); if (!sendByeEnabled) - await channel.SendMessageAsync($"โ„น๏ธ Enable bye messsages by typing `{NadekoBot.ModulePrefixes[typeof(Administration).Name]}bye`").ConfigureAwait(false); + await channel.SendConfirmAsync($"โ„น๏ธ Enable bye messsages by typing `{NadekoBot.ModulePrefixes[typeof(Administration).Name]}bye`").ConfigureAwait(false); } public static bool SetByeMessage(ulong guildId, ref string message) @@ -381,9 +381,9 @@ namespace NadekoBot.Modules.Administration await ServerGreetCommands.SetByeDel(channel.Guild.Id, timer).ConfigureAwait(false); if (timer > 0) - await channel.SendMessageAsync($"๐Ÿ†— Bye messages **will be deleted** after `{timer} seconds`.").ConfigureAwait(false); + await channel.SendConfirmAsync($"๐Ÿ†— Bye messages **will be deleted** after `{timer} seconds`.").ConfigureAwait(false); else - await channel.SendMessageAsync("โ„น๏ธ Automatic deletion of bye messages has been **disabled**.").ConfigureAwait(false); + await channel.SendConfirmAsync("โ„น๏ธ Automatic deletion of bye messages has been **disabled**.").ConfigureAwait(false); } private static async Task SetByeDel(ulong id, int timer) diff --git a/src/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommands.cs b/src/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommands.cs index a6ca255f..4ffff33a 100644 --- a/src/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommands.cs @@ -51,7 +51,7 @@ namespace NadekoBot.Modules.Administration { try { - await (await guild.GetOwnerAsync()).SendMessageAsync( + await (await guild.GetOwnerAsync()).SendErrorAsync( "โš ๏ธ I don't have **manage server** and/or **manage channels** permission," + $" so I cannot run `voice+text` on **{guild.Name}** server.").ConfigureAwait(false); } @@ -116,7 +116,7 @@ namespace NadekoBot.Modules.Administration var botUser = await guild.GetCurrentUserAsync().ConfigureAwait(false); if (!botUser.GuildPermissions.ManageRoles || !botUser.GuildPermissions.ManageChannels) { - await channel.SendMessageAsync("๐Ÿ’ข I require atleast **manage roles** and **manage channels permissions** to enable this feature. `(preffered Administration permission)`"); + await channel.SendErrorAsync("I require atleast **manage roles** and **manage channels permissions** to enable this feature. `(preffered Administration permission)`"); return; } @@ -124,7 +124,7 @@ namespace NadekoBot.Modules.Administration { try { - await channel.SendMessageAsync("โš ๏ธ You are enabling this feature and **I do not have ADMINISTRATOR permissions**. " + + await channel.SendErrorAsync("โš ๏ธ You are enabling this feature and **I do not have ADMINISTRATOR permissions**. " + "`This may cause some issues, and you will have to clean up text channels yourself afterwards.`"); } catch { } @@ -145,16 +145,16 @@ namespace NadekoBot.Modules.Administration { try { await textChannel.DeleteAsync().ConfigureAwait(false); } catch { } } - await channel.SendMessageAsync("โ„น๏ธ Successfuly **removed** voice + text feature.").ConfigureAwait(false); + await channel.SendConfirmAsync("โ„น๏ธ Successfuly **removed** voice + text feature.").ConfigureAwait(false); return; } voicePlusTextCache.Add(guild.Id); - await channel.SendMessageAsync("๐Ÿ†— Successfuly **enabled** voice + text feature.").ConfigureAwait(false); + await channel.SendConfirmAsync("๐Ÿ†— Successfuly **enabled** voice + text feature.").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendMessageAsync(ex.ToString()).ConfigureAwait(false); + await channel.SendErrorAsync(ex.ToString()).ConfigureAwait(false); } } [NadekoCommand, Usage, Description, Aliases] @@ -168,7 +168,7 @@ namespace NadekoBot.Modules.Administration var botUser = await guild.GetCurrentUserAsync().ConfigureAwait(false); if (!botUser.GuildPermissions.Administrator) { - await channel.SendMessageAsync("โš ๏ธ I need **Administrator permission** to do that.").ConfigureAwait(false); + await channel.SendErrorAsync("I need **Administrator permission** to do that.").ConfigureAwait(false); return; } @@ -183,7 +183,7 @@ namespace NadekoBot.Modules.Administration await Task.Delay(500); } - await channel.SendMessageAsync("โœ… Done.").ConfigureAwait(false); + await channel.SendConfirmAsync("Cleaned v+t.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/ClashOfClans/ClashOfClans.cs b/src/NadekoBot/Modules/ClashOfClans/ClashOfClans.cs index 4a61127a..81be7144 100644 --- a/src/NadekoBot/Modules/ClashOfClans/ClashOfClans.cs +++ b/src/NadekoBot/Modules/ClashOfClans/ClashOfClans.cs @@ -10,6 +10,7 @@ using NadekoBot.Attributes; using Discord.WebSocket; using NadekoBot.Services.Database.Models; using System.Linq; +using NadekoBot.Extensions; namespace NadekoBot.Modules.ClashOfClans { @@ -49,7 +50,7 @@ namespace NadekoBot.Modules.ClashOfClans if (!Bases[i].BaseDestroyed && DateTime.UtcNow - Bases[i].TimeAdded >= callExpire) { Bases[i] = null; - try { await war.Channel.SendMessageAsync($"โ—๐Ÿ”ฐ**Claim from @{Bases[i].CallUser} for a war against {war.ShortPrint()} has expired.**").ConfigureAwait(false); } catch { } + try { await war.Channel.SendErrorAsync($"โ—๐Ÿ”ฐ**Claim from @{Bases[i].CallUser} for a war against {war.ShortPrint()} has expired.**").ConfigureAwait(false); } catch { } } } } @@ -68,7 +69,7 @@ namespace NadekoBot.Modules.ClashOfClans if (size < 10 || size > 50 || size % 5 != 0) { - await channel.SendMessageAsync("๐Ÿ’ข๐Ÿ”ฐ Not a Valid war size").ConfigureAwait(false); + await channel.SendErrorAsync("๐Ÿ”ฐ Not a Valid war size").ConfigureAwait(false); return; } List wars; @@ -83,7 +84,7 @@ namespace NadekoBot.Modules.ClashOfClans var cw = await CreateWar(enemyClan, size, channel.Guild.Id, umsg.Channel.Id); wars.Add(cw); - await channel.SendMessageAsync($"โ—๐Ÿ”ฐ**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**").ConfigureAwait(false); + await channel.SendConfirmAsync($"โ—๐Ÿ”ฐ**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -98,18 +99,18 @@ namespace NadekoBot.Modules.ClashOfClans var warsInfo = GetWarInfo(umsg, num); if (warsInfo == null) { - await channel.SendMessageAsync("๐Ÿ’ข๐Ÿ”ฐ **That war does not exist.**").ConfigureAwait(false); + await channel.SendErrorAsync("๐Ÿ”ฐ **That war does not exist.**").ConfigureAwait(false); return; } var war = warsInfo.Item1[warsInfo.Item2]; try { war.Start(); - await channel.SendMessageAsync($"๐Ÿ”ฐ**STARTED WAR AGAINST {war.ShortPrint()}**").ConfigureAwait(false); + await channel.SendConfirmAsync($"๐Ÿ”ฐ**STARTED WAR AGAINST {war.ShortPrint()}**").ConfigureAwait(false); } catch { - await channel.SendMessageAsync($"๐Ÿ”ฐ**WAR AGAINST {war.ShortPrint()} HAS ALREADY STARTED**").ConfigureAwait(false); + await channel.SendErrorAsync($"๐Ÿ”ฐ**WAR AGAINST {war.ShortPrint()} HAS ALREADY STARTED**").ConfigureAwait(false); } SaveWar(war); } @@ -128,7 +129,7 @@ namespace NadekoBot.Modules.ClashOfClans ClashWars.TryGetValue(channel.Guild.Id, out wars); if (wars == null || wars.Count == 0) { - await channel.SendMessageAsync("๐Ÿ”ฐ **No active wars.**").ConfigureAwait(false); + await channel.SendErrorAsync("๐Ÿ”ฐ **No active wars.**").ConfigureAwait(false); return; } @@ -141,7 +142,7 @@ namespace NadekoBot.Modules.ClashOfClans sb.AppendLine($"\t\t`Size:` **{wars[i].Size} v {wars[i].Size}**"); sb.AppendLine("**-------------------------**"); } - await channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false); + await channel.SendConfirmAsync(sb.ToString()).ConfigureAwait(false); return; } @@ -151,10 +152,10 @@ namespace NadekoBot.Modules.ClashOfClans var warsInfo = GetWarInfo(umsg, num); if (warsInfo == null) { - await channel.SendMessageAsync("๐Ÿ’ข๐Ÿ”ฐ **That war does not exist.**").ConfigureAwait(false); + await channel.SendErrorAsync("๐Ÿ”ฐ **That war does not exist.**").ConfigureAwait(false); return; } - await channel.SendMessageAsync(warsInfo.Item1[warsInfo.Item2].ToPrettyString()).ConfigureAwait(false); + await channel.SendConfirmAsync(warsInfo.Item1[warsInfo.Item2].ToPrettyString()).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -165,7 +166,7 @@ namespace NadekoBot.Modules.ClashOfClans var warsInfo = GetWarInfo(umsg, number); if (warsInfo == null || warsInfo.Item1.Count == 0) { - await channel.SendMessageAsync("๐Ÿ’ข๐Ÿ”ฐ **That war does not exist.**").ConfigureAwait(false); + await channel.SendErrorAsync("๐Ÿ”ฐ **That war does not exist.**").ConfigureAwait(false); return; } var usr = @@ -177,11 +178,11 @@ namespace NadekoBot.Modules.ClashOfClans var war = warsInfo.Item1[warsInfo.Item2]; war.Call(usr, baseNumber - 1); SaveWar(war); - await channel.SendMessageAsync($"๐Ÿ”ฐ**{usr}** claimed a base #{baseNumber} for a war against {war.ShortPrint()}").ConfigureAwait(false); + await channel.SendConfirmAsync($"๐Ÿ”ฐ**{usr}** claimed a base #{baseNumber} for a war against {war.ShortPrint()}").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendMessageAsync($"๐Ÿ’ข๐Ÿ”ฐ {ex.Message}").ConfigureAwait(false); + await channel.SendErrorAsync($"๐Ÿ”ฐ {ex.Message}").ConfigureAwait(false); } } @@ -218,13 +219,13 @@ namespace NadekoBot.Modules.ClashOfClans var warsInfo = GetWarInfo(umsg,number); if (warsInfo == null) { - await channel.SendMessageAsync("๐Ÿ’ข๐Ÿ”ฐ That war does not exist.").ConfigureAwait(false); + await channel.SendErrorAsync("๐Ÿ”ฐ That war does not exist.").ConfigureAwait(false); return; } var war = warsInfo.Item1[warsInfo.Item2]; war.End(); SaveWar(war); - await channel.SendMessageAsync($"โ—๐Ÿ”ฐ**War against {warsInfo.Item1[warsInfo.Item2].ShortPrint()} ended.**").ConfigureAwait(false); + await channel.SendConfirmAsync($"โ—๐Ÿ”ฐ**War against {warsInfo.Item1[warsInfo.Item2].ShortPrint()} ended.**").ConfigureAwait(false); var size = warsInfo.Item1[warsInfo.Item2].Size; warsInfo.Item1.RemoveAt(warsInfo.Item2); @@ -239,7 +240,7 @@ namespace NadekoBot.Modules.ClashOfClans var warsInfo = GetWarInfo(umsg, number); if (warsInfo == null || warsInfo.Item1.Count == 0) { - await channel.SendMessageAsync("๐Ÿ’ข๐Ÿ”ฐ **That war does not exist.**").ConfigureAwait(false); + await channel.SendErrorAsync("๐Ÿ”ฐ **That war does not exist.**").ConfigureAwait(false); return; } var usr = @@ -251,11 +252,11 @@ namespace NadekoBot.Modules.ClashOfClans var war = warsInfo.Item1[warsInfo.Item2]; var baseNumber = war.Uncall(usr); SaveWar(war); - await channel.SendMessageAsync($"๐Ÿ”ฐ @{usr} has **UNCLAIMED** a base #{baseNumber + 1} from a war against {war.ShortPrint()}").ConfigureAwait(false); + await channel.SendConfirmAsync($"๐Ÿ”ฐ @{usr} has **UNCLAIMED** a base #{baseNumber + 1} from a war against {war.ShortPrint()}").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendMessageAsync($"๐Ÿ’ข๐Ÿ”ฐ {ex.Message}").ConfigureAwait(false); + await channel.SendErrorAsync($"๐Ÿ”ฐ {ex.Message}").ConfigureAwait(false); } } @@ -265,7 +266,7 @@ namespace NadekoBot.Modules.ClashOfClans var warInfo = GetWarInfo(umsg, number); if (warInfo == null || warInfo.Item1.Count == 0) { - await channel.SendMessageAsync("๐Ÿ’ข๐Ÿ”ฐ **That war does not exist.**").ConfigureAwait(false); + await channel.SendErrorAsync("๐Ÿ”ฐ **That war does not exist.**").ConfigureAwait(false); return; } var war = warInfo.Item1[warInfo.Item2]; @@ -280,11 +281,11 @@ namespace NadekoBot.Modules.ClashOfClans { war.FinishClaim(baseNumber, stars); } - await channel.SendMessageAsync($"โ—๐Ÿ”ฐ{umsg.Author.Mention} **DESTROYED** a base #{baseNumber + 1} in a war against {war.ShortPrint()}").ConfigureAwait(false); + await channel.SendConfirmAsync($"โ—๐Ÿ”ฐ{umsg.Author.Mention} **DESTROYED** a base #{baseNumber + 1} in a war against {war.ShortPrint()}").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendMessageAsync($"๐Ÿ’ข๐Ÿ”ฐ {ex.Message}").ConfigureAwait(false); + await channel.SendErrorAsync($"๐Ÿ”ฐ {ex.Message}").ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs b/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs index 7dfa0cb5..b7241f12 100644 --- a/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs +++ b/src/NadekoBot/Modules/CustomReactions/CustomReactions.cs @@ -47,7 +47,8 @@ namespace NadekoBot.Modules.CustomReactions }).Shuffle().FirstOrDefault(); if (reaction != null) { - try { await channel.SendMessageAsync(reaction.ResponseWithContext(umsg)).ConfigureAwait(false); } catch { } + if(reaction.Response != "-") + try { await channel.SendMessageAsync(reaction.ResponseWithContext(umsg)).ConfigureAwait(false); } catch { } return true; } } @@ -77,7 +78,7 @@ namespace NadekoBot.Modules.CustomReactions if ((channel == null && !NadekoBot.Credentials.IsOwner(imsg.Author)) || (channel != null && !((IGuildUser)imsg.Author).GuildPermissions.Administrator)) { - try { await imsg.Channel.SendMessageAsync("Insufficient permissions. Requires Bot ownership for global custom reactions, and Administrator for guild custom reactions."); } catch { } + try { await imsg.Channel.SendErrorAsync("Insufficient permissions. Requires Bot ownership for global custom reactions, and Administrator for guild custom reactions."); } catch { } return; } @@ -106,7 +107,12 @@ namespace NadekoBot.Modules.CustomReactions reactions.Add(cr); } - await imsg.Channel.SendMessageAsync($"`Added new custom reaction {cr.Id}:`\n\t`Trigger:` {key}\n\t`Response:` {message}").ConfigureAwait(false); + await imsg.Channel.EmbedAsync(new EmbedBuilder().WithColor(NadekoBot.OkColor) + .WithTitle("New Custom Reaction") + .WithDescription($"#{cr.Id}") + .AddField(efb => efb.WithName("Trigger").WithValue(key)) + .AddField(efb => efb.WithName("Response").WithValue(message)) + .Build()).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -124,16 +130,15 @@ namespace NadekoBot.Modules.CustomReactions customReactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet()); if (customReactions == null || !customReactions.Any()) - await imsg.Channel.SendMessageAsync("`No custom reactions found`").ConfigureAwait(false); + await imsg.Channel.SendErrorAsync("No custom reactions found").ConfigureAwait(false); else - await imsg.Channel.SendMessageAsync( - $"`Page {page} of custom reactions:`\n" + - string.Join("\n", customReactions - .OrderBy(cr => cr.Trigger) - .Skip((page - 1) * 20) - .Take(20) - .Select(cr => $"`#{cr.Id}` `Trigger:` {cr.Trigger}"))) - .ConfigureAwait(false); + await imsg.Channel.SendConfirmAsync( + $"Page {page} of custom reactions:", + string.Join("\n", customReactions.OrderBy(cr => cr.Trigger) + .Skip((page - 1) * 20) + .Take(20) + .Select(cr => $"`#{cr.Id}` `Trigger:` {cr.Trigger}"))) + .ConfigureAwait(false); } public enum All @@ -154,7 +159,7 @@ namespace NadekoBot.Modules.CustomReactions customReactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet()); if (customReactions == null || !customReactions.Any()) - await imsg.Channel.SendMessageAsync("`No custom reactions found`").ConfigureAwait(false); + await imsg.Channel.SendErrorAsync("No custom reactions found").ConfigureAwait(false); else { var txtStream = await customReactions.GroupBy(cr => cr.Trigger) @@ -183,9 +188,9 @@ namespace NadekoBot.Modules.CustomReactions customReactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet()); if (customReactions == null || !customReactions.Any()) - await imsg.Channel.SendMessageAsync("`No custom reactions found`").ConfigureAwait(false); + await imsg.Channel.SendErrorAsync("No custom reactions found").ConfigureAwait(false); else - await imsg.Channel.SendMessageAsync($"{imsg.Author.Mention}\n`Page {page} of custom reactions (grouped):`\n" + + await imsg.Channel.SendConfirmAsync($"Page {page} of custom reactions (grouped):", string.Join("\r\n", customReactions .GroupBy(cr=>cr.Trigger) .OrderBy(cr => cr.Key) @@ -209,11 +214,14 @@ namespace NadekoBot.Modules.CustomReactions var found = customReactions.FirstOrDefault(cr => cr.Id == id); if (found == null) - await imsg.Channel.SendMessageAsync("`No custom reaction found with that id.`").ConfigureAwait(false); + await imsg.Channel.SendErrorAsync("No custom reaction found with that id.").ConfigureAwait(false); else { - await imsg.Channel.SendMessageAsync($"`Custom reaction #{id}`\n`Trigger:` {found.Trigger}\n`Response:` {found.Response} ```css\n{found.Response}```") - .ConfigureAwait(false); + await imsg.Channel.EmbedAsync(new EmbedBuilder().WithColor(NadekoBot.OkColor) + .WithDescription($"#{id}") + .AddField(efb => efb.WithName("Trigger").WithValue(found.Trigger)) + .AddField(efb => efb.WithName("Response").WithValue(found.Response + "\n```css\n" + found.Response + "```" )) + .Build()).ConfigureAwait(false); } } @@ -224,7 +232,7 @@ namespace NadekoBot.Modules.CustomReactions if ((channel == null && !NadekoBot.Credentials.IsOwner(imsg.Author)) || (channel != null && !((IGuildUser)imsg.Author).GuildPermissions.Administrator)) { - try { await imsg.Channel.SendMessageAsync("Insufficient permissions. Requires Bot ownership for global custom reactions, and Administrator for guild custom reactions."); } catch { } + try { await imsg.Channel.SendErrorAsync("Insufficient permissions. Requires Bot ownership for global custom reactions, and Administrator for guild custom reactions."); } catch { } return; } @@ -253,9 +261,9 @@ namespace NadekoBot.Modules.CustomReactions } if (success) - await imsg.Channel.SendMessageAsync("**Successfully deleted custom reaction** " + toDelete.ToString()).ConfigureAwait(false); + await imsg.Channel.SendConfirmAsync("Deleted custom reaction", toDelete.ToString()).ConfigureAwait(false); else - await imsg.Channel.SendMessageAsync("`Failed to find that custom reaction.`").ConfigureAwait(false); + await imsg.Channel.SendErrorAsync("Failed to find that custom reaction.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs b/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs index 9dc5de5b..d462d572 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs @@ -29,7 +29,7 @@ namespace NadekoBot.Modules.Gambling var ar = new AnimalRace(channel.Guild.Id, channel); if (ar.Fail) - await channel.SendMessageAsync("๐Ÿ `Failed starting a race. Another race is probably running.`"); + await channel.SendErrorAsync("๐Ÿ `Failed starting a race. Another race is probably running.`"); } [NadekoCommand, Usage, Description, Aliases] @@ -45,7 +45,7 @@ namespace NadekoBot.Modules.Gambling AnimalRace ar; if (!AnimalRaces.TryGetValue(channel.Guild.Id, out ar)) { - await channel.SendMessageAsync("No race exists on this server"); + await channel.SendErrorAsync("No race exists on this server"); return; } await ar.JoinRace(umsg.Author as IGuildUser, amount); @@ -90,21 +90,21 @@ namespace NadekoBot.Modules.Gambling { try { - try { await raceChannel.SendMessageAsync($"๐Ÿ`Race is starting in 20 seconds or when the room is full. Type {NadekoBot.ModulePrefixes[typeof(Gambling).Name]}jr to join the race.`"); } catch (Exception ex) { _log.Warn(ex); } + try { await raceChannel.SendConfirmAsync($"๐Ÿ`Race is starting in 20 seconds or when the room is full. Type {NadekoBot.ModulePrefixes[typeof(Gambling).Name]}jr to join the race.`"); } catch (Exception ex) { _log.Warn(ex); } var t = await Task.WhenAny(Task.Delay(20000, token), fullgame); Started = true; cancelSource.Cancel(); if (t == fullgame) { - try { await raceChannel.SendMessageAsync("๐Ÿ`Race full, starting right now!`"); } catch (Exception ex) { _log.Warn(ex); } + try { await raceChannel.SendConfirmAsync("๐Ÿ`Race full, starting right now!`"); } catch (Exception ex) { _log.Warn(ex); } } else if (participants.Count > 1) { - try { await raceChannel.SendMessageAsync("๐Ÿ`Game starting with " + participants.Count + " participants.`"); } catch (Exception ex) { _log.Warn(ex); } + try { await raceChannel.SendConfirmAsync("๐Ÿ`Game starting with " + participants.Count + " participants.`"); } catch (Exception ex) { _log.Warn(ex); } } else { - try { await raceChannel.SendMessageAsync("๐Ÿ`Race failed to start since there was not enough participants.`"); } catch (Exception ex) { _log.Warn(ex); } + try { await raceChannel.SendErrorAsync("๐Ÿ`Race failed to start since there was not enough participants.`"); } catch (Exception ex) { _log.Warn(ex); } var p = participants.FirstOrDefault(); if (p != null && p.AmountBet > 0) @@ -185,11 +185,11 @@ namespace NadekoBot.Modules.Gambling var wonAmount = winner.AmountBet * (participants.Count - 1); await CurrencyHandler.AddCurrencyAsync(winner.User, "Won a Race", wonAmount, false).ConfigureAwait(false); - await raceChannel.SendMessageAsync($"๐Ÿ {winner.User.Mention} as {winner.Animal} **Won the race and {wonAmount}{CurrencySign}!**").ConfigureAwait(false); + await raceChannel.SendConfirmAsync($"๐Ÿ {winner.User.Mention} as {winner.Animal} **Won the race and {wonAmount}{CurrencySign}!**").ConfigureAwait(false); } else { - await raceChannel.SendMessageAsync($"๐Ÿ {winner.User.Mention} as {winner.Animal} **Won the race!**"); + await raceChannel.SendConfirmAsync($"๐Ÿ {winner.User.Mention} as {winner.Animal} **Won the race!**"); } } @@ -218,28 +218,28 @@ namespace NadekoBot.Modules.Gambling var animal = ""; if (!animals.TryDequeue(out animal)) { - await raceChannel.SendMessageAsync($"{u.Mention} `There is no running race on this server.`"); + await raceChannel.SendErrorAsync($"{u.Mention} `There is no running race on this server.`"); return; } var p = new Participant(u, animal, amount); if (participants.Contains(p)) { - await raceChannel.SendMessageAsync($"{u.Mention} `You already joined this race.`"); + await raceChannel.SendErrorAsync($"{u.Mention} `You already joined this race.`"); return; } if (Started) { - await raceChannel.SendMessageAsync($"{u.Mention} `Race is already started`"); + await raceChannel.SendErrorAsync($"{u.Mention} `Race is already started`"); return; } if (amount > 0) if (!await CurrencyHandler.RemoveCurrencyAsync((IGuildUser)u, "BetRace", amount, true).ConfigureAwait(false)) { - try { await raceChannel.SendMessageAsync($"{u.Mention} You don't have enough {Gambling.CurrencyName}s.").ConfigureAwait(false); } catch { } + try { await raceChannel.SendErrorAsync($"{u.Mention} You don't have enough {Gambling.CurrencyName}s.").ConfigureAwait(false); } catch { } return; } participants.Add(p); - await raceChannel.SendMessageAsync($"{u.Mention} **joined the race as a {p.Animal}" + (amount > 0 ? $" and bet {amount} {CurrencySign}!**" : "**")); + await raceChannel.SendConfirmAsync($"{u.Mention} **joined the race as a {p.Animal}" + (amount > 0 ? $" and bet {amount} {CurrencySign}!**" : "**")); } } diff --git a/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs index dc075964..22d58035 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs @@ -78,7 +78,7 @@ namespace NadekoBot.Modules.Gambling arr[i] = rng.Next(1, n2 + 1) + add - sub; } var elemCnt = 0; - await channel.SendMessageAsync($"{umsg.Author.Mention} rolled {n1} {(n1 == 1 ? "die" : "dice")} `1 to {n2}` +`{add}` -`{sub}`.\n`Result:` " + string.Join(", ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => elemCnt++ % 2 == 0 ? $"**{x}**" : x.ToString()))).ConfigureAwait(false); + await channel.SendConfirmAsync($"{umsg.Author.Mention} rolled {n1} {(n1 == 1 ? "die" : "dice")} `1 to {n2}` +`{add}` -`{sub}`.\n`Result:` " + string.Join(", ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => elemCnt++ % 2 == 0 ? $"**{x}**" : x.ToString()))).ConfigureAwait(false); } } } @@ -96,7 +96,7 @@ namespace NadekoBot.Modules.Gambling if (num < 1 || num > 30) { - await channel.SendMessageAsync("Invalid number specified. You can roll up to 1-30 dice at a time.").ConfigureAwait(false); + await channel.SendErrorAsync("Invalid number specified. You can roll up to 1-30 dice at a time.").ConfigureAwait(false); return; } @@ -167,7 +167,7 @@ namespace NadekoBot.Modules.Gambling arr[i] = rng.Next(1, n2 + 1) + add - sub; } var elemCnt = 0; - await channel.SendMessageAsync($"{umsg.Author.Mention} rolled {n1} {(n1 == 1 ? "die" : "dice")} `1 to {n2}` +`{add}` -`{sub}`.\n`Result:` " + string.Join(", ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => elemCnt++ % 2 == 0 ? $"**{x}**" : x.ToString()))).ConfigureAwait(false); + await channel.SendConfirmAsync($"{umsg.Author.Mention} rolled {n1} {(n1 == 1 ? "die" : "dice")} `1 to {n2}` +`{add}` -`{sub}`.\n`Result:` " + string.Join(", ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => elemCnt++ % 2 == 0 ? $"**{x}**" : x.ToString()))).ConfigureAwait(false); } } } @@ -184,7 +184,7 @@ namespace NadekoBot.Modules.Gambling if (num < 1 || num > 30) { - await channel.SendMessageAsync("Invalid number specified. You can roll up to 1-30 dice at a time.").ConfigureAwait(false); + await channel.SendErrorAsync("Invalid number specified. You can roll up to 1-30 dice at a time.").ConfigureAwait(false); return; } @@ -249,11 +249,11 @@ namespace NadekoBot.Modules.Gambling rolled = new NadekoRandom().Next(0, int.Parse(range) + 1); } - await channel.SendMessageAsync($"{umsg.Author.Mention} rolled **{rolled}**.").ConfigureAwait(false); + await channel.SendConfirmAsync($"{umsg.Author.Mention} rolled **{rolled}**.").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendMessageAsync($":anger: {ex.Message}").ConfigureAwait(false); + await channel.SendErrorAsync($":anger: {ex.Message}").ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/Gambling/Commands/DrawCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/DrawCommand.cs index eca29d75..58785882 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/DrawCommand.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/DrawCommand.cs @@ -42,7 +42,7 @@ namespace NadekoBot.Modules.Gambling { if (cards.CardPool.Count == 0 && i != 0) { - try { await channel.SendMessageAsync("No more cards in a deck.").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } + try { await channel.SendErrorAsync("No more cards in a deck.").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } break; } var currentCard = cards.DrawACard(); @@ -75,7 +75,7 @@ namespace NadekoBot.Modules.Gambling return c; }); - await channel.SendMessageAsync("`Deck reshuffled.`").ConfigureAwait(false); + await channel.SendConfirmAsync("Deck reshuffled.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs index e5e84e11..7cbc089a 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs @@ -34,7 +34,7 @@ namespace NadekoBot.Modules.Gambling } if (count > 10 || count < 1) { - await channel.SendMessageAsync("`Invalid number specified. You can flip 1 to 10 coins.`"); + await channel.SendErrorAsync("`Invalid number specified. You can flip 1 to 10 coins.`"); return; } var imgs = new Image[count]; @@ -59,7 +59,7 @@ namespace NadekoBot.Modules.Gambling if (amount < 3) { - await channel.SendMessageAsync($"You can't bet less than 3{Gambling.CurrencySign}.") + await channel.SendErrorAsync($"You can't bet less than 3{Gambling.CurrencySign}.") .ConfigureAwait(false); return; } @@ -72,7 +72,7 @@ namespace NadekoBot.Modules.Gambling if (userFlowers < amount) { - await channel.SendMessageAsync($"{umsg.Author.Mention} You don't have enough {Gambling.CurrencyPluralName}. You only have {userFlowers}{Gambling.CurrencySign}.").ConfigureAwait(false); + await channel.SendErrorAsync($"{umsg.Author.Mention} You don't have enough {Gambling.CurrencyPluralName}. You only have {userFlowers}{Gambling.CurrencySign}.").ConfigureAwait(false); return; } diff --git a/src/NadekoBot/Modules/Gambling/Gambling.cs b/src/NadekoBot/Modules/Gambling/Gambling.cs index 3dc865ca..cc4e123b 100644 --- a/src/NadekoBot/Modules/Gambling/Gambling.cs +++ b/src/NadekoBot/Modules/Gambling/Gambling.cs @@ -51,7 +51,7 @@ namespace NadekoBot.Modules.Gambling var members = role.Members().Where(u => u.Status != UserStatus.Offline && u.Status != UserStatus.Unknown); var membersArray = members as IUser[] ?? members.ToArray(); var usr = membersArray[new NadekoRandom().Next(0, membersArray.Length)]; - await channel.SendMessageAsync($"๐ŸŽŸ Raffled user: **{usr.Username}#{usr.Discriminator}** ID: `{usr.Id}`").ConfigureAwait(false); + await channel.SendConfirmAsync("๐ŸŽŸ Raffled user", $"**{usr.Username}#{usr.Discriminator}** ID: `{usr.Id}`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -62,7 +62,7 @@ namespace NadekoBot.Modules.Gambling user = user ?? umsg.Author; - await channel.SendMessageAsync($"{user.Username} has {GetCurrency(user.Id)} {CurrencySign}").ConfigureAwait(false); + await channel.SendConfirmAsync($"{user.Username} has {GetCurrency(user.Id)} {CurrencySign}").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -71,7 +71,7 @@ namespace NadekoBot.Modules.Gambling { var channel = umsg.Channel; - await channel.SendMessageAsync($"`{userId}` has {GetCurrency(userId)} {CurrencySign}").ConfigureAwait(false); + await channel.SendConfirmAsync($"`{userId}` has {GetCurrency(userId)} {CurrencySign}").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -84,11 +84,11 @@ namespace NadekoBot.Modules.Gambling var success = await CurrencyHandler.RemoveCurrencyAsync((IGuildUser)umsg.Author, $"Gift to {receiver.Username} ({receiver.Id}).", amount, true).ConfigureAwait(false); if (!success) { - await channel.SendMessageAsync($"{umsg.Author.Mention} You don't have enough {Gambling.CurrencyPluralName}.").ConfigureAwait(false); + await channel.SendErrorAsync($"{umsg.Author.Mention} You don't have enough {Gambling.CurrencyPluralName}.").ConfigureAwait(false); return; } await CurrencyHandler.AddCurrencyAsync(receiver, $"Gift from {umsg.Author.Username} ({umsg.Author.Id}).", amount, true).ConfigureAwait(false); - await channel.SendMessageAsync($"{umsg.Author.Mention} successfully sent {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} to {receiver.Mention}!").ConfigureAwait(false); + await channel.SendConfirmAsync($"{umsg.Author.Mention} successfully sent {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} to {receiver.Mention}!").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -111,7 +111,7 @@ namespace NadekoBot.Modules.Gambling await CurrencyHandler.AddCurrencyAsync(usrId, $"Awarded by bot owner. ({umsg.Author.Username}/{umsg.Author.Id})", amount).ConfigureAwait(false); - await channel.SendMessageAsync($"{umsg.Author.Mention} successfully awarded {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} to <@{usrId}>!").ConfigureAwait(false); + await channel.SendConfirmAsync($"{umsg.Author.Mention} successfully awarded {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} to <@{usrId}>!").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -129,7 +129,7 @@ namespace NadekoBot.Modules.Gambling amount))) .ConfigureAwait(false); - await channel.SendMessageAsync($"Awarded `{amount}` {Gambling.CurrencyPluralName} to `{users.Count}` users from `{role.Name}` role.") + await channel.SendConfirmAsync($"Awarded `{amount}` {Gambling.CurrencyPluralName} to `{users.Count}` users from `{role.Name}` role.") .ConfigureAwait(false); } @@ -144,9 +144,9 @@ namespace NadekoBot.Modules.Gambling return; if(await CurrencyHandler.RemoveCurrencyAsync(user, $"Taken by bot owner.({umsg.Author.Username}/{umsg.Author.Id})", amount, true).ConfigureAwait(false)) - await channel.SendMessageAsync($"{umsg.Author.Mention} successfully took {amount} {(amount == 1? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from {user}!").ConfigureAwait(false); + await channel.SendConfirmAsync($"{umsg.Author.Mention} successfully took {amount} {(amount == 1? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from {user}!").ConfigureAwait(false); else - await channel.SendMessageAsync($"{umsg.Author.Mention} was unable to take {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from {user} because the user doesn't have that much {Gambling.CurrencyPluralName}!").ConfigureAwait(false); + await channel.SendErrorAsync($"{umsg.Author.Mention} was unable to take {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from {user} because the user doesn't have that much {Gambling.CurrencyPluralName}!").ConfigureAwait(false); } @@ -160,9 +160,9 @@ namespace NadekoBot.Modules.Gambling return; if(await CurrencyHandler.RemoveCurrencyAsync(usrId, $"Taken by bot owner.({umsg.Author.Username}/{umsg.Author.Id})", amount).ConfigureAwait(false)) - await channel.SendMessageAsync($"{umsg.Author.Mention} successfully took {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from <@{usrId}>!").ConfigureAwait(false); + await channel.SendConfirmAsync($"{umsg.Author.Mention} successfully took {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from <@{usrId}>!").ConfigureAwait(false); else - await channel.SendMessageAsync($"{umsg.Author.Mention} was unable to take {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from `{usrId}` because the user doesn't have that much {Gambling.CurrencyPluralName}!").ConfigureAwait(false); + await channel.SendErrorAsync($"{umsg.Author.Mention} was unable to take {amount} {(amount == 1 ? Gambling.CurrencyName : Gambling.CurrencyPluralName)} from `{usrId}` because the user doesn't have that much {Gambling.CurrencyPluralName}!").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -184,7 +184,7 @@ namespace NadekoBot.Modules.Gambling if (userFlowers < amount) { - await channel.SendMessageAsync($"{guildUser.Mention} You don't have enough {Gambling.CurrencyPluralName}. You only have {userFlowers}{Gambling.CurrencySign}.").ConfigureAwait(false); + await channel.SendErrorAsync($"{guildUser.Mention} You don't have enough {Gambling.CurrencyPluralName}. You only have {userFlowers}{Gambling.CurrencySign}.").ConfigureAwait(false); return; } @@ -212,7 +212,7 @@ namespace NadekoBot.Modules.Gambling await CurrencyHandler.AddCurrencyAsync(guildUser, "Betroll Gamble", amount * 10, false).ConfigureAwait(false); } - await channel.SendMessageAsync(str).ConfigureAwait(false); + await channel.SendConfirmAsync(str).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] diff --git a/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs b/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs index 39c95425..f3b148cd 100644 --- a/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/CleverBotCommands.cs @@ -1,6 +1,7 @@ ๏ปฟusing Discord; using Discord.Commands; using NadekoBot.Attributes; +using NadekoBot.Extensions; using NadekoBot.Services; using NLog; using Services.CleverBotApi; @@ -72,12 +73,11 @@ namespace NadekoBot.Modules.Games var response = await cleverbot.Think(message).ConfigureAwait(false); try { - await msg.Channel.SendMessageAsync(response).ConfigureAwait(false); + await msg.Channel.SendConfirmAsync(response.SanitizeMentions()).ConfigureAwait(false); } - catch (Exception ex) + catch { - _log.Warn(ex, "Eror sending response"); - await msg.Channel.SendMessageAsync(msg.Author.Mention+" "+response).ConfigureAwait(false); // try twice :\ + await msg.Channel.SendConfirmAsync(response.SanitizeMentions()).ConfigureAwait(false); // try twice :\ } return true; } @@ -97,7 +97,7 @@ namespace NadekoBot.Modules.Games uow.GuildConfigs.SetCleverbotEnabled(channel.Guild.Id, false); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"{imsg.Author.Mention} `Disabled cleverbot on this server.`").ConfigureAwait(false); + await channel.SendConfirmAsync($"{imsg.Author.Mention} Disabled cleverbot on this server.").ConfigureAwait(false); return; } @@ -112,7 +112,7 @@ namespace NadekoBot.Modules.Games await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"{imsg.Author.Mention} `Enabled cleverbot on this server.`").ConfigureAwait(false); + await channel.SendConfirmAsync($"{imsg.Author.Mention} Enabled cleverbot on this server.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Games/Commands/LeetCommands.cs b/src/NadekoBot/Modules/Games/Commands/LeetCommands.cs index 1a7657b4..f877ebe7 100644 --- a/src/NadekoBot/Modules/Games/Commands/LeetCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/LeetCommands.cs @@ -21,7 +21,7 @@ namespace NadekoBot.Modules.Games text = text.Trim(); if (string.IsNullOrWhiteSpace(text)) return; - await channel.SendMessageAsync(ToLeet(text, level)).ConfigureAwait(false); + await channel.SendConfirmAsync("L33t", ToLeet(text, level).SanitizeMentions()).ConfigureAwait(false); } diff --git a/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs b/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs index 3a0ef80c..61a9a10d 100644 --- a/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs @@ -105,7 +105,7 @@ namespace NadekoBot.Modules.Games if (!channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages) { - await channel.SendMessageAsync("`I need manage channel permissions in order to process this command.`").ConfigureAwait(false); + await channel.SendErrorAsync("I need manage channel permissions in order to process this command.").ConfigureAwait(false); return; } @@ -118,7 +118,7 @@ namespace NadekoBot.Modules.Games await Task.WhenAll(msgs.Select(toDelete => toDelete.DeleteAsync())).ConfigureAwait(false); await CurrencyHandler.AddCurrencyAsync((IGuildUser)imsg.Author, "Picked flower(s).", msgs.Count, false).ConfigureAwait(false); - var msg = await channel.SendMessageAsync($"**{imsg.Author.Username}** picked {msgs.Count}{Gambling.Gambling.CurrencySign}!").ConfigureAwait(false); + var msg = await channel.SendConfirmAsync($"**{imsg.Author}** picked {msgs.Count}{Gambling.Gambling.CurrencySign}!").ConfigureAwait(false); var t = Task.Run(async () => { await Task.Delay(10000).ConfigureAwait(false); @@ -135,7 +135,7 @@ namespace NadekoBot.Modules.Games var removed = await CurrencyHandler.RemoveCurrencyAsync((IGuildUser)imsg.Author, "Planted a flower.", 1, false).ConfigureAwait(false); if (!removed) { - await channel.SendMessageAsync($"You don't have any {Gambling.Gambling.CurrencyPluralName}.").ConfigureAwait(false); + await channel.SendErrorAsync($"You don't have any {Gambling.Gambling.CurrencyPluralName}.").ConfigureAwait(false); return; } @@ -146,7 +146,7 @@ namespace NadekoBot.Modules.Games var msgToSend = $"Oh how Nice! **{imsg.Author.Username}** planted {(vowelFirst ? "an" : "a")} {Gambling.Gambling.CurrencyName}. Pick it using {NadekoBot.ModulePrefixes[typeof(Games).Name]}pick"; if (file == null) { - msg = await channel.SendMessageAsync(Gambling.Gambling.CurrencySign).ConfigureAwait(false); + msg = await channel.SendConfirmAsync(Gambling.Gambling.CurrencySign).ConfigureAwait(false); } else { @@ -184,11 +184,11 @@ namespace NadekoBot.Modules.Games } if (enabled) { - await channel.SendMessageAsync("`Currency generation enabled on this channel.`").ConfigureAwait(false); + await channel.SendConfirmAsync("Currency generation enabled on this channel.").ConfigureAwait(false); } else { - await channel.SendMessageAsync($"`Currency generation disabled on this channel.`").ConfigureAwait(false); + await channel.SendConfirmAsync("Currency generation disabled on this channel.").ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/Games/Commands/PollCommands.cs b/src/NadekoBot/Modules/Games/Commands/PollCommands.cs index 66c72f02..840abdf1 100644 --- a/src/NadekoBot/Modules/Games/Commands/PollCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/PollCommands.cs @@ -1,6 +1,7 @@ ๏ปฟusing Discord; using Discord.Commands; using NadekoBot.Attributes; +using NadekoBot.Extensions; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -44,7 +45,7 @@ namespace NadekoBot.Modules.Games await poll.StartPoll().ConfigureAwait(false); } else - await channel.SendMessageAsync("`Poll is already running on this server.`").ConfigureAwait(false); + await channel.SendErrorAsync("Poll is already running on this server.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -91,7 +92,7 @@ namespace NadekoBot.Modules.Games msgToSend += "\n**Private Message me with the corresponding number of the answer.**"; else msgToSend += "\n**Send a Message here with the corresponding number of the answer.**"; - await originalMessage.Channel.SendMessageAsync(msgToSend).ConfigureAwait(false); + await originalMessage.Channel.SendConfirmAsync(msgToSend).ConfigureAwait(false); } public async Task StopPoll() @@ -115,7 +116,7 @@ namespace NadekoBot.Modules.Games $" has {kvp.Value} votes." + $"({kvp.Value * 1.0f / totalVotesCast * 100}%)\n"); - await originalMessage.Channel.SendMessageAsync($"๐Ÿ“„ **Total votes cast**: {totalVotesCast}\n{closeMessage}").ConfigureAwait(false); + await originalMessage.Channel.SendConfirmAsync($"๐Ÿ“„ **Total votes cast**: {totalVotesCast}\n{closeMessage}").ConfigureAwait(false); } catch (Exception ex) { @@ -166,11 +167,11 @@ namespace NadekoBot.Modules.Games { if (!isPublic) { - await ch.SendMessageAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false); + await ch.SendConfirmAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false); } else { - var toDelete = await ch.SendMessageAsync($"{msg.Author.Mention} cast their vote.").ConfigureAwait(false); + var toDelete = await ch.SendConfirmAsync($"{msg.Author.Mention} cast their vote.").ConfigureAwait(false); await Task.Delay(5000); await toDelete.DeleteAsync().ConfigureAwait(false); } diff --git a/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs b/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs index 74f67dcd..8ea17e2c 100644 --- a/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs @@ -21,9 +21,9 @@ namespace NadekoBot.Modules.Games public class TypingGame { public const float WORD_VALUE = 4.5f; - private readonly ITextChannel channel; - public string CurrentSentence; - public bool IsActive; + public ITextChannel Channel { get; } + public string CurrentSentence { get; private set; } + public bool IsActive { get; private set; } private readonly Stopwatch sw; private readonly List finishedUserIds; private Logger _log { get; } @@ -31,14 +31,12 @@ namespace NadekoBot.Modules.Games public TypingGame(ITextChannel channel) { _log = LogManager.GetCurrentClassLogger(); - this.channel = channel; + this.Channel = channel; IsActive = false; sw = new Stopwatch(); finishedUserIds = new List(); } - public ITextChannel Channel { get; set; } - public async Task Stop() { if (!IsActive) return false; @@ -47,7 +45,7 @@ namespace NadekoBot.Modules.Games IsActive = false; sw.Stop(); sw.Reset(); - try { await channel.SendMessageAsync("Typing contest stopped").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } + try { await Channel.SendConfirmAsync("Typing contest stopped.").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } return true; } @@ -59,10 +57,10 @@ namespace NadekoBot.Modules.Games var i = (int)(CurrentSentence.Length / WORD_VALUE * 1.7f); try { - await channel.SendMessageAsync($@":clock2: Next contest will last for {i} seconds. Type the bolded text as fast as you can.").ConfigureAwait(false); + await Channel.SendConfirmAsync($@":clock2: Next contest will last for {i} seconds. Type the bolded text as fast as you can.").ConfigureAwait(false); - var msg = await channel.SendMessageAsync("Starting new typing contest in **3**...").ConfigureAwait(false); + var msg = await Channel.SendMessageAsync("Starting new typing contest in **3**...").ConfigureAwait(false); await Task.Delay(1000).ConfigureAwait(false); try { @@ -118,7 +116,7 @@ namespace NadekoBot.Modules.Games { try { - if (channel == null || channel.Id != channel.Id) return; + if (this.Channel == null || this.Channel.Id != this.Channel.Id) return; var guess = msg.Content; @@ -126,11 +124,17 @@ namespace NadekoBot.Modules.Games var decision = Judge(distance, guess.Length); if (decision && !finishedUserIds.Contains(msg.Author.Id)) { + var wpm = CurrentSentence.Length / WORD_VALUE / sw.Elapsed.Seconds * 60; finishedUserIds.Add(msg.Author.Id); - await channel.SendMessageAsync($"{msg.Author.Mention} finished in **{sw.Elapsed.Seconds}** seconds with { distance } errors, **{ CurrentSentence.Length / WORD_VALUE / sw.Elapsed.Seconds * 60 }** WPM!").ConfigureAwait(false); + await Extensions.Extensions.EmbedAsync(this.Channel, (Discord.API.Embed)new EmbedBuilder().WithColor((uint)NadekoBot.OkColor) + .WithTitle((string)$"{msg.Author} finished the race!") + .AddField(efb => efb.WithName("Place").WithValue($"#{finishedUserIds.Count}").WithIsInline(true)) + .AddField(efb => efb.WithName("WPM").WithValue($"{wpm:F2} *[{sw.Elapsed.Seconds.ToString()}sec]*").WithIsInline(true)) + .AddField(efb => efb.WithName((string)"Errors").WithValue((string)distance.ToString()).WithIsInline((bool)true)) + .Build()).ConfigureAwait(false); if (finishedUserIds.Count % 4 == 0) { - await channel.SendMessageAsync($":exclamation: `A lot of people finished, here is the text for those still typing:`\n\n**{Format.Sanitize(CurrentSentence.Replace(" ", " \x200B")).SanitizeMentions()}**").ConfigureAwait(false); + await Extensions.Extensions.SendConfirmAsync(this.Channel, (string)$":exclamation: A lot of people finished, here is the text for those still typing:\n\n**{Format.Sanitize((string)CurrentSentence.Replace((string)" ", (string)" \x200B")).SanitizeMentions()}**").ConfigureAwait(false); } } } @@ -172,7 +176,7 @@ namespace NadekoBot.Modules.Games if (game.IsActive) { - await channel.SendMessageAsync( + await channel.SendErrorAsync( $"Contest already running in " + $"{game.Channel.Mention} channel.") .ConfigureAwait(false); @@ -194,17 +198,17 @@ namespace NadekoBot.Modules.Games await game.Stop().ConfigureAwait(false); return; } - await channel.SendMessageAsync("No contest to stop on this channel.").ConfigureAwait(false); + await channel.SendErrorAsync("No contest to stop on this channel.").ConfigureAwait(false); } - + [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [OwnerOnly] public async Task Typeadd(IUserMessage imsg, [Remainder] string text) { var channel = (ITextChannel)imsg.Channel; - + TypingArticles.Add(new TypingArticle { Title = $"Text added on {DateTime.UtcNow} by {imsg.Author}", @@ -213,7 +217,7 @@ namespace NadekoBot.Modules.Games File.WriteAllText(typingArticlesPath, JsonConvert.SerializeObject(TypingArticles)); - await channel.SendMessageAsync("Added new article for typing game.").ConfigureAwait(false); + await channel.SendConfirmAsync("Added new article for typing game.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -229,11 +233,11 @@ namespace NadekoBot.Modules.Games if (!articles.Any()) { - await channel.SendMessageAsync($"{imsg.Author.Mention} `No articles found on that page.`").ConfigureAwait(false); + await channel.SendErrorAsync($"{imsg.Author.Mention} `No articles found on that page.`").ConfigureAwait(false); return; } var i = (page - 1) * 15; - await channel.SendMessageAsync(String.Join("\n", articles.Select(a => $"`#{++i}` - {a.Text.TrimTo(50)}"))) + await channel.SendConfirmAsync("List of articles for Type Race", String.Join("\n", articles.Select(a => $"`#{++i}` - {a.Text.TrimTo(50)}"))) .ConfigureAwait(false); } @@ -253,7 +257,7 @@ namespace NadekoBot.Modules.Games File.WriteAllText(typingArticlesPath, JsonConvert.SerializeObject(TypingArticles)); - await channel.SendMessageAsync($"`Removed typing article:` #{index + 1} - {removed.Text.TrimTo(50)}") + await channel.SendConfirmAsync($"`Removed typing article:` #{index + 1} - {removed.Text.TrimTo(50)}") .ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs b/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs index a52b8122..534c5040 100644 --- a/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs +++ b/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs @@ -56,13 +56,13 @@ namespace NadekoBot.Modules.Games.Trivia CurrentQuestion = TriviaQuestionPool.Instance.GetRandomQuestion(oldQuestions); if (CurrentQuestion == null) { - try { await channel.SendMessageAsync($":exclamation: Failed loading a trivia question").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } + try { await channel.SendErrorAsync($":exclamation: Failed loading a trivia question.").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } await End().ConfigureAwait(false); return; } oldQuestions.Add(CurrentQuestion); //add it to exclusion list so it doesn't show up again //sendquestion - try { await channel.SendMessageAsync($":question: **{CurrentQuestion.Question}**").ConfigureAwait(false); } + try { await channel.SendConfirmAsync($":question: Question",$"**{CurrentQuestion.Question}**").ConfigureAwait(false); } catch (HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound || ex.StatusCode == System.Net.HttpStatusCode.Forbidden) { break; @@ -80,7 +80,7 @@ namespace NadekoBot.Modules.Games.Trivia //hint await Task.Delay(HintTimeoutMiliseconds, token).ConfigureAwait(false); if (ShowHints) - try { await channel.SendMessageAsync($":exclamation:**Hint:** {CurrentQuestion.GetHint()}").ConfigureAwait(false); } + try { await channel.SendConfirmAsync($":exclamation: Hint", CurrentQuestion.GetHint()).ConfigureAwait(false); } catch (HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound || ex.StatusCode == System.Net.HttpStatusCode.Forbidden) { break; @@ -94,7 +94,7 @@ namespace NadekoBot.Modules.Games.Trivia catch (TaskCanceledException) { } //means someone guessed the answer GameActive = false; if (!triviaCancelSource.IsCancellationRequested) - try { await channel.SendMessageAsync($":clock2: :question: **Time's up!** The correct answer was **{CurrentQuestion.Answer}**").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } + try { await channel.SendConfirmAsync($":clock2: :question: **Time's up!** The correct answer was **{CurrentQuestion.Answer}**").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } NadekoBot.Client.MessageReceived -= PotentialGuess; // load next question if game is still running await Task.Delay(2000).ConfigureAwait(false); @@ -104,18 +104,25 @@ namespace NadekoBot.Modules.Games.Trivia await End().ConfigureAwait(false); } - private async Task End() + public async Task End() { ShouldStopGame = true; TriviaGame throwaway; Games.TriviaCommands.RunningTrivias.TryRemove(channel.Guild.Id, out throwaway); - try { await channel.SendMessageAsync("**Trivia game ended**\n" + GetLeaderboard()).ConfigureAwait(false); } catch { } + try + { + await channel.EmbedAsync(new EmbedBuilder().WithColor(NadekoBot.OkColor) + .WithTitle("Leaderboard") + .WithDescription(GetLeaderboard()) + .Build(), "Trivia game ended.").ConfigureAwait(false); + } + catch { } } public async Task StopGame() { if (!ShouldStopGame) - try { await channel.SendMessageAsync(":exclamation: Trivia will stop after this question.").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } + try { await channel.SendConfirmAsync(":exclamation: Trivia will stop after this question.").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } ShouldStopGame = true; } @@ -149,10 +156,10 @@ namespace NadekoBot.Modules.Games.Trivia finally { _guessLock.Release(); } if (!guess) return; triviaCancelSource.Cancel(); - try { await channel.SendMessageAsync($"โ˜‘๏ธ {guildUser.Mention} guessed it! The answer was: **{CurrentQuestion.Answer}**").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } + try { await channel.SendConfirmAsync($"โ˜‘๏ธ {guildUser.Mention} guessed it! The answer was: **{CurrentQuestion.Answer}**").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } if (Users[guildUser] != WinRequirement) return; ShouldStopGame = true; - await channel.SendMessageAsync($":exclamation: We have a winner! It's {guildUser.Mention}.").ConfigureAwait(false); + await channel.SendConfirmAsync($":exclamation: We have a winner! It's {guildUser.Mention}.").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); } }); @@ -165,7 +172,6 @@ namespace NadekoBot.Modules.Games.Trivia return ""; var sb = new StringBuilder(); - sb.Append("**Leaderboard:**\n-----------\n"); foreach (var kvp in Users.OrderByDescending(kvp => kvp.Value)) { diff --git a/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs b/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs index 56fd3fc1..25051444 100644 --- a/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs @@ -1,6 +1,7 @@ ๏ปฟusing Discord; using Discord.Commands; using NadekoBot.Attributes; +using NadekoBot.Extensions; using NadekoBot.Modules.Games.Trivia; using System; using System.Collections.Concurrent; @@ -36,12 +37,12 @@ namespace NadekoBot.Modules.Games return; var triviaGame = new TriviaGame(channel.Guild, (ITextChannel)umsg.Channel, showHints, number == 0 ? 10 : number); if (RunningTrivias.TryAdd(channel.Guild.Id, triviaGame)) - await channel.SendMessageAsync($"**Trivia game started! {triviaGame.WinRequirement} points needed to win.**").ConfigureAwait(false); + await channel.SendConfirmAsync($"**Trivia game started! {triviaGame.WinRequirement} points needed to win.**").ConfigureAwait(false); else await triviaGame.StopGame().ConfigureAwait(false); } else - await channel.SendMessageAsync("Trivia game is already running on this server.\n" + trivia.CurrentQuestion).ConfigureAwait(false); + await channel.SendErrorAsync("Trivia game is already running on this server.\n" + trivia.CurrentQuestion).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -52,9 +53,9 @@ namespace NadekoBot.Modules.Games TriviaGame trivia; if (RunningTrivias.TryGetValue(channel.Guild.Id, out trivia)) - await channel.SendMessageAsync(trivia.GetLeaderboard()).ConfigureAwait(false); + await channel.SendConfirmAsync("Leaderboard", trivia.GetLeaderboard()).ConfigureAwait(false); else - await channel.SendMessageAsync("No trivia is running on this server.").ConfigureAwait(false); + await channel.SendErrorAsync("No trivia is running on this server.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -64,12 +65,12 @@ namespace NadekoBot.Modules.Games var channel = (ITextChannel)umsg.Channel; TriviaGame trivia; - if (RunningTrivias.TryRemove(channel.Guild.Id, out trivia)) + if (RunningTrivias.TryGetValue(channel.Guild.Id, out trivia)) { await trivia.StopGame().ConfigureAwait(false); } else - await channel.SendMessageAsync("No trivia is running on this server.").ConfigureAwait(false); + await channel.SendErrorAsync("No trivia is running on this server.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Games/Games.cs b/src/NadekoBot/Modules/Games/Games.cs index a95a9bd8..592881d1 100644 --- a/src/NadekoBot/Modules/Games/Games.cs +++ b/src/NadekoBot/Modules/Games/Games.cs @@ -36,7 +36,7 @@ namespace NadekoBot.Modules.Games if (listArr.Count() < 2) return; var rng = new NadekoRandom(); - await channel.SendMessageAsync(listArr[rng.Next(0, listArr.Length)]).ConfigureAwait(false); + await channel.SendConfirmAsync("๐Ÿค”", listArr[rng.Next(0, listArr.Length)]).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -48,8 +48,11 @@ namespace NadekoBot.Modules.Games if (string.IsNullOrWhiteSpace(question)) return; var rng = new NadekoRandom(); - await channel.SendMessageAsync($@"โ“ `Question` __**{question}**__ -๐ŸŽฑ `8Ball Answers` __**{_8BallResponses.Shuffle().FirstOrDefault()}**__").ConfigureAwait(false); + + await channel.EmbedAsync(new EmbedBuilder().WithColor(NadekoBot.OkColor) + .AddField(efb => efb.WithName("โ“ Question").WithValue(question).WithIsInline(false)) + .AddField(efb => efb.WithName("๐ŸŽฑ 8Ball").WithValue(_8BallResponses.Shuffle().FirstOrDefault()).WithIsInline(false)) + .Build()); } [NadekoCommand, Usage, Description, Aliases] @@ -99,7 +102,7 @@ namespace NadekoBot.Modules.Games else msg = $"{umsg.Author.Mention} won! {GetRPSPick(pick)} beats {GetRPSPick(nadekoPick)}"; - await channel.SendMessageAsync(msg).ConfigureAwait(false); + await channel.SendConfirmAsync(msg).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -108,7 +111,7 @@ namespace NadekoBot.Modules.Games { var channel = (ITextChannel)umsg.Channel; - await channel.SendMessageAsync( + await channel.SendConfirmAsync( $@"I'd just like to interject for moment. What you're refering to as {loonix}, is in fact, {guhnoo}/{loonix}, or as I've recently taken to calling it, {guhnoo} plus {loonix}. {loonix} is not an operating system unto itself, but rather another free component of a fully functioning {guhnoo} system made useful by the {guhnoo} corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX. Many computer users run a modified version of the {guhnoo} system every day, without realizing it. Through a peculiar turn of events, the version of {guhnoo} which is widely used today is often called {loonix}, and many of its users are not aware that it is basically the {guhnoo} system, developed by the {guhnoo} Project. diff --git a/src/NadekoBot/Modules/Help/Help.cs b/src/NadekoBot/Modules/Help/Help.cs index 80bcc0a0..2b824111 100644 --- a/src/NadekoBot/Modules/Help/Help.cs +++ b/src/NadekoBot/Modules/Help/Help.cs @@ -58,7 +58,7 @@ namespace NadekoBot.Modules.Help var cmdsArray = cmds as Command[] ?? cmds.ToArray(); if (!cmdsArray.Any()) { - await channel.SendMessageAsync("๐Ÿšซ **That module does not exist.**").ConfigureAwait(false); + await channel.SendErrorAsync("That module does not exist.").ConfigureAwait(false); return; } if (module != "customreactions" && module != "conversations") @@ -69,7 +69,7 @@ namespace NadekoBot.Modules.Help { await channel.SendMessageAsync("๐Ÿ“ƒ **List Of Commands:**\nโ€ข " + string.Join("\nโ€ข ", cmdsArray.Select(c => $"{c.Text}"))); } - await channel.SendMessageAsync($"โ„น๏ธ **Type** `\"{NadekoBot.ModulePrefixes[typeof(Help).Name]}h CommandName\"` **to see the help for that specified command.** ***e.g.*** `-h >8ball`").ConfigureAwait(false); + await channel.SendConfirmAsync($"โ„น๏ธ **Type** `\"{NadekoBot.ModulePrefixes[typeof(Help).Name]}h CommandName\"` **to see the help for that specified command.** ***e.g.*** `-h >8ball`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -94,13 +94,12 @@ namespace NadekoBot.Modules.Help var str = $"**`{com.Text}`**"; var alias = com.Aliases.Skip(1).FirstOrDefault(); if (alias != null) - str += $" **/** **`{alias}`**"; + str += $" **/ `{alias}`**"; var embed = new EmbedBuilder() .AddField(fb => fb.WithIndex(1).WithName(str).WithValue($"{ string.Format(com.Summary, com.Module.Prefix)} { GetCommandRequirements(com)}").WithIsInline(true)) .AddField(fb => fb.WithIndex(2).WithName("**Usage**").WithValue($"{string.Format(com.Remarks, com.Module.Prefix)}").WithIsInline(false)) .WithColor(NadekoBot.OkColor); - if (com != null) - await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); } private string GetCommandRequirements(Command cmd) @@ -157,7 +156,7 @@ namespace NadekoBot.Modules.Help { var channel = (ITextChannel)umsg.Channel; - await channel.SendMessageAsync( + await channel.SendConfirmAsync( @"**LIST OF COMMANDS**: **Hosting Guides and docs can be found here**: ").ConfigureAwait(false); } @@ -168,7 +167,7 @@ namespace NadekoBot.Modules.Help { var channel = (ITextChannel)umsg.Channel; - await channel.SendMessageAsync( + await channel.SendConfirmAsync( $@"You can support the NadekoBot project on patreon. or You can send donations to `nadekodiscordbot@gmail.com` Don't forget to leave your discord name or id in the message. diff --git a/src/NadekoBot/Modules/NSFW/NSFW.cs b/src/NadekoBot/Modules/NSFW/NSFW.cs index 0d95ee21..0fba9e0e 100644 --- a/src/NadekoBot/Modules/NSFW/NSFW.cs +++ b/src/NadekoBot/Modules/NSFW/NSFW.cs @@ -51,7 +51,7 @@ namespace NadekoBot.Modules.NSFW } var link = await provider.ConfigureAwait(false); if (string.IsNullOrWhiteSpace(link)) - await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false); + await channel.SendErrorAsync("No results found.").ConfigureAwait(false); else await channel.SendMessageAsync(link).ConfigureAwait(false); } @@ -68,17 +68,17 @@ namespace NadekoBot.Modules.NSFW var links = await Task.WhenAll(GetGelbooruImageLink(tag), GetDanbooruImageLink(tag), GetKonachanImageLink(tag), - GetYandereImageLink(tag)).ConfigureAwait(false); + GetYandereImageLink(tag)).ConfigureAwait(false); if (links.All(l => l == null)) { - await channel.SendMessageAsync("`No results.`").ConfigureAwait(false); + await channel.SendErrorAsync("No results found.").ConfigureAwait(false); return; } await channel.SendMessageAsync(String.Join("\n\n", links)).ConfigureAwait(false); } - + public static async Task GetYandereImageLink(string tag) { var rng = new NadekoRandom(); @@ -97,7 +97,7 @@ namespace NadekoBot.Modules.NSFW return matches[rng.Next(0, matches.Count)].Groups["url"].Value; } } - + [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] public async Task Yandere(IUserMessage umsg, [Remainder] string tag = null) @@ -107,7 +107,7 @@ namespace NadekoBot.Modules.NSFW tag = tag?.Trim() ?? ""; var link = await GetYandereImageLink(tag).ConfigureAwait(false); if (string.IsNullOrWhiteSpace(link)) - await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false); + await channel.SendErrorAsync("No results found.").ConfigureAwait(false); else await channel.SendMessageAsync(link).ConfigureAwait(false); } @@ -121,7 +121,7 @@ namespace NadekoBot.Modules.NSFW tag = tag?.Trim() ?? ""; var link = await GetDanbooruImageLink(tag).ConfigureAwait(false); if (string.IsNullOrWhiteSpace(link)) - await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false); + await channel.SendErrorAsync("No results found.").ConfigureAwait(false); else await channel.SendMessageAsync(link).ConfigureAwait(false); } @@ -135,7 +135,7 @@ namespace NadekoBot.Modules.NSFW tag = tag?.Trim() ?? ""; var link = await GetKonachanImageLink(tag).ConfigureAwait(false); if (string.IsNullOrWhiteSpace(link)) - await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false); + await channel.SendErrorAsync("No results found.").ConfigureAwait(false); else await channel.SendMessageAsync(link).ConfigureAwait(false); } @@ -149,7 +149,7 @@ namespace NadekoBot.Modules.NSFW tag = tag?.Trim() ?? ""; var link = await GetGelbooruImageLink(tag).ConfigureAwait(false); if (string.IsNullOrWhiteSpace(link)) - await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false); + await channel.SendErrorAsync("No results found.").ConfigureAwait(false); else await channel.SendMessageAsync(link).ConfigureAwait(false); } @@ -163,7 +163,7 @@ namespace NadekoBot.Modules.NSFW tag = tag?.Trim() ?? ""; var link = await GetRule34ImageLink(tag).ConfigureAwait(false); if (string.IsNullOrWhiteSpace(link)) - await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false); + await channel.SendErrorAsync("No results found.").ConfigureAwait(false); else await channel.SendMessageAsync(link).ConfigureAwait(false); } @@ -177,7 +177,7 @@ namespace NadekoBot.Modules.NSFW tag = tag?.Trim() ?? ""; var link = await GetE621ImageLink(tag).ConfigureAwait(false); if (string.IsNullOrWhiteSpace(link)) - await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false); + await channel.SendErrorAsync("No results found.").ConfigureAwait(false); else await channel.SendMessageAsync(link).ConfigureAwait(false); } @@ -201,13 +201,13 @@ namespace NadekoBot.Modules.NSFW JToken obj; using (var http = new HttpClient()) { - obj = JArray.Parse(await http.GetStringAsync($"http://api.oboobs.ru/boobs/{ new NadekoRandom().Next(0, 9880) }").ConfigureAwait(false))[0]; + obj = JArray.Parse(await http.GetStringAsync($"http://api.oboobs.ru/boobs/{ new NadekoRandom().Next(0, 10229) }").ConfigureAwait(false))[0]; } await channel.SendMessageAsync($"http://media.oboobs.ru/{ obj["preview"].ToString() }").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendMessageAsync($"๐Ÿ’ข {ex.Message}").ConfigureAwait(false); + await channel.SendErrorAsync(ex.Message).ConfigureAwait(false); } } @@ -222,13 +222,13 @@ namespace NadekoBot.Modules.NSFW JToken obj; using (var http = new HttpClient()) { - obj = JArray.Parse(await http.GetStringAsync($"http://api.obutts.ru/butts/{ new NadekoRandom().Next(0, 3873) }").ConfigureAwait(false))[0]; + obj = JArray.Parse(await http.GetStringAsync($"http://api.obutts.ru/butts/{ new NadekoRandom().Next(0, 4222) }").ConfigureAwait(false))[0]; } await channel.SendMessageAsync($"http://media.obutts.ru/{ obj["preview"].ToString() }").ConfigureAwait(false); } catch (Exception ex) { - await channel.SendMessageAsync($"๐Ÿ’ข {ex.Message}").ConfigureAwait(false); + await channel.SendErrorAsync(ex.Message).ConfigureAwait(false); } } diff --git a/src/NadekoBot/Modules/Permissions/Commands/BlacklistCommands.cs b/src/NadekoBot/Modules/Permissions/Commands/BlacklistCommands.cs index d218b9b0..2d90a2e7 100644 --- a/src/NadekoBot/Modules/Permissions/Commands/BlacklistCommands.cs +++ b/src/NadekoBot/Modules/Permissions/Commands/BlacklistCommands.cs @@ -1,6 +1,7 @@ ๏ปฟusing Discord; using Discord.Commands; using NadekoBot.Attributes; +using NadekoBot.Extensions; using NadekoBot.Modules.Games.Trivia; using NadekoBot.Services; using NadekoBot.Services.Database.Models; @@ -104,7 +105,7 @@ namespace NadekoBot.Modules.Permissions } - await channel.SendMessageAsync(":ok:").ConfigureAwait(false); + await channel.SendConfirmAsync($"Blacklisted a `{type}` with id `{id}`").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Permissions/Commands/CmdCdsCommands.cs b/src/NadekoBot/Modules/Permissions/Commands/CmdCdsCommands.cs index 8ef8f5c4..c18bf8ed 100644 --- a/src/NadekoBot/Modules/Permissions/Commands/CmdCdsCommands.cs +++ b/src/NadekoBot/Modules/Permissions/Commands/CmdCdsCommands.cs @@ -41,7 +41,7 @@ namespace NadekoBot.Modules.Permissions var channel = (ITextChannel)imsg.Channel; if (secs < 0 || secs > 3600) { - await channel.SendMessageAsync("โš ๏ธ Invalid second parameter. (Must be a number between 0 and 3600)").ConfigureAwait(false); + await channel.SendErrorAsync("Invalid second parameter. (Must be a number between 0 and 3600)").ConfigureAwait(false); return; } @@ -68,10 +68,14 @@ namespace NadekoBot.Modules.Permissions { var activeCds = activeCooldowns.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet()); activeCds.RemoveWhere(ac => ac.Command == command.Text.ToLowerInvariant()); - await channel.SendMessageAsync($"๐Ÿšฎ Command **{command}** has no coooldown now and all existing cooldowns have been cleared.").ConfigureAwait(false); + await channel.SendConfirmAsync($"๐Ÿšฎ Command **{command}** has no coooldown now and all existing cooldowns have been cleared.") + .ConfigureAwait(false); } else - await channel.SendMessageAsync($"โœ… Command **{command}** now has a **{secs} {(secs == 1 ? "second" : "seconds")}** cooldown.").ConfigureAwait(false); + { + await channel.SendConfirmAsync($"โœ… Command **{command}** now has a **{secs} {"seconds".SnPl(secs)}** cooldown.") + .ConfigureAwait(false); + } } [NadekoCommand, Usage, Description, Aliases] @@ -82,7 +86,7 @@ namespace NadekoBot.Modules.Permissions var localSet = commandCooldowns.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet()); if (!localSet.Any()) - await channel.SendMessageAsync("โ„น๏ธ `No command cooldowns set.`").ConfigureAwait(false); + await channel.SendConfirmAsync("โ„น๏ธ `No command cooldowns set.`").ConfigureAwait(false); else await channel.SendTableAsync("", localSet.Select(c => c.CommandName + ": " + c.Seconds + " secs"), s => $"{s,-30}", 2).ConfigureAwait(false); } diff --git a/src/NadekoBot/Modules/Permissions/Permissions.cs b/src/NadekoBot/Modules/Permissions/Permissions.cs index 815896f6..d3de046c 100644 --- a/src/NadekoBot/Modules/Permissions/Permissions.cs +++ b/src/NadekoBot/Modules/Permissions/Permissions.cs @@ -7,6 +7,7 @@ using NadekoBot.Services; using Discord; using NadekoBot.Services.Database.Models; using System.Collections.Concurrent; +using NadekoBot.Extensions; namespace NadekoBot.Modules.Permissions { @@ -62,7 +63,7 @@ namespace NadekoBot.Modules.Permissions await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync("โ„น๏ธ I will " + (action.Value ? "now" : "no longer") + " show permission warnings.").ConfigureAwait(false); + await channel.SendConfirmAsync("โ„น๏ธ I will " + (action.Value ? "now" : "no longer") + " show permission warnings.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -75,7 +76,7 @@ namespace NadekoBot.Modules.Permissions var config = uow.GuildConfigs.For(channel.Guild.Id, set => set); if (role == null) { - await channel.SendMessageAsync($"โ„น๏ธ Current permission role is **{config.PermissionRole}**.").ConfigureAwait(false); + await channel.SendConfirmAsync($"โ„น๏ธ Current permission role is **{config.PermissionRole}**.").ConfigureAwait(false); return; } else { @@ -90,7 +91,7 @@ namespace NadekoBot.Modules.Permissions } } - await channel.SendMessageAsync($"โœ… Users now require **{role.Name}** role in order to edit permissions.").ConfigureAwait(false); + await channel.SendConfirmAsync($"Users now require **{role.Name}** role in order to edit permissions.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -109,10 +110,7 @@ namespace NadekoBot.Modules.Permissions toSend = Format.Code($"๐Ÿ“„ Permissions page {page}") + "\n\n" + String.Join("\n", perms.AsEnumerable().Skip((page - 1) * 20).Take(20).Select(p => $"`{(i++)}.` {(p.Next == null ? Format.Bold(p.GetCommand(channel.Guild) + " [uneditable]") : (p.GetCommand(channel.Guild)))}")); } - if (string.IsNullOrWhiteSpace(toSend)) - await channel.SendMessageAsync("โ—๏ธ`No permissions set.`").ConfigureAwait(false); - else - await channel.SendMessageAsync(toSend).ConfigureAwait(false); + await channel.SendMessageAsync(toSend).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -156,11 +154,11 @@ namespace NadekoBot.Modules.Permissions uow2._context.SaveChanges(); } - await channel.SendMessageAsync($"โœ… {imsg.Author.Mention} removed permission **{p.GetCommand(channel.Guild)}** from position #{index + 1}.").ConfigureAwait(false); + await channel.SendConfirmAsync($"โœ… {imsg.Author.Mention} removed permission **{p.GetCommand(channel.Guild)}** from position #{index + 1}.").ConfigureAwait(false); } catch (ArgumentOutOfRangeException) { - await channel.SendMessageAsync("โ—๏ธ`No command on that index found.`").ConfigureAwait(false); + await channel.SendErrorAsync("โ—๏ธ`No command on that index found.`").ConfigureAwait(false); } } @@ -208,13 +206,13 @@ namespace NadekoBot.Modules.Permissions { if (!fromFound) { - await channel.SendMessageAsync($"โ—๏ธ`Can't find permission at index `#{++from}`").ConfigureAwait(false); + await channel.SendErrorAsync($"Can't find permission at index `#{++from}`").ConfigureAwait(false); return; } if (!toFound) { - await channel.SendMessageAsync($"โ—๏ธ`Can't find permission at index `#{++to}`").ConfigureAwait(false); + await channel.SendErrorAsync($"Can't find permission at index `#{++to}`").ConfigureAwait(false); return; } } @@ -264,14 +262,14 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"โœ… `Moved permission:` \"{fromPerm.GetCommand(channel.Guild)}\" `from #{++from} to #{++to}.`").ConfigureAwait(false); + await channel.SendConfirmAsync($"`Moved permission:` \"{fromPerm.GetCommand(channel.Guild)}\" `from #{++from} to #{++to}.`").ConfigureAwait(false); return; } catch (Exception e) when (e is ArgumentOutOfRangeException || e is IndexOutOfRangeException) { } } - await channel.SendMessageAsync("`Invalid index(es) specified.`").ConfigureAwait(false); + await channel.SendErrorAsync("`Invalid index(es) specified.`").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -300,7 +298,7 @@ namespace NadekoBot.Modules.Permissions await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `{command.Text}` command on this server.").ConfigureAwait(false); + await channel.SendConfirmAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `{command.Text}` command on this server.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -328,7 +326,7 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of **`{module.Name}`** module on this server.").ConfigureAwait(false); + await channel.SendConfirmAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of **`{module.Name}`** module on this server.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -356,7 +354,7 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `{command.Text}` command for `{user}` user.").ConfigureAwait(false); + await channel.SendConfirmAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `{command.Text}` command for `{user}` user.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -384,7 +382,7 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `{module.Name}` module for `{user}` user.").ConfigureAwait(false); + await channel.SendConfirmAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `{module.Name}` module for `{user}` user.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -412,7 +410,7 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `{command.Text}` command for `{role}` role.").ConfigureAwait(false); + await channel.SendConfirmAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `{command.Text}` command for `{role}` role.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -440,7 +438,7 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `{module.Name}` module for `{role}` role.").ConfigureAwait(false); + await channel.SendConfirmAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `{module.Name}` module for `{role}` role.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -471,9 +469,9 @@ namespace NadekoBot.Modules.Permissions } } catch (Exception ex) { - Console.WriteLine(ex); + _log.Error(ex); } - await channel.SendMessageAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `{command.Text}` command for `{chnl}` channel.").ConfigureAwait(false); + await channel.SendConfirmAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `{command.Text}` command for `{chnl}` channel.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -501,7 +499,7 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `{module.Name}` module for `{chnl}` channel.").ConfigureAwait(false); + await channel.SendConfirmAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `{module.Name}` module for `{chnl}` channel.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -529,7 +527,7 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `ALL MODULES` for `{chnl}` channel.").ConfigureAwait(false); + await channel.SendConfirmAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `ALL MODULES` for `{chnl}` channel.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -557,7 +555,7 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `ALL MODULES` for `{role}` role.").ConfigureAwait(false); + await channel.SendConfirmAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `ALL MODULES` for `{role}` role.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -585,7 +583,7 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `ALL MODULES` for `{user}` user.").ConfigureAwait(false); + await channel.SendConfirmAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `ALL MODULES` for `{user}` user.").ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -624,7 +622,7 @@ namespace NadekoBot.Modules.Permissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } - await channel.SendMessageAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `ALL MODULES` on this server.").ConfigureAwait(false); + await channel.SendConfirmAsync($"{(action.Value ? "โœ… Allowed" : "๐Ÿ†— Denied")} usage of `ALL MODULES` on this server.").ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Modules/Searches/Commands/Translator.cs b/src/NadekoBot/Modules/Searches/Commands/Translator.cs index 943e152e..31aaf147 100644 --- a/src/NadekoBot/Modules/Searches/Commands/Translator.cs +++ b/src/NadekoBot/Modules/Searches/Commands/Translator.cs @@ -56,7 +56,7 @@ namespace NadekoBot.Modules.Searches .ConfigureAwait(false); if (autoDelete) try { await umsg.DeleteAsync().ConfigureAwait(false); } catch { } - await umsg.Channel.SendMessageAsync($"{umsg.Author.Mention} `:` "+text.Replace("<@ ", "<@").Replace("<@! ", "<@!")).ConfigureAwait(false); + await umsg.Channel.SendConfirmAsync($"{umsg.Author.Mention} `:` "+text.Replace("<@ ", "<@").Replace("<@! ", "<@!")).ConfigureAwait(false); } catch { } @@ -75,8 +75,7 @@ namespace NadekoBot.Modules.Searches { await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); var translation = await TranslateInternal(umsg, langs, text); - await channel.SendConfirmAsync(translation).ConfigureAwait(false); - + await channel.SendConfirmAsync("Translation " + langs, translation).ConfigureAwait(false); } catch { @@ -94,7 +93,7 @@ namespace NadekoBot.Modules.Searches text = text?.Trim(); if (string.IsNullOrWhiteSpace(text)) throw new ArgumentException(); - return await GoogleTranslator.Instance.Translate(text, from, to).ConfigureAwait(false); + return (await GoogleTranslator.Instance.Translate(text, from, to).ConfigureAwait(false)).SanitizeMentions(); } public enum AutoDeleteAutoTranslate diff --git a/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs b/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs index 01ce0937..740b18e0 100644 --- a/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs @@ -14,72 +14,42 @@ namespace NadekoBot.Modules.Utility { [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] - public async Task ServerInfo(IUserMessage msg, string guild = null) + public async Task ServerInfo(IUserMessage msg, string guildName = null) { var channel = (ITextChannel)msg.Channel; - guild = guild?.ToUpperInvariant(); - IGuild server; + guildName = guildName?.ToUpperInvariant(); + IGuild guild; + if (string.IsNullOrWhiteSpace(guildName)) + guild = channel.Guild; + else + guild = NadekoBot.Client.GetGuilds().Where(g => g.Name.ToUpperInvariant() == guildName.ToUpperInvariant()).FirstOrDefault(); if (guild == null) - server = channel.Guild; - else - server = NadekoBot.Client.GetGuilds().Where(g => g.Name.ToUpperInvariant() == guild.ToUpperInvariant()).FirstOrDefault(); - if (server == null) return; - var ownername = $"{await server.GetUserAsync(server.OwnerId)}"; - var textchn = $"{(await server.GetTextChannelsAsync()).Count()}"; - var voicechn = $"{(await server.GetVoiceChannelsAsync()).Count()}"; + var ownername = await guild.GetUserAsync(guild.OwnerId); + var textchn = (await guild.GetTextChannelsAsync()).Count(); + var voicechn = (await guild.GetVoiceChannelsAsync()).Count(); - var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(server.Id >> 22); + var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(guild.Id >> 22); var sb = new StringBuilder(); - var users = await server.GetUsersAsync(); - if (server.Emojis.Count() > 0) + var users = await guild.GetUsersAsync().ConfigureAwait(false); + var embed = new EmbedBuilder() + .WithAuthor(eab => eab.WithName("Server Info")) + .WithTitle(guild.Name) + .AddField(fb => fb.WithName("**ID**").WithValue(guild.Id.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Owner**").WithValue(ownername.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Members**").WithValue(users.Count.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Text Channels**").WithValue(textchn.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Voice Channels**").WithValue(voicechn.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Created At**").WithValue($"{createdAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) + .AddField(fb => fb.WithName("**Region**").WithValue(guild.VoiceRegionId.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Roles**").WithValue(guild.Roles.Count().ToString()).WithIsInline(true)) + .WithImage(tn => tn.WithUrl(guild.IconUrl)) + .WithColor(NadekoBot.OkColor); + if (guild.Emojis.Count() > 0) { - var embed = new EmbedBuilder() - .AddField(fb => fb.WithName("**Name**").WithValue($"**{server.Name}**").WithIsInline(true)) - .AddField(fb => fb.WithName("**ID**").WithValue($"`{server.Id}`").WithIsInline(true)) - .AddField(fb => fb.WithName("**Owner**").WithValue(ownername).WithIsInline(true)) - .AddField(fb => fb.WithName("**Members**").WithValue($"**{users.Count}** - {users.Count(u => u.Status == UserStatus.Online)} ๐Ÿ’š {users.Count(u => u.Status == UserStatus.Idle)} ๐Ÿ”ถ {users.Count(u => u.Status == UserStatus.DoNotDisturb)} ๐Ÿ”ด {users.Count(u=> u.Status == UserStatus.Offline || u.Status == UserStatus.Unknown)} โฌ›๏ธ").WithIsInline(true)) - .AddField(fb => fb.WithName("**Text Channels**").WithValue(textchn).WithIsInline(true)) - .AddField(fb => fb.WithName("**Voice Channels**").WithValue(voicechn).WithIsInline(true)) - .AddField(fb => fb.WithName("**Roles**").WithValue($"{server.Roles.Count()}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Created At**").WithValue($"{createdAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Custom Emojis**").WithValue($"*{string.Join(", ", server.Emojis)}*").WithIsInline(true)) - .WithThumbnail(tn => tn.Url = $"{ server.IconUrl}") - .WithColor(NadekoBot.OkColor); - await msg.Channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + embed.AddField(fb => fb.WithName("**Custom Emojis**").WithValue(Format.Italics(string.Join(", ", guild.Emojis))).WithIsInline(true)); } - else - { - var embed = new EmbedBuilder() - .AddField(fb => fb.WithName("**Name**").WithValue($"**{server.Name}**").WithIsInline(true)) - .AddField(fb => fb.WithName("**ID**").WithValue($"`{server.Id}`").WithIsInline(true)) - .AddField(fb => fb.WithName("**Owner**").WithValue(ownername).WithIsInline(true)) - .AddField(fb => fb.WithName("**Members**").WithValue($"**{users.Count}** - {users.Count(u => u.Status == UserStatus.Online)} ๐Ÿ’š {users.Count(u => u.Status == UserStatus.Idle)} ๐Ÿ”ถ {users.Count(u => u.Status == UserStatus.DoNotDisturb)} ๐Ÿ”ด {users.Count(u=> u.Status == UserStatus.Offline || u.Status == UserStatus.Unknown)} โฌ›๏ธ").WithIsInline(true)) - .AddField(fb => fb.WithName("**Text Channels**").WithValue(textchn).WithIsInline(true)) - .AddField(fb => fb.WithName("**Voice Channels**").WithValue(voicechn).WithIsInline(true)) - .AddField(fb => fb.WithName("**Roles**").WithValue($"{server.Roles.Count()}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Created At**").WithValue($"{createdAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) - .WithThumbnail(tn => tn.Url = $"{ server.IconUrl}") - .WithColor(NadekoBot.OkColor); - await msg.Channel.EmbedAsync(embed.Build()).ConfigureAwait(false); - return; - } - //sb.AppendLine($@"__`Name:`__ **{server.Name}** -//__`Owner:`__ **{await server.GetUserAsync(server.OwnerId)}** -//__`ID:`__ **{server.Id}** -//__`Icon URL:`__ { server.IconUrl} -//__`TextChannels:`__ **{(await server.GetTextChannelsAsync()).Count()}** `VoiceChannels:` **{(await server.GetVoiceChannelsAsync()).Count()}** -//__`Members:`__ **{users.Count}** `-` {users.Count(u => u.Status == UserStatus.Online)}๐Ÿ’š {users.Count(u => u.Status == UserStatus.Idle)}๐Ÿ”ถ {users.Count(u => u.Status == UserStatus.DoNotDisturb)}๐Ÿ”ด {users.Count(u=> u.Status == UserStatus.Offline || u.Status == UserStatus.Unknown)}โฌ›๏ธ -//__`Roles:`__ **{server.Roles.Count()}** -//__`Created At:`__ **{createdAt.ToString("dd.MM.yyyy HH:mm")}** -//"); - //if (server.Emojis.Count() > 0) - //sb.AppendLine($"__`Custom Emojis:`__ *{string.Join(", ", server.Emojis)}*"); - //if (server.Features.Count() > 0) - //sb.AppendLine($"__`Features:`__ **{string.Join(", ", server.Features)}**"); - //if (!string.IsNullOrWhiteSpace(server.SplashUrl)) - //sb.AppendLine($"__`Region:`__ **{server.VoiceRegionId}**"); - //await channel.SendConfirmAsync(sb.ToString()).ConfigureAwait(false); + await msg.Channel.EmbedAsync(embed.Build()).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -91,34 +61,14 @@ namespace NadekoBot.Modules.Utility return; var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(ch.Id >> 22); var usercount = (await ch.GetUsersAsync()).Count(); - if (!string.IsNullOrWhiteSpace(ch.Topic)) - { - var embed = new EmbedBuilder() - .WithDescription($"{ch.Topic}") - .AddField(fb => fb.WithName("**Name**").WithValue($"#{ch.Name}").WithIsInline(false)) - .AddField(fb => fb.WithName("**ID**").WithValue($"`{ch.Id}`").WithIsInline(true)) - .AddField(fb => fb.WithName("**Created At**").WithValue($"{createdAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Users**").WithValue($"{usercount}").WithIsInline(true)) - .WithColor(NadekoBot.OkColor); - await msg.Channel.EmbedAsync(embed.Build()).ConfigureAwait(false); - } - else - { - var embed = new EmbedBuilder() - .AddField(fb => fb.WithName("**Name**").WithValue($"#{ch.Name}").WithIsInline(false)) - .AddField(fb => fb.WithName("**ID**").WithValue($"`{ch.Id}`").WithIsInline(true)) - .AddField(fb => fb.WithName("**Created At**").WithValue($"{createdAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Users**").WithValue($"{usercount}").WithIsInline(true)) - .WithColor(NadekoBot.OkColor); - await msg.Channel.EmbedAsync(embed.Build()).ConfigureAwait(false); - return; - } - //var toReturn = $@"__`Name:`__ **#{ch.Name}** -//__`ID:`__ **{ch.Id}** -//__`Created At:`__ **{createdAt.ToString("dd.MM.yyyy HH:mm")}** -//__`Topic:`__ {ch.Topic} -//__`Users:`__ **{(await ch.GetUsersAsync()).Count()}**"; - //await msg.Channel.SendConfirmAsync(toReturn).ConfigureAwait(false); + var embed = new EmbedBuilder() + .WithTitle(ch.Name) + .WithDescription(ch.Topic?.SanitizeMentions()) + .AddField(fb => fb.WithName("**ID**").WithValue(ch.Id.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Created At**").WithValue($"{createdAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) + .AddField(fb => fb.WithName("**Users**").WithValue(usercount.ToString()).WithIsInline(true)) + .WithColor(NadekoBot.OkColor); + await msg.Channel.EmbedAsync(embed.Build()).ConfigureAwait(false); } [NadekoCommand, Usage, Description, Aliases] @@ -127,53 +77,23 @@ namespace NadekoBot.Modules.Utility { var channel = (ITextChannel)msg.Channel; var user = usr ?? msg.Author as IGuildUser; - //var avurl = await NadekoBot.Google.ShortenUrl(user.AvatarUrl).ConfigureAwait(false); + if (user == null) return; - if (string.IsNullOrWhiteSpace(user.Nickname)) - { - var embed = new EmbedBuilder() - .AddField(fb => fb.WithName("**Name**").WithValue($"**{user.Username}**#{user.Discriminator}").WithIsInline(false)) - .AddField(fb => fb.WithName("**ID**").WithValue($"`{user.Id}`").WithIsInline(true)) - .AddField(fb => fb.WithName("**Joined Server**").WithValue($"{user.JoinedAt?.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Joined Discord**").WithValue($"{user.CreatedAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Current Game**").WithValue($"{(user.Game?.Name == null ? "-" : user.Game.Name)}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Roles**").WithValue($"**({user.Roles.Count()})** - {string.Join(", ", user.Roles.Select(r => r.Name)).SanitizeMentions()}").WithIsInline(false)) - //.AddField(fb => fb.WithName("**Avatar URL**").WithValue(avurl).WithIsInline(true)) - .WithThumbnail(tn => tn.Url = $"{user.AvatarUrl}") - .WithColor(NadekoBot.OkColor); - await msg.Channel.EmbedAsync(embed.Build()).ConfigureAwait(false); + + var embed = new EmbedBuilder() + .AddField(fb => fb.WithName("**Name**").WithValue($"**{user.Username}**#{user.Discriminator}").WithIsInline(true)); + if (!string.IsNullOrWhiteSpace(user.Nickname)) { + embed.AddField(fb => fb.WithName("**Nickname**").WithValue(user.Nickname).WithIsInline(true)); } - else - { - var embed = new EmbedBuilder() - .AddField(fb => fb.WithName("**Name**").WithValue($"**{user.Username}**#{user.Discriminator}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Nickname**").WithValue($"{user.Nickname}").WithIsInline(true)) - .AddField(fb => fb.WithName("**ID**").WithValue($"`{user.Id}`").WithIsInline(true)) - .AddField(fb => fb.WithName("**Joined Server**").WithValue($"{user.JoinedAt?.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Joined Discord**").WithValue($"{user.CreatedAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Current Game**").WithValue($"{(user.Game?.Name == null ? "-" : user.Game.Name)}").WithIsInline(true)) - .AddField(fb => fb.WithName("**Roles**").WithValue($"**({user.Roles.Count()})** - {string.Join(", ", user.Roles.Select(r => r.Name)).SanitizeMentions()}").WithIsInline(false)) - //.AddField(fb => fb.WithName("**Avatar URL**").WithValue(avurl).WithIsInline(true)) - .WithThumbnail(tn => tn.Url = $"{user.AvatarUrl}") - .WithColor(NadekoBot.OkColor); - await msg.Channel.EmbedAsync(embed.Build()).ConfigureAwait(false); - return; - } - ////RIP OLD ONE - // - //var toReturn = $"๐Ÿ‘ค __`Name:`__ **{user.Username}#{user.Discriminator}**\n"; - //if (!string.IsNullOrWhiteSpace(user.Nickname)) - //toReturn += $"๐Ÿ†• __`Nickname:`__ **{user.Nickname}** "; - //toReturn += $@"๐Ÿท __`ID:`__ **{user.Id}** -//๐ŸŽฎ __`Current Game:`__ **{(user.Game?.Name == null ? "-" : user.Game.Name)}** -//๐Ÿ“… __`Joined Server:`__ **{user.JoinedAt?.ToString("dd.MM.yyyy HH:mm")}** -//๐Ÿ—“ __`Joined Discord:`__ **{user.CreatedAt.ToString("dd.MM.yyyy HH:mm")}** -//โš” __`Roles:`__ **({user.Roles.Count()}) - {string.Join(", ", user.Roles.Select(r => r.Name)).SanitizeMentions()}**"; - //if (!string.IsNullOrWhiteSpace(user.AvatarUrl)) - //toReturn += $@" -//๐Ÿ“ท __`Avatar URL:`__ **{await NadekoBot.Google.ShortenUrl(user.AvatarUrl).ConfigureAwait(false)}**"; - //await msg.Channel.SendConfirmAsync(toReturn).ConfigureAwait(false); + embed.AddField(fb => fb.WithName("**ID**").WithValue(user.Id.ToString()).WithIsInline(true)) + .AddField(fb => fb.WithName("**Joined Server**").WithValue($"{user.JoinedAt?.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) + .AddField(fb => fb.WithName("**Joined Discord**").WithValue($"{user.CreatedAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true)) + .AddField(fb => fb.WithName("**Current Game**").WithValue($"{(user.Game?.Name == null ? "-" : user.Game.Name)}").WithIsInline(true)) + .AddField(fb => fb.WithName("**Roles**").WithValue($"**({user.Roles.Count()})** - {string.Join(", ", user.Roles.Select(r => r.Name)).SanitizeMentions()}").WithIsInline(true)) + .WithThumbnail(tn => tn.WithUrl(user.AvatarUrl)) + .WithColor(NadekoBot.OkColor); + await msg.Channel.EmbedAsync(embed.Build()).ConfigureAwait(false); } } } diff --git a/src/NadekoBot/Services/CurrencyHandler.cs b/src/NadekoBot/Services/CurrencyHandler.cs index c12dffec..45383968 100644 --- a/src/NadekoBot/Services/CurrencyHandler.cs +++ b/src/NadekoBot/Services/CurrencyHandler.cs @@ -14,7 +14,7 @@ namespace NadekoBot.Services var success = await RemoveCurrencyAsync(author.Id, reason, amount); if (success && sendMessage) - try { await author.SendMessageAsync($"`You lost:` {amount} {Gambling.CurrencySign}\n`Reason:` {reason}").ConfigureAwait(false); } catch { } + try { await author.SendErrorAsync($"`You lost:` {amount} {Gambling.CurrencySign}\n`Reason:` {reason}").ConfigureAwait(false); } catch { } return success; } @@ -47,7 +47,7 @@ namespace NadekoBot.Services await AddCurrencyAsync(author.Id, reason, amount); if (sendMessage) - try { await author.SendMessageAsync($"`You received:` {amount} {Gambling.CurrencySign}\n`Reason:` {reason}").ConfigureAwait(false); } catch { } + try { await author.SendConfirmAsync($"`You received:` {amount} {Gambling.CurrencySign}\n`Reason:` {reason}").ConfigureAwait(false); } catch { } } public static async Task AddCurrencyAsync(ulong receiverId, string reason, long amount) diff --git a/src/NadekoBot/Services/Database/Models/GuildConfig.cs b/src/NadekoBot/Services/Database/Models/GuildConfig.cs index 2c39b4a2..99608eff 100644 --- a/src/NadekoBot/Services/Database/Models/GuildConfig.cs +++ b/src/NadekoBot/Services/Database/Models/GuildConfig.cs @@ -54,11 +54,13 @@ namespace NadekoBot.Services.Database.Models public HashSet FilteredWords { get; set; } = new HashSet(); public HashSet FilterWordsChannelIds { get; set; } = new HashSet(); + public HashSet MutedUsers { get; set; } = new HashSet(); + public string MuteRoleName { get; set; } public bool CleverbotEnabled { get; set; } } - public class FilterChannelId :DbEntity + public class FilterChannelId : DbEntity { public ulong ChannelId { get; set; } } @@ -68,6 +70,25 @@ namespace NadekoBot.Services.Database.Models public string Word { get; set; } } + public class MutedUserId : DbEntity + { + public ulong UserId { get; set; } + + public override int GetHashCode() + { + return UserId.GetHashCode(); + } + + public override bool Equals(object obj) + { + var mui = obj as MutedUserId; + if (mui == null) + return false; + + return mui.UserId == this.UserId; + } + } + public class GCChannelId : DbEntity { public ulong ChannelId { get; set; } diff --git a/src/NadekoBot/Services/Database/NadekoContext.cs b/src/NadekoBot/Services/Database/NadekoContext.cs index 6752343a..ec7c2288 100644 --- a/src/NadekoBot/Services/Database/NadekoContext.cs +++ b/src/NadekoBot/Services/Database/NadekoContext.cs @@ -36,7 +36,7 @@ namespace NadekoBot.Services.Database public NadekoContext() { - this.Database.Migrate(); + this.Database.Migrate(); } public NadekoContext(DbContextOptions options) : base(options) @@ -44,7 +44,7 @@ namespace NadekoBot.Services.Database this.Database.Migrate(); EnsureSeedData(); } - //Uncomment this to db initialisation with dotnet ef migration add [module] + ////Uncomment this to db initialisation with dotnet ef migration add [module] //protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) //{ // optionsBuilder.UseSqlite("Filename=./data/NadekoBot.db"); diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs index 96f0cc22..957f40a2 100644 --- a/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs @@ -22,6 +22,7 @@ namespace NadekoBot.Services.Database.Repositories.Impl .ThenInclude(gc => gc.Previous) .Include(gc => gc.RootPermission) .ThenInclude(gc => gc.Next) + .Include(gc => gc.MutedUsers) .Include(gc => gc.GenerateCurrencyChannelIds) .Include(gc => gc.FilterInvitesChannelIds) .Include(gc => gc.FilterWordsChannelIds) diff --git a/src/NadekoBot/Services/Impl/GoogleApiService.cs b/src/NadekoBot/Services/Impl/GoogleApiService.cs index cb401476..6a18c686 100644 --- a/src/NadekoBot/Services/Impl/GoogleApiService.cs +++ b/src/NadekoBot/Services/Impl/GoogleApiService.cs @@ -51,6 +51,8 @@ namespace NadekoBot.Services.Impl return (await query.ExecuteAsync()).Items.Select(i => i.Id.PlaylistId); } + private readonly Regex YtVideoIdRegex = new Regex("(?:youtu\\.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=|\\&v=)(?[^#\\&\\?]*)", RegexOptions.Compiled); + public async Task> GetRelatedVideosAsync(string id, int count = 1) { if (string.IsNullOrWhiteSpace(id)) @@ -59,7 +61,7 @@ namespace NadekoBot.Services.Impl if (count <= 0) throw new ArgumentOutOfRangeException(nameof(count)); - var match = new Regex("(?:youtu\\.be\\/|v=)(?[\\da-zA-Z\\-_]*)").Match(id); + var match = YtVideoIdRegex.Match(id); if (match.Length > 1) { id = match.Groups["id"].Value; @@ -79,6 +81,16 @@ namespace NadekoBot.Services.Impl if (count <= 0) throw new ArgumentOutOfRangeException(nameof(count)); + string id = ""; + var match = YtVideoIdRegex.Match(keywords); + if (match.Length > 1) + { + id = match.Groups["id"].Value; + } + if (!string.IsNullOrWhiteSpace(id)) + { + return new[] { "http://www.youtube.com/watch?v=" + id }; + } var query = yt.Search.List("snippet"); query.MaxResults = count; query.Q = keywords; diff --git a/src/NadekoBot/_Extensions/Extensions.cs b/src/NadekoBot/_Extensions/Extensions.cs index 0b5051c7..a94681bb 100644 --- a/src/NadekoBot/_Extensions/Extensions.cs +++ b/src/NadekoBot/_Extensions/Extensions.cs @@ -68,6 +68,18 @@ namespace NadekoBot.Extensions public static async Task SendMessageAsync(this IGuildUser user, string message, bool isTTS = false) => await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendMessageAsync(message, isTTS).ConfigureAwait(false); + public static async Task SendConfirmAsync(this IGuildUser user, string text) + => await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new Embed() { Description = text, Color = NadekoBot.OkColor }); + + public static async Task SendConfirmAsync(this IGuildUser user, string title, string text, string url = null) + => await(await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new Embed() { Description = text, Title = title, Url = url, Color = NadekoBot.OkColor }); + + public static async Task SendErrorAsync(this IGuildUser user, string title, string error, string url = null) + => await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new Embed() { Description = error, Title = title, Url = url, Color = NadekoBot.ErrorColor }); + + public static async Task SendErrorAsync(this IGuildUser user, string error) + => await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new Embed() { Description = error, Color = NadekoBot.ErrorColor }); + public static async Task SendFileAsync(this IGuildUser user, string filePath, string caption = null, bool isTTS = false) => await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(filePath, caption, isTTS).ConfigureAwait(false); diff --git a/src/NadekoBot/data/questions.json b/src/NadekoBot/data/questions.json index b74a23a1..4a2fa9f3 100644 --- a/src/NadekoBot/data/questions.json +++ b/src/NadekoBot/data/questions.json @@ -523,7 +523,7 @@ }, { "Category": "Acronym Soup", - "Question": " BOS;big orange switch", + "Question": " BOS", "Answer": "boyfriend over shoulder" }, { @@ -1676,7 +1676,7 @@ "Answer": "Voyage of the Mimi" }, { - "Question": "Benazir Bhutto regained power in 1993 after being ousted how many years before;three", + "Question": "Benazir Bhutto regained power in 1993 after being ousted how many years before", "Answer": "3" }, { @@ -5805,7 +5805,7 @@ "Answer": "pompidou" }, { - "Question": "In 1974 Soyuz ---------- is launched. ;fourteen", + "Question": "In 1974 Soyuz ---------- is launched.", "Answer": "14" }, { @@ -5865,7 +5865,7 @@ "Answer": "fatima" }, { - "Question": "In 1982 1st permanent artificial ---------- successfully implanted (U of Utah) in retired dentist Barney Clark; lived 112 days with the Jarvic-7 heart. ", + "Question": "In 1982 1st permanent artificial ---------- successfully implanted (U of Utah) in retired dentist Barney Clark", "Answer": "heart" }, { @@ -6186,7 +6186,7 @@ "Answer": "whitsun" }, { - "Question": "In the contract that gave cuba freedom from the us, what was required;permanent us navy base there", + "Question": "In the contract that gave cuba freedom from the us, what was required", "Answer": "permanent naval base" }, { @@ -7041,7 +7041,7 @@ }, { "Category": "Music", - "Question": " what composer and organist was married twice and had 20 children;johann sebastian bach", + "Question": " what composer and organist was married twice and had 20 children", "Answer": "bach" }, { @@ -7414,12 +7414,12 @@ "Answer": "bones" }, { - "Question": "Other than the U.K. and Eire, name a European country where cars are driven on the left hand side of the road.;cyprus", + "Question": "Other than the U.K. and Eire, name a European country where cars are driven on the left hand side of the road.", "Answer": "malta" }, { - "Question": "Pagophobia is the fear of;ice", - "Answer": "frost" + "Question": "Pagophobia is the fear of", + "Answer": "ice" }, { "Question": "Pants", @@ -7744,7 +7744,7 @@ "Answer": "parents-in-law" }, { - "Question": "Solar time what's the usual age for a jewish boy to celebrate his 'bar mitzvah';thirteen", + "Question": "Solar time what's the usual age for a jewish boy to celebrate his 'bar mitzvah'", "Answer": "13" }, { @@ -7757,7 +7757,7 @@ "Answer": "immortality" }, { - "Question": "Spectrophobia is the fear of;specters", + "Question": "Spectrophobia is the fear of", "Answer": "ghosts" }, { @@ -7871,8 +7871,8 @@ "Answer": "alaska" }, { - "Question": "The canary islands in the pacific are named after what animal;dog", - "Answer": "dogs" + "Question": "The canary islands in the pacific are named after what animal", + "Answer": "dog" }, { "Question": "The childrens story 'The Rose and The Ring' was written by which 19th century novelist", @@ -7947,7 +7947,7 @@ "Answer": "galileo" }, { - "Question": "The Irish Province of Connaught contains five counties. Sligo and Galway are two. Name one of the others. leitrim;mayo", + "Question": "The Irish Province of Connaught contains five counties. Sligo, Mayo and Galway are three. Name one of the others.", "Answer": "roscommon" }, { @@ -8035,8 +8035,8 @@ "Answer": "beard" }, { - "Question": "The ore pitchblende is the major source of which element;uranium", - "Answer": "radium" + "Question": "The ore pitchblende is the major source of which element", + "Answer": "uranium" }, { "Question": "The peace of Aix-la-Chapelle was celebrated by which piece of music", @@ -8171,7 +8171,7 @@ "Answer": "aardvark" }, { - "Question": "This company uses the slogan AOL;america on line", + "Question": "This company uses the slogan AOL", "Answer": "america online" }, { @@ -8251,7 +8251,7 @@ "Answer": "flies" }, { - "Question": "To the nearest minute, how long does it take sunlight to reach earth;eight", + "Question": "To the nearest minute, how long does it take sunlight to reach earth", "Answer": "8" }, { @@ -8291,7 +8291,7 @@ "Answer": "mclaren" }, { - "Question": "To within 30 feet, how tall is the Eiffel Tower;nine hundred & eighty four", + "Question": "To within 30 feet, how tall is the Eiffel Tower", "Answer": "984" }, { @@ -8337,8 +8337,8 @@ "Answer": "frigid" }, { - "Question": "Unscramble the letters of the words 'no stamp' into a single english word;postman", - "Answer": "tampons" + "Question": "Unscramble the letters of the words 'no stamp' into a single english word.", + "Answer": "postman" }, { "Category": "UnScramble this Word", @@ -9760,7 +9760,7 @@ "Answer": "Augusta" }, { - "Question": "US Captials - Minnesota;St. Paul", + "Question": "US Captials - Minnesota", "Answer": "St Paul" }, { @@ -9805,7 +9805,7 @@ }, { "Category": "Useless Facts", - "Question": " Banging your head against a wall can burn up to ----------- calories per hour.;one hundred and fifty", + "Question": " Banging your head against a wall can burn up to ----------- calories per hour.", "Answer": "150" }, { @@ -9840,7 +9840,7 @@ }, { "Category": "Useless Facts", - "Question": " It has been estimated that the typical American will spend an average of -------- years of his/her life reading newspapers.;two", + "Question": " It has been estimated that the typical American will spend an average of -------- years of his/her life reading newspapers.", "Answer": "2" }, { @@ -9955,7 +9955,7 @@ }, { "Category": "Useless Trivia", - "Question": " A lifetime supply of all the vitamins you need weighs only about ---------- ounces.;eight", + "Question": " A lifetime supply of all the vitamins you need weighs only about ---------- ounces.", "Answer": "8" }, { @@ -10045,7 +10045,7 @@ }, { "Category": "Useless Trivia", - "Question": " At birth a panda is smaller than a mouse and weighs about ---------- ounces.;four", + "Question": " At birth a panda is smaller than a mouse and weighs about ---------- ounces.", "Answer": "4" }, { @@ -10160,7 +10160,7 @@ }, { "Category": "Useless Trivia", - "Question": " Gorillas often sleep for up to ---------- hours a day.;fourteen", + "Question": " Gorillas often sleep for up to ---------- hours a day.", "Answer": "14" }, { @@ -10235,7 +10235,7 @@ }, { "Category": "Useless Trivia", - "Question": " In the Great Fire of London in 1666, half of London was burnt down but only ---------- people were injured.;six", + "Question": " In the Great Fire of London in 1666, half of London was burnt down but only ---------- people were injured.", "Answer": "6" }, { @@ -10374,7 +10374,7 @@ }, { "Category": "Video Games", - "Question": " 'Secret of Evermore' was entirely produced in which country?;U.S.A.;usa;America", + "Question": " 'Secret of Evermore' was entirely produced in which country?", "Answer": "United States" }, { @@ -10575,7 +10575,7 @@ "Answer": "swan" }, { - "Question": "What body of water is fed from the south by the Wadi Araba & from the north by the river Jordan;the dead sea", + "Question": "What body of water is fed from the south by the Wadi Araba & from the north by the river Jordan", "Answer": "dead sea" }, { @@ -10667,7 +10667,7 @@ "Answer": "black russian" }, { - "Question": "What color is the blood of an octopus;pale bluish-green", + "Question": "What color is the blood of an octopus", "Answer": "bluish green" }, { @@ -11124,7 +11124,7 @@ "Answer": "fruit" }, { - "Question": "What is 240 minutes in hours;four", + "Question": "What is 240 minutes in hours", "Answer": "4" }, { @@ -11464,8 +11464,8 @@ "Answer": "five to seven" }, { - "Question": "What is the average temperature (f) at the South Pole;minus fifty six", - "Answer": "56" + "Question": "What is the average temperature (f) at the South Pole", + "Answer": "-56" }, { "Question": "What is the base twenty numbering system", @@ -12318,7 +12318,7 @@ "Answer": "dreamt" }, { - "Question": "What is the point value of the 'f' in scrabble ;four", + "Question": "What is the point value of the 'f' in scrabble", "Answer": "4" }, { @@ -12742,11 +12742,11 @@ "Answer": "gone with the wind" }, { - "Question": "What number does VII mean in roman numerals;seven", + "Question": "What number does VII mean in roman numerals", "Answer": "7" }, { - "Question": "What number is at 6 oclock on a dartboard;three", + "Question": "What number is at 6 oclock on a dartboard", "Answer": "3" }, { @@ -12798,7 +12798,7 @@ "Answer": "yucatan" }, { - "Question": "What percentage of alcohol is contained in a 100 proof mixture;fifty", + "Question": "What percentage of alcohol is contained in a 100 proof mixture", "Answer": "50" }, { @@ -13035,8 +13035,8 @@ "Answer": "typhoon" }, { - "Question": "What structure in the back of the brain governs motor control;cerebellum", - "Answer": "the cerebellum" + "Question": "What structure in the back of the brain governs motor contro", + "Answer": "cerebellum" }, { "Question": "What style of dancing was popularized with rap music?", @@ -13095,8 +13095,8 @@ "Answer": "bert and ernie" }, { - "Question": "What two countries were known as 'the yellow peril' in the 1890's ;china & japan", - "Answer": "japan & china" + "Question": "What two countries were known as 'the yellow peril' in the 1890's", + "Answer": "japan and china" }, { "Question": "What type of animal was selected to test the first electric toothbrush", @@ -15659,7 +15659,7 @@ "Answer": "bugsy siegel" }, { - "Question": "Whose grandson got the first phone call from a commercial cellular system, in 1983;alexander graham bell's;alexander graham bells", + "Question": "Whose grandson got the first phone call from a commercial cellular system, in 1983", "Answer": "alexander graham bell" }, {