Merge pull request #36 from Kwoth/dev

ups
This commit is contained in:
samvaio 2016-12-13 16:37:37 +05:30 committed by GitHub
commit 7a4ff53637
51 changed files with 1827 additions and 781 deletions

20
Dockerfile Normal file
View File

@ -0,0 +1,20 @@
FROM microsoft/dotnet:sdk
MAINTAINER Poag <poag@gany.net>
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"]

@ -1 +1 @@
Subproject commit 321f6bb2155dcece696d93c6be4023b457b3eaa2
Subproject commit 508026d5d4f4d8780d983c63ab25e4c15ad69e59

View File

@ -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`

View File

@ -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.

View File

@ -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.
## 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.

View File

@ -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<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<ulong>("ItemId");
b.Property<int>("Type");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("BlacklistItem");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.BotConfig", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("BufferSize");
b.Property<float>("CurrencyGenerationChance");
b.Property<int>("CurrencyGenerationCooldown");
b.Property<string>("CurrencyName");
b.Property<string>("CurrencyPluralName");
b.Property<string>("CurrencySign");
b.Property<string>("DMHelpString");
b.Property<bool>("ForwardMessages");
b.Property<bool>("ForwardToAllOwners");
b.Property<string>("HelpString");
b.Property<int>("MigrationVersion");
b.Property<string>("RemindMessageFormat");
b.Property<bool>("RotatingStatuses");
b.HasKey("Id");
b.ToTable("BotConfig");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("BaseDestroyed");
b.Property<string>("CallUser");
b.Property<int>("ClashWarId");
b.Property<int?>("SequenceNumber");
b.Property<int>("Stars");
b.Property<DateTime>("TimeAdded");
b.HasKey("Id");
b.HasIndex("ClashWarId");
b.ToTable("ClashCallers");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashWar", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<string>("EnemyClan");
b.Property<ulong>("GuildId");
b.Property<int>("Size");
b.Property<DateTime>("StartedAt");
b.Property<int>("WarState");
b.HasKey("Id");
b.ToTable("ClashOfClans");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("CommandName");
b.Property<int?>("GuildConfigId");
b.Property<int>("Seconds");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("CommandCooldown");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ConvertUnit", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("InternalTrigger");
b.Property<decimal>("Modifier");
b.Property<string>("UnitType");
b.HasKey("Id");
b.ToTable("ConversionUnits");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Currency", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<long>("Amount");
b.Property<ulong>("UserId");
b.HasKey("Id");
b.HasIndex("UserId")
.IsUnique();
b.ToTable("Currency");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.CurrencyTransaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<long>("Amount");
b.Property<string>("Reason");
b.Property<ulong>("UserId");
b.HasKey("Id");
b.ToTable("CurrencyTransactions");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.CustomReaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong?>("GuildId");
b.Property<bool>("IsRegex");
b.Property<bool>("OwnerOnly");
b.Property<string>("Response");
b.Property<string>("Trigger");
b.HasKey("Id");
b.ToTable("CustomReactions");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Donator", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("Amount");
b.Property<string>("Name");
b.Property<ulong>("UserId");
b.HasKey("Id");
b.HasIndex("UserId")
.IsUnique();
b.ToTable("Donators");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("Text");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("EightBallResponses");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("GuildConfigId");
b.Property<int?>("GuildConfigId1");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.HasIndex("GuildConfigId1");
b.ToTable("FilterChannelId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("GuildConfigId");
b.Property<string>("Word");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("FilteredWord");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("GuildConfigId");
b.Property<ulong>("GuildId");
b.Property<int>("Type");
b.Property<string>("Username");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("FollowedStream");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("GuildConfigId");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("GCChannelId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("AutoAssignRoleId");
b.Property<bool>("AutoDeleteByeMessages");
b.Property<int>("AutoDeleteByeMessagesTimer");
b.Property<bool>("AutoDeleteGreetMessages");
b.Property<int>("AutoDeleteGreetMessagesTimer");
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages");
b.Property<ulong>("ByeMessageChannelId");
b.Property<string>("ChannelByeMessageText");
b.Property<string>("ChannelGreetMessageText");
b.Property<bool>("CleverbotEnabled");
b.Property<float>("DefaultMusicVolume");
b.Property<bool>("DeleteMessageOnCommand");
b.Property<string>("DmGreetMessageText");
b.Property<bool>("ExclusiveSelfAssignedRoles");
b.Property<bool>("FilterInvites");
b.Property<bool>("FilterWords");
b.Property<ulong>("GreetMessageChannelId");
b.Property<ulong>("GuildId");
b.Property<int?>("LogSettingId");
b.Property<string>("MuteRoleName");
b.Property<string>("PermissionRole");
b.Property<int?>("RootPermissionId");
b.Property<bool>("SendChannelByeMessage");
b.Property<bool>("SendChannelGreetMessage");
b.Property<bool>("SendDmGreetMessage");
b.Property<bool>("VerbosePermissions");
b.Property<bool>("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<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("LogSettingId");
b.HasKey("Id");
b.HasIndex("LogSettingId");
b.ToTable("IgnoredLogChannels");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("LogSettingId");
b.HasKey("Id");
b.HasIndex("LogSettingId");
b.ToTable("IgnoredVoicePresenceCHannels");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("ChannelCreated");
b.Property<bool>("ChannelDestroyed");
b.Property<ulong>("ChannelId");
b.Property<bool>("ChannelUpdated");
b.Property<bool>("IsLogging");
b.Property<bool>("LogUserPresence");
b.Property<bool>("LogVoicePresence");
b.Property<bool>("MessageDeleted");
b.Property<bool>("MessageUpdated");
b.Property<bool>("UserBanned");
b.Property<bool>("UserJoined");
b.Property<bool>("UserLeft");
b.Property<ulong>("UserPresenceChannelId");
b.Property<bool>("UserUnbanned");
b.Property<bool>("UserUpdated");
b.Property<ulong>("VoicePresenceChannelId");
b.HasKey("Id");
b.ToTable("LogSettings");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("ModuleName");
b.Property<string>("Prefix");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("ModulePrefixes");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlaylist", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Author");
b.Property<ulong>("AuthorId");
b.Property<string>("Name");
b.HasKey("Id");
b.ToTable("MusicPlaylists");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("GuildConfigId");
b.Property<ulong>("UserId");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("MutedUserId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("NextId");
b.Property<int>("PrimaryTarget");
b.Property<ulong>("PrimaryTargetId");
b.Property<int>("SecondaryTarget");
b.Property<string>("SecondaryTargetName");
b.Property<bool>("State");
b.HasKey("Id");
b.HasIndex("NextId")
.IsUnique();
b.ToTable("Permission");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("Status");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("PlayingStatus");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("MusicPlaylistId");
b.Property<string>("Provider");
b.Property<int>("ProviderType");
b.Property<string>("Query");
b.Property<string>("Title");
b.Property<string>("Uri");
b.HasKey("Id");
b.HasIndex("MusicPlaylistId");
b.ToTable("PlaylistSong");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("AuthorId");
b.Property<string>("AuthorName")
.IsRequired();
b.Property<ulong>("GuildId");
b.Property<string>("Keyword")
.IsRequired();
b.Property<string>("Text")
.IsRequired();
b.HasKey("Id");
b.ToTable("Quotes");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("Icon");
b.Property<string>("Name");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("RaceAnimals");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<bool>("IsPrivate");
b.Property<string>("Message");
b.Property<ulong>("ServerId");
b.Property<ulong>("UserId");
b.Property<DateTime>("When");
b.HasKey("Id");
b.ToTable("Reminders");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Repeater", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<ulong>("GuildId");
b.Property<TimeSpan>("Interval");
b.Property<string>("Message");
b.HasKey("Id");
b.HasIndex("ChannelId")
.IsUnique();
b.ToTable("Repeaters");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("GuildId");
b.Property<ulong>("RoleId");
b.HasKey("Id");
b.HasIndex("GuildId", "RoleId")
.IsUnique();
b.ToTable("SelfAssignableRoles");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.UserPokeTypes", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("UserId");
b.Property<string>("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");
});
}
}
}

View File

@ -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<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
GuildConfigId = table.Column<int>(nullable: true),
UserId = table.Column<ulong>(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");
}
}
}

View File

@ -492,6 +492,22 @@ namespace NadekoBot.Migrations
b.ToTable("MusicPlaylists");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("GuildConfigId");
b.Property<ulong>("UserId");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("MutedUserId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b =>
{
b.Property<int>("Id")
@ -663,7 +679,7 @@ namespace NadekoBot.Migrations
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<long>("UserId");
b.Property<ulong>("UserId");
b.Property<string>("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")

View File

@ -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<ulong, string> GuildMuteRoles { get; } = new ConcurrentDictionary<ulong, string>();
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<ulong, string>(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<IRole> 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<Donator> 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);
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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 { }
}
}
}

View File

@ -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)
{

View File

@ -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);
}
}
}

View File

@ -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<ulong, string> GuildMuteRoles { get; } = new ConcurrentDictionary<ulong, string>();
private static ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> MutedUsers { get; } = new ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>>();
public static event Func<IGuildUser, MuteType, Task> UserMuted = delegate { return Task.CompletedTask; };
public static event Func<IGuildUser, MuteType, Task> 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<ulong, string>(configs
.Where(c => !string.IsNullOrWhiteSpace(c.MuteRoleName))
.ToDictionary(c => c.GuildId, c => c.MuteRoleName));
MutedUsers = new ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>>(configs.ToDictionary(
k => k.GuildId,
v => new ConcurrentHashSet<ulong>(v.MutedUsers.Select(m => m.UserId))
));
}
NadekoBot.Client.UserJoined += Client_UserJoined;
}
private static async Task Client_UserJoined(IGuildUser usr)
{
ConcurrentHashSet<ulong> 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<ulong> 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<ulong> 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<IRole> 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);
}
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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<SelfAssignedRole>();
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)
{

View File

@ -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);
}
}
}

View File

@ -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<bool> 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<bool> 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<bool> 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)

View File

@ -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);
}
}
}

View File

@ -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<ClashWar> 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);
}
}

View File

@ -47,6 +47,7 @@ namespace NadekoBot.Modules.CustomReactions
}).Shuffle().FirstOrDefault();
if (reaction != null)
{
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,12 +130,11 @@ namespace NadekoBot.Modules.CustomReactions
customReactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<CustomReaction>());
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)
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}")))
@ -154,7 +159,7 @@ namespace NadekoBot.Modules.CustomReactions
customReactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<CustomReaction>());
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<CustomReaction>());
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);
}
}
}

View File

@ -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}!**" : "**"));
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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]

View File

@ -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);
}
}
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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<ulong> 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<ulong>();
}
public ITextChannel Channel { get; set; }
public async Task<bool> 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,7 +198,7 @@ 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);
}
@ -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);
}
}

View File

@ -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))
{

View File

@ -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);
}
}
}

View File

@ -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.

View File

@ -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,12 +94,11 @@ 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);
}
@ -157,7 +156,7 @@ namespace NadekoBot.Modules.Help
{
var channel = (ITextChannel)umsg.Channel;
await channel.SendMessageAsync(
await channel.SendConfirmAsync(
@"**LIST OF COMMANDS**: <http://nadekobot.readthedocs.io/en/latest/Commands%20List/>
**Hosting Guides and docs can be found here**: <http://nadekobot.readthedocs.io/en/latest/>").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. <https://patreon.com/nadekobot> or
You can send donations to `nadekodiscordbot@gmail.com`
Don't forget to leave your discord name or id in the message.

View File

@ -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);
}
@ -72,7 +72,7 @@ namespace NadekoBot.Modules.NSFW
if (links.All(l => l == null))
{
await channel.SendMessageAsync("`No results.`").ConfigureAwait(false);
await channel.SendErrorAsync("No results found.").ConfigureAwait(false);
return;
}
@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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<ActiveCooldown>());
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<CommandCooldown>());
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);
}

View File

@ -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,9 +110,6 @@ 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);
}
@ -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);
}
}
}

View File

@ -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

View File

@ -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()
.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))
.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("**Custom Emojis**").WithValue($"*{string.Join(", ", server.Emojis)}*").WithIsInline(true))
.WithThumbnail(tn => tn.Url = $"{ server.IconUrl}")
.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);
await msg.Channel.EmbedAsync(embed.Build()).ConfigureAwait(false);
}
else
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))
.WithThumbnail(tn => tn.Url = $"{ server.IconUrl}")
.WithColor(NadekoBot.OkColor);
await msg.Channel.EmbedAsync(embed.Build()).ConfigureAwait(false);
return;
embed.AddField(fb => fb.WithName("**Custom Emojis**").WithValue(Format.Italics(string.Join(", ", guild.Emojis))).WithIsInline(true));
}
//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,35 +61,15 @@ 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))
.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}").WithIsInline(true))
.AddField(fb => fb.WithName("**Users**").WithValue(usercount.ToString()).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);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
@ -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("**Name**").WithValue($"**{user.Username}**#{user.Discriminator}").WithIsInline(true));
if (!string.IsNullOrWhiteSpace(user.Nickname)) {
embed.AddField(fb => fb.WithName("**Nickname**").WithValue(user.Nickname).WithIsInline(true));
}
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(false))
//.AddField(fb => fb.WithName("**Avatar URL**").WithValue(avurl).WithIsInline(true))
.WithThumbnail(tn => tn.Url = $"{user.AvatarUrl}")
.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);
}
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);
}
}
}

View File

@ -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)

View File

@ -54,11 +54,13 @@ namespace NadekoBot.Services.Database.Models
public HashSet<FilteredWord> FilteredWords { get; set; } = new HashSet<FilteredWord>();
public HashSet<FilterChannelId> FilterWordsChannelIds { get; set; } = new HashSet<FilterChannelId>();
public HashSet<MutedUserId> MutedUsers { get; set; } = new HashSet<MutedUserId>();
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; }

View File

@ -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");

View File

@ -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)

View File

@ -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=)(?<id>[^#\\&\\?]*)", RegexOptions.Compiled);
public async Task<IEnumerable<string>> 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=)(?<id>[\\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;

View File

@ -68,6 +68,18 @@ namespace NadekoBot.Extensions
public static async Task<IUserMessage> SendMessageAsync(this IGuildUser user, string message, bool isTTS = false) =>
await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendMessageAsync(message, isTTS).ConfigureAwait(false);
public static async Task<IUserMessage> SendConfirmAsync(this IGuildUser user, string text)
=> await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new Embed() { Description = text, Color = NadekoBot.OkColor });
public static async Task<IUserMessage> 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<IUserMessage> 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<IUserMessage> SendErrorAsync(this IGuildUser user, string error)
=> await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new Embed() { Description = error, Color = NadekoBot.ErrorColor });
public static async Task<IUserMessage> SendFileAsync(this IGuildUser user, string filePath, string caption = null, bool isTTS = false) =>
await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(filePath, caption, isTTS).ConfigureAwait(false);

View File

@ -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"
},
{