diff --git a/docs/Commands List.md b/docs/Commands List.md
index 513edd6a..0021e0cc 100644
--- a/docs/Commands List.md
+++ b/docs/Commands List.md
@@ -26,7 +26,7 @@ Commands and aliases | Description | Usage
`.renamerole` `.renr` | Renames a role. The role you are renaming must be lower than bot's highest role. **Requires ManageRoles server permission.** | `.renr "First role" SecondRole`
`.removeallroles` `.rar` | Removes all roles from a mentioned user. **Requires ManageRoles server permission.** | `.rar @User`
`.createrole` `.cr` | Creates a role with a given name. **Requires ManageRoles server permission.** | `.cr Awesome Role`
-`.rolehoist` `.rh` | Toggles if this role is displayed in the sidebar or not **Requires ManageRoles server permission.** | `.rh Guests true` or `.rh "Space Wizards" true
+`.rolehoist` `.rh` | Toggles if this role is displayed in the sidebar or not **Requires ManageRoles server permission.** | `.rh Guests true` or `.rh "Space Wizards" true`
`.rolecolor` `.rc` | Set a role's color to the hex or 0-255 rgb color value provided. **Requires ManageRoles server permission.** | `.rc Admin 255 200 100` or `.rc Admin ffba55`
`.deafen` `.deaf` | Deafens mentioned user or users. **Requires DeafenMembers server permission.** | `.deaf "@Someguy"` or `.deaf "@Someguy" "@Someguy"`
`.undeafen` `.undef` | Undeafens mentioned user or users. **Requires DeafenMembers server permission.** | `.undef "@Someguy"` or `.undef "@Someguy" "@Someguy"`
@@ -73,7 +73,7 @@ Commands and aliases | Description | Usage
`.lsar` | Lists all self-assignable roles. | `.lsar`
`.togglexclsar` `.tesar` | Toggles whether the self-assigned roles are exclusive. (So that any person can have only one of the self assignable roles) **Requires ManageRoles server permission.** | `.tesar`
`.iam` | Adds a role to you that you choose. Role must be on a list of self-assignable roles. | `.iam Gamer`
-`.iamnot` `.iamn` | Removes a role to you that you choose. Role must be on a list of self-assignable roles. | `.iamn Gamer`
+`.iamnot` `.iamn` | Removes a specified role from you. Role must be on a list of self-assignable roles. | `.iamn Gamer`
`.scadd` | Adds a command to the list of commands which will be executed automatically in the current channel, in the order they were added in, by the bot when it startups up. **Bot owner only** | `.scadd .stats`
`.sclist` | Lists all startup commands in the order they will be executed in. **Bot owner only** | `.sclist`
`.wait` | Used only as a startup command. Waits a certain number of miliseconds before continuing the execution of the following startup commands. **Bot owner only** | `.wait 3000`
@@ -94,11 +94,11 @@ Commands and aliases | Description | Usage
`.reloadimages` | Reloads images bot is using. Safe to use even when bot is being used heavily. **Bot owner only** | `.reloadimages`
`.greetdel` `.grdel` | Sets the time it takes (in seconds) for greet messages to be auto-deleted. Set it to 0 to disable automatic deletion. **Requires ManageServer server permission.** | `.greetdel 0` or `.greetdel 30`
`.greet` | Toggles anouncements on the current channel when someone joins the server. **Requires ManageServer server permission.** | `.greet`
-`.greetmsg` | Sets a new join announcement message which will be shown in the server's channel. Type `%user%` if you want to mention the new member. Using it with no message will show the current greet message. You can use embed json from instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.greetmsg Welcome, %user%.`
+`.greetmsg` | Sets a new join announcement message which will be shown in the server's channel. Type `%user%` if you want to mention the new member. Using it with no message will show the current greet message. You can use embed json from instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.greetmsg Welcome, %user%.`
`.greetdm` | Toggles whether the greet messages will be sent in a DM (This is separate from greet - you can have both, any or neither enabled). **Requires ManageServer server permission.** | `.greetdm`
-`.greetdmmsg` | Sets a new join announcement message which will be sent to the user who joined. Type `%user%` if you want to mention the new member. Using it with no message will show the current DM greet message. You can use embed json from instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.greetdmmsg Welcome to the server, %user%`.
+`.greetdmmsg` | Sets a new join announcement message which will be sent to the user who joined. Type `%user%` if you want to mention the new member. Using it with no message will show the current DM greet message. You can use embed json from instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.greetdmmsg Welcome to the server, %user%`.
`.bye` | Toggles anouncements on the current channel when someone leaves the server. **Requires ManageServer server permission.** | `.bye`
-`.byemsg` | Sets a new leave announcement message. Type `%user%` if you want to show the name the user who left. Type `%id%` to show id. Using this command with no message will show the current bye message. You can use embed json from instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.byemsg %user% has left.`
+`.byemsg` | Sets a new leave announcement message. Type `%user%` if you want to show the name the user who left. Type `%id%` to show id. Using this command with no message will show the current bye message. You can use embed json from instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.byemsg %user% has left.`
`.byedel` | Sets the time it takes (in seconds) for bye messages to be auto-deleted. Set it to `0` to disable automatic deletion. **Requires ManageServer server permission.** | `.byedel 0` or `.byedel 30`
`.warn` | Warns a user. **Requires BanMembers server permission.** | `.warn @b1nzy Very rude person`
`.warnlog` | See a list of warnings of a certain user. **Requires BanMembers server permission.** | `.warnlog @b1nzy`
@@ -170,7 +170,7 @@ Commands and aliases | Description | Usage
`$buy` | Buys an item from the shop on a given index. If buying items, make sure that the bot can DM you. | `$buy 2`
`$shopadd` | Adds an item to the shop by specifying type price and name. Available types are role and list. **Requires Administrator server permission.** | `$shopadd role 1000 Rich`
`$shoplistadd` | Adds an item to the list of items for sale in the shop entry given the index. You usually want to run this command in the secret channel, so that the unique items are not leaked. **Requires Administrator server permission.** | `$shoplistadd 1 Uni-que-Steam-Key`
-`$shoprem` `$shoprm` | Removes an item from the shop by its color. **Requires Administrator server permission.** | `$shoprm 1`
+`$shoprem` `$shoprm` | Removes an item from the shop by its ID. **Requires Administrator server permission.** | `$shoprm 1`
`$slotstats` | Shows the total stats of the slot command for this bot's session. **Bot owner only** | `$slotstats`
`$slottest` | Tests to see how much slots payout for X number of plays. **Bot owner only** | `$slottest 1000`
`$slot` | Play Nadeko slots. Max bet is 9999. 1.5 second cooldown per user. | `$slot 5`
@@ -311,8 +311,8 @@ Commands and aliases | Description | Usage
`;fw` | Adds or removes (if it exists) a word from the list of filtered words. Use`;sfw` or `;cfw` to toggle filtering. | `;fw poop`
`;lstfilterwords` `;lfw` | Shows a list of filtered words. | `;lfw`
`;listglobalperms` `;lgp` | Lists global permissions set by the bot owner. **Bot owner only** | `;lgp`
-`;globalmodule` `;gmod` | Enable or disable a module from use on all servers. **Bot owner only** | `;gmod nsfw disable`
-`;globalcommand` `;gcmd` | Enables or disables a command from use on all servers. **Bot owner only** | `;gcmd `
+`;globalmodule` `;gmod` | Toggles whether a module can be used on any server. **Bot owner only** | `;gmod nsfw`
+`;globalcommand` `;gcmd` | Toggles whether a command can be used on any server. **Bot owner only** | `;gcmd .stats`
###### [Back to ToC](#table-of-contents)
@@ -362,7 +362,7 @@ Commands and aliases | Description | Usage
`~manga` `~mang` `~mq` | Queries anilist for a manga and shows the first result. | `~mq Shingeki no kyojin`
`~yomama` `~ym` | Shows a random joke from | `~ym`
`~randjoke` `~rj` | Shows a random joke from | `~rj`
-`~chucknorris` `~cn` | Shows a random Chuck Norris joke from | `~cn`
+`~chucknorris` `~cn` | Shows a random Chuck Norris joke from | `~cn`
`~wowjoke` | Get one of Kwoth's penultimate WoW jokes. | `~wowjoke`
`~magicitem` `~mi` | Shows a random magic item from | `~mi`
`~memelist` | Pulls a list of memes you can use with `~memegen` from http://memegen.link/templates/ | `~memelist`
diff --git a/src/NadekoBot/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs
index 2aca6bf0..792e1ca0 100644
--- a/src/NadekoBot/Modules/Administration/Administration.cs
+++ b/src/NadekoBot/Modules/Administration/Administration.cs
@@ -41,7 +41,7 @@ namespace NadekoBot.Modules.Administration
var channel = msg.Channel as SocketTextChannel;
if (channel == null)
return;
- if (deleteMessagesOnCommand.Contains(channel.Guild.Id) && cmd.Name != "prune")
+ if (deleteMessagesOnCommand.Contains(channel.Guild.Id) && cmd.Name != "prune" && cmd.Name != "pick")
await msg.DeleteAsync().ConfigureAwait(false);
}
catch (Exception ex)
@@ -118,7 +118,7 @@ namespace NadekoBot.Modules.Administration
{
var guser = (IGuildUser)Context.User;
var maxRole = guser.GetRoles().Max(x => x.Position);
- if (maxRole < role.Position || maxRole <= usr.GetRoles().Max(x => x.Position))
+ if ((Context.User.Id != Context.Guild.OwnerId) && (maxRole < role.Position || maxRole <= usr.GetRoles().Max(x => x.Position)))
return;
try
{
@@ -378,12 +378,14 @@ namespace NadekoBot.Modules.Administration
{
var user = await Context.Guild.GetCurrentUserAsync().ConfigureAwait(false);
- var enumerable = (await Context.Channel.GetMessagesAsync().Flatten()).AsEnumerable();
- enumerable = enumerable.Where(x => x.Author.Id == user.Id);
+ var enumerable = (await Context.Channel.GetMessagesAsync().Flatten())
+ .Where(x => x.Author.Id == user.Id && DateTime.Now - x.CreatedAt < twoWeeks);
await Context.Channel.DeleteMessagesAsync(enumerable).ConfigureAwait(false);
Context.Message.DeleteAfter(3);
}
+
+ private TimeSpan twoWeeks => TimeSpan.FromDays(14);
// prune x
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
@@ -396,7 +398,8 @@ namespace NadekoBot.Modules.Administration
return;
await Context.Message.DeleteAsync().ConfigureAwait(false);
int limit = (count < 100) ? count + 1 : 100;
- var enumerable = (await Context.Channel.GetMessagesAsync(limit: limit).Flatten().ConfigureAwait(false));
+ var enumerable = (await Context.Channel.GetMessagesAsync(limit: limit).Flatten().ConfigureAwait(false))
+ .Where(x => DateTime.Now - x.CreatedAt < twoWeeks);
if (enumerable.FirstOrDefault()?.Id == Context.Message.Id)
enumerable = enumerable.Skip(1).ToArray();
else
@@ -419,7 +422,8 @@ namespace NadekoBot.Modules.Administration
count += 1;
int limit = (count < 100) ? count : 100;
- var enumerable = (await Context.Channel.GetMessagesAsync(limit: limit).Flatten()).Where(m => m.Author == user);
+ var enumerable = (await Context.Channel.GetMessagesAsync(limit: limit).Flatten())
+ .Where(m => m.Author == user && DateTime.Now - m.CreatedAt < twoWeeks);
await Context.Channel.DeleteMessagesAsync(enumerable).ConfigureAwait(false);
Context.Message.DeleteAfter(3);
@@ -434,7 +438,9 @@ namespace NadekoBot.Modules.Administration
foreach (var role in roles)
{
send += $"\n**{role.Name}**\n";
- send += string.Join(", ", (await Context.Guild.GetUsersAsync()).Where(u => u.GetRoles().Contains(role)).Take(50).Select(u => u.Mention));
+ send += string.Join(", ", (await Context.Guild.GetUsersAsync())
+ .Where(u => u.GetRoles().Contains(role))
+ .Take(50).Select(u => u.Mention));
}
while (send.Length > 2000)
diff --git a/src/NadekoBot/Modules/Administration/Commands/ProtectionCommands.cs b/src/NadekoBot/Modules/Administration/Commands/ProtectionCommands.cs
index 23f1eaf0..e89f14ba 100644
--- a/src/NadekoBot/Modules/Administration/Commands/ProtectionCommands.cs
+++ b/src/NadekoBot/Modules/Administration/Commands/ProtectionCommands.cs
@@ -10,6 +10,8 @@ using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
+using System.Threading;
+using System.Collections.Generic;
namespace NadekoBot.Modules.Administration
{
@@ -35,30 +37,51 @@ namespace NadekoBot.Modules.Administration
= new ConcurrentDictionary();
}
- public class UserSpamStats
+ public class UserSpamStats : IDisposable
{
- public int Count { get; set; }
+ public int Count => timers.Count;
public string LastMessage { get; set; }
- public UserSpamStats(string msg)
- {
- Count = 1;
- LastMessage = msg.ToUpperInvariant();
- }
+ private ConcurrentQueue timers { get; }
+ public UserSpamStats(IUserMessage msg)
+ {
+ LastMessage = msg.Content.ToUpperInvariant();
+ timers = new ConcurrentQueue();
+
+ ApplyNextMessage(msg);
+ }
+
+ private readonly object applyLock = new object();
public void ApplyNextMessage(IUserMessage message)
{
- var upperMsg = message.Content.ToUpperInvariant();
- if (upperMsg != LastMessage || (string.IsNullOrWhiteSpace(upperMsg) && message.Attachments.Any()))
- {
- LastMessage = upperMsg;
- Count = 0;
- }
- else
- {
- Count++;
+ lock(applyLock){
+ var upperMsg = message.Content.ToUpperInvariant();
+ if (upperMsg != LastMessage || (string.IsNullOrWhiteSpace(upperMsg) && message.Attachments.Any()))
+ {
+ LastMessage = upperMsg;
+ //todo c#7
+ Timer old;
+ while(timers.TryDequeue(out old))
+ old.Change(Timeout.Infinite, Timeout.Infinite);
+ }
+ var t = new Timer((_) => {
+ //todo c#7
+ Timer __;
+ if(timers.TryDequeue(out __))
+ __.Change(Timeout.Infinite, Timeout.Infinite);
+ }, null, TimeSpan.FromMinutes(30), TimeSpan.FromMinutes(30));
+ timers.Enqueue(t);
}
}
+
+ public void Dispose()
+ {
+ //todo c#7
+ Timer old;
+ while(timers.TryDequeue(out old))
+ old.Change(Timeout.Infinite, Timeout.Infinite);
+ }
}
[Group]
@@ -112,7 +135,7 @@ namespace NadekoBot.Modules.Administration
}))
return;
- var stats = spamSettings.UserStats.AddOrUpdate(msg.Author.Id, new UserSpamStats(msg.Content),
+ var stats = spamSettings.UserStats.AddOrUpdate(msg.Author.Id, (id) => new UserSpamStats(msg),
(id, old) =>
{
old.ApplyNextMessage(msg); return old;
@@ -122,6 +145,7 @@ namespace NadekoBot.Modules.Administration
{
if (spamSettings.UserStats.TryRemove(msg.Author.Id, out stats))
{
+ stats.Dispose();
await PunishUsers(spamSettings.AntiSpamSettings.Action, ProtectionType.Spamming, (IGuildUser)msg.Author)
.ConfigureAwait(false);
}
@@ -317,6 +341,7 @@ namespace NadekoBot.Modules.Administration
AntiSpamStats throwaway;
if (_antiSpamGuilds.TryRemove(Context.Guild.Id, out throwaway))
{
+ throwaway.UserStats.ForEach(x => x.Value.Dispose());
using (var uow = DbHandler.UnitOfWork())
{
var gc = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.AntiSpamSetting)
diff --git a/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs
index 727593df..71b90906 100644
--- a/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs
+++ b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs
@@ -108,7 +108,6 @@ namespace NadekoBot.Modules.Administration
using (var uow = DbHandler.UnitOfWork())
{
var roleModels = uow.SelfAssignedRoles.GetFromGuild(Context.Guild.Id).ToList();
- roleCnt = roleModels.Count;
msg.AppendLine();
foreach (var roleModel in roleModels)
@@ -116,11 +115,13 @@ namespace NadekoBot.Modules.Administration
var role = Context.Guild.Roles.FirstOrDefault(r => r.Id == roleModel.RoleId);
if (role == null)
{
+ toRemove.Add(roleModel);
uow.SelfAssignedRoles.Remove(roleModel);
}
else
{
msg.Append($"**{role.Name}**, ");
+ roleCnt++;
}
}
foreach (var role in toRemove)
diff --git a/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs b/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs
index f794d47a..f0189683 100644
--- a/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs
+++ b/src/NadekoBot/Modules/Administration/Commands/UserPunishCommands.cs
@@ -73,7 +73,7 @@ namespace NadekoBot.Modules.Administration
await guild.AddBanAsync(user).ConfigureAwait(false);
break;
case PunishmentAction.Softban:
- await guild.AddBanAsync(user).ConfigureAwait(false);
+ await guild.AddBanAsync(user, 7).ConfigureAwait(false);
try
{
await guild.RemoveBanAsync(user).ConfigureAwait(false);
@@ -214,25 +214,15 @@ namespace NadekoBot.Modules.Administration
using (var uow = DbHandler.UnitOfWork())
{
- var ps = uow.GuildConfigs.For(Context.Guild.Id).WarnPunishments;
- var p = ps.FirstOrDefault(x => x.Count == number);
+ var ps = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.WarnPunishments)).WarnPunishments;
+ ps.RemoveAll(x => x.Count == number);
- if (p == null)
+ ps.Add(new WarningPunishment()
{
- ps.Add(new WarningPunishment()
- {
- Count = number,
- Punishment = punish,
- Time = time,
- });
- }
- else
- {
- p.Count = number;
- p.Punishment = punish;
- p.Time = time;
- uow._context.Update(p);
- }
+ Count = number,
+ Punishment = punish,
+ Time = time,
+ });
uow.Complete();
}
diff --git a/src/NadekoBot/Modules/Gambling/Commands/WaifuClaimCommands.cs b/src/NadekoBot/Modules/Gambling/Commands/WaifuClaimCommands.cs
index a6fe9bb0..d5c78800 100644
--- a/src/NadekoBot/Modules/Gambling/Commands/WaifuClaimCommands.cs
+++ b/src/NadekoBot/Modules/Gambling/Commands/WaifuClaimCommands.cs
@@ -173,6 +173,8 @@ namespace NadekoBot.Modules.Gambling
amount + CurrencySign);
if (w.Affinity?.UserId == Context.User.Id)
msg += "\n" + GetText("waifu_fulfilled", target, w.Price + CurrencySign);
+ else
+ msg = " " + msg;
await Context.Channel.SendConfirmAsync(Context.User.Mention + msg).ConfigureAwait(false);
}
@@ -188,9 +190,15 @@ namespace NadekoBot.Modules.Gambling
private static readonly TimeSpan _divorceLimit = TimeSpan.FromHours(6);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
- public async Task Divorce([Remainder]IGuildUser target)
+ [Priority(1)]
+ public Task Divorce([Remainder]IGuildUser target) => Divorce(target.Id);
+
+ [NadekoCommand, Usage, Description, Aliases]
+ [RequireContext(ContextType.Guild)]
+ [Priority(0)]
+ public async Task Divorce([Remainder]ulong targetId)
{
- if (target.Id == Context.User.Id)
+ if (targetId == Context.User.Id)
return;
DivorceResult result;
@@ -199,7 +207,7 @@ namespace NadekoBot.Modules.Gambling
WaifuInfo w = null;
using (var uow = DbHandler.UnitOfWork())
{
- w = uow.Waifus.ByWaifuUserId(target.Id);
+ w = uow.Waifus.ByWaifuUserId(targetId);
var now = DateTime.UtcNow;
if (w?.Claimer == null || w.Claimer.UserId != Context.User.Id)
result = DivorceResult.NotYourWife;
diff --git a/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs b/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs
index 0f2f3bda..5c329925 100644
--- a/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs
+++ b/src/NadekoBot/Modules/Games/Commands/Hangman/HangmanGame.cs
@@ -15,7 +15,7 @@ namespace NadekoBot.Modules.Games.Hangman
{
public class HangmanTermPool
{
- const string termsPath = "data/hangman2.json";
+ const string termsPath = "data/hangman3.json";
public static IReadOnlyDictionary data { get; }
static HangmanTermPool()
{
diff --git a/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs b/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs
index bffa5624..640422f7 100644
--- a/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs
+++ b/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs
@@ -82,9 +82,9 @@ namespace NadekoBot.Modules.Games
var prefix = NadekoBot.ModulePrefixes[typeof(Games).Name];
var toSend = dropAmount == 1
? GetLocalText(channel, "curgen_sn", NadekoBot.BotConfig.CurrencySign)
- + GetLocalText(channel, "pick_sn", prefix)
+ + " " + GetLocalText(channel, "pick_sn", prefix)
: GetLocalText(channel, "curgen_pl", dropAmount, NadekoBot.BotConfig.CurrencySign)
- + GetLocalText(channel, "pick_pl", prefix);
+ + " " + GetLocalText(channel, "pick_pl", prefix);
var file = GetRandomCurrencyImage();
using (var fileStream = file.Value.ToStream())
{
diff --git a/src/NadekoBot/Modules/Music/Classes/Song.cs b/src/NadekoBot/Modules/Music/Classes/Song.cs
index cc105b4c..b7c16266 100644
--- a/src/NadekoBot/Modules/Music/Classes/Song.cs
+++ b/src/NadekoBot/Modules/Music/Classes/Song.cs
@@ -26,7 +26,11 @@ namespace NadekoBot.Modules.Music.Classes
{
public SongInfo SongInfo { get; }
public MusicPlayer MusicPlayer { get; set; }
- public string QueuerName { get; set; }
+
+ private string _queuerName;
+ public string QueuerName { get{
+ return Discord.Format.Sanitize(_queuerName);
+ } set { _queuerName = value; } }
public TimeSpan TotalTime { get; set; } = TimeSpan.Zero;
public TimeSpan CurrentTime => TimeSpan.FromSeconds(BytesSent / (float)_frameBytes / (1000 / (float)_milliseconds));
diff --git a/src/NadekoBot/Modules/Permissions/Commands/BlacklistCommands.cs b/src/NadekoBot/Modules/Permissions/Commands/BlacklistCommands.cs
index 4278d5a4..7cc8e62f 100644
--- a/src/NadekoBot/Modules/Permissions/Commands/BlacklistCommands.cs
+++ b/src/NadekoBot/Modules/Permissions/Commands/BlacklistCommands.cs
@@ -65,6 +65,9 @@ namespace NadekoBot.Modules.Permissions
private async Task Blacklist(AddRemove action, ulong id, BlacklistType type)
{
+ if(action == AddRemove.Add && NadekoBot.Credentials.OwnerIds.Contains(id))
+ return;
+
using (var uow = DbHandler.UnitOfWork())
{
if (action == AddRemove.Add)
diff --git a/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs b/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs
index 9eea8a50..fe2cf36d 100644
--- a/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs
+++ b/src/NadekoBot/Modules/Permissions/Commands/FilterCommands.cs
@@ -190,7 +190,7 @@ namespace NadekoBot.Modules.Permissions
{
var config = uow.GuildConfigs.For(channel.Guild.Id, set => set.Include(gc => gc.FilteredWords));
- removed = config.FilteredWords.RemoveWhere(fw => fw.Word == word);
+ removed = config.FilteredWords.RemoveWhere(fw => fw.Word.Trim().ToLowerInvariant() == word);
if (removed == 0)
config.FilteredWords.Add(new Services.Database.Models.FilteredWord() { Word = word });
diff --git a/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs b/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs
index 76722ad8..92abd1f3 100644
--- a/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs
+++ b/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs
@@ -126,7 +126,7 @@ namespace NadekoBot.Modules.Utility
}
await Context.Channel.EmbedAsync(new EmbedBuilder()
- .WithTitle(GetText("activity_page", page))
+ .WithTitle(GetText("activity_page", page + 1))
.WithOkColor()
.WithFooter(efb => efb.WithText(GetText("activity_users_total",
NadekoBot.CommandHandler.UserMessagesSent.Count)))
diff --git a/src/NadekoBot/Modules/Utility/Commands/Remind.cs b/src/NadekoBot/Modules/Utility/Commands/Remind.cs
index 8da05b89..4ffd9469 100644
--- a/src/NadekoBot/Modules/Utility/Commands/Remind.cs
+++ b/src/NadekoBot/Modules/Utility/Commands/Remind.cs
@@ -123,8 +123,19 @@ namespace NadekoBot.Modules.Utility
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.ManageMessages)]
[Priority(0)]
- public Task Remind(ITextChannel channel, string timeStr, [Remainder] string message) =>
- RemindInternal(channel.Id, false, timeStr, message);
+ public async Task Remind(ITextChannel channel, string timeStr, [Remainder] string message)
+ {
+ var perms = ((IGuildUser)Context.User).GetPermissions((ITextChannel)channel);
+ if (!perms.SendMessages || !perms.ReadMessages)
+ {
+ await ReplyErrorLocalized("cant_read_or_send").ConfigureAwait(false);
+ return;
+ }
+ else
+ {
+ var _ = RemindInternal(channel.Id, false, timeStr, message).ConfigureAwait(false);
+ }
+ }
public async Task RemindInternal(ulong targetId, bool isPrivate, string timeStr, [Remainder] string message)
{
diff --git a/src/NadekoBot/Modules/Utility/Utility.cs b/src/NadekoBot/Modules/Utility/Utility.cs
index 0b16da07..af782973 100644
--- a/src/NadekoBot/Modules/Utility/Utility.cs
+++ b/src/NadekoBot/Modules/Utility/Utility.cs
@@ -503,7 +503,6 @@ namespace NadekoBot.Modules.Utility
await JsonConvert.SerializeObject(grouping, Formatting.Indented).ToStream().ConfigureAwait(false), title, title).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
- [RequireContext(ContextType.Guild)]
public async Task Ping()
{
var sw = Stopwatch.StartNew();
diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx
index b2dceba7..2be9a8e3 100644
--- a/src/NadekoBot/Resources/CommandStrings.resx
+++ b/src/NadekoBot/Resources/CommandStrings.resx
@@ -418,7 +418,7 @@
iamnot iamn
- Removes a role to you that you choose. Role must be on a list of self-assignable roles.
+ Removes a specified role from you. Role must be on a list of self-assignable roles.
`{0}iamn Gamer`
@@ -2038,7 +2038,7 @@
chucknorris cn
- Shows a random Chuck Norris joke from <http://tambal.azurewebsites.net/joke/random>
+ Shows a random Chuck Norris joke from <http://api.icndb.com/jokes/random/>
`{0}cn`
@@ -3388,7 +3388,7 @@
shoprem shoprm
- Removes an item from the shop by its color.
+ Removes an item from the shop by its ID.
shop
@@ -3406,7 +3406,7 @@
Toggles whether this role is displayed in the sidebar or not.
- `{0}rh Guests` or `{0}rh "Space Wizards"
+ `{0}rh Guests` or `{0}rh "Space Wizards"`
buy
@@ -3442,19 +3442,19 @@
globalcommand gcmd
- Enables or disables a command from use on all servers.
+ Toggles whether a command can be used on any server.
- `{0}gcmd `
+ `{0}gcmd .stats`
globalmodule gmod
- Enable or disable a module from use on all servers.
+ Toggles whether a module can be used on any server.
- `{0}gmod nsfw disable`
+ `{0}gmod nsfw`
listglobalperms lgp
diff --git a/src/NadekoBot/data/hangman2.json b/src/NadekoBot/data/hangman3.json
similarity index 99%
rename from src/NadekoBot/data/hangman2.json
rename to src/NadekoBot/data/hangman3.json
index b93e6aa5..a671657f 100644
--- a/src/NadekoBot/data/hangman2.json
+++ b/src/NadekoBot/data/hangman3.json
@@ -772,7 +772,7 @@
},
{
"Word": "Antigua and Barbuda",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/antigua-and-barbuda.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/antigua_and_barbuda.gif"
},
{
"Word": "Argentina",
@@ -836,7 +836,7 @@
},
{
"Word": "Bosnia and Herzegovina",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/bosnia-and-herzegovina.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/bosnia_and_herzegovina.gif"
},
{
"Word": "Botswana",
@@ -856,7 +856,7 @@
},
{
"Word": "Burkina Faso",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/burkina-faso.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/burkina_faso.gif"
},
{
"Word": "Burma",
@@ -880,11 +880,11 @@
},
{
"Word": "Cape Verde",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/cape-verde.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/cape_verde.gif"
},
{
"Word": "Central African Republic",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/central-african-republic.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/central_african_republic.gif"
},
{
"Word": "Chad",
@@ -912,7 +912,7 @@
},
{
"Word": "Costa Rica",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/costa-rica.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/costa_rica.gif"
},
{
"Word": "Croatia",
@@ -928,7 +928,7 @@
},
{
"Word": "Czech Republic",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/czech-republic.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/czech_republic.gif"
},
{
"Word": "Denmark",
@@ -944,11 +944,11 @@
},
{
"Word": "Dominican Republic",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/dominican-republic.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/dominican_republic.gif"
},
{
"Word": "East Timor",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/east-timor.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/east_timor.gif"
},
{
"Word": "Ecuador",
@@ -960,7 +960,7 @@
},
{
"Word": "El Salvador",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/el-salvador.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/el_salvador.gif"
},
{
"Word": "England",
@@ -968,7 +968,7 @@
},
{
"Word": "Equatorial Guinea",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/equatorial-guinea.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/equatorial_guinea.gif"
},
{
"Word": "Eritrea",
@@ -1032,7 +1032,7 @@
},
{
"Word": "Guinea-Bissau",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/guinea-bissau.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/guinea_bissau.gif"
},
{
"Word": "Guyana",
@@ -1048,7 +1048,7 @@
},
{
"Word": "Hong Kong",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/hong-kong.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/hong_kong.gif"
},
{
"Word": "Hungary",
@@ -1080,7 +1080,7 @@
},
{
"Word": "Isle of Man",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/isle-of-man.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/isle_of_man.gif"
},
{
"Word": "Israel",
@@ -1116,11 +1116,11 @@
},
{
"Word": "North Korea",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/korea-north.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/korea_north.gif"
},
{
"Word": "South Korea",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/korea-south.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/korea_south.gif"
},
{
"Word": "Kosovo",
@@ -1204,7 +1204,7 @@
},
{
"Word": "Marshall Islands",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/marshall-islands.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/marshall_islands.gif"
},
{
"Word": "Mauritania",
@@ -1264,7 +1264,7 @@
},
{
"Word": "New Zealand",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/new-zealand.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/new_zealand.gif"
},
{
"Word": "Nicaragua",
@@ -1300,7 +1300,7 @@
},
{
"Word": "Papua New Guinea",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/papua-new-guinea.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/papua_new_guinea.gif"
},
{
"Word": "Paraguay",
@@ -1324,7 +1324,7 @@
},
{
"Word": "Puerto Rico",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/puerto-rico.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/puerto_rico.gif"
},
{
"Word": "Qatar",
@@ -1344,15 +1344,15 @@
},
{
"Word": "Saint Kitts and Nevis",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/saint-kitts-and-nevis.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/saint_kitts_and_nevis.gif"
},
{
"Word": "Saint Lucia",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/saint-lucia.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/saint_lucia.gif"
},
{
"Word": "Saint Vincent and the Grenadines",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/saint-vincent-and-the-grenadines.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/saint_vincent_and_the_grenadines.gif"
},
{
"Word": "Samoa",
@@ -1360,11 +1360,11 @@
},
{
"Word": "San Marino",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/san-marino.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/san_marino.gif"
},
{
"Word": "Saudi Arabia",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/saudi-arabia.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/saudi_arabia.gif"
},
{
"Word": "Scotland",
@@ -1384,7 +1384,7 @@
},
{
"Word": "Sierra Leone",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/sierra-leone.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/sierra_leone.gif"
},
{
"Word": "Singapore",
@@ -1400,7 +1400,7 @@
},
{
"Word": "Solomon Islands",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/solomon-islands.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/solomon_islands.gif"
},
{
"Word": "Somalia",
@@ -1408,7 +1408,7 @@
},
{
"Word": "South Africa",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/south-africa.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/south_africa.gif"
},
{
"Word": "Spain",
@@ -1416,7 +1416,7 @@
},
{
"Word": "Sri Lanka",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/sri-lanka.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/sri_lanka.gif"
},
{
"Word": "Sudan",
@@ -1468,7 +1468,7 @@
},
{
"Word": "Trinidad and Tobago",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/trinidad-and-tobago.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/trinidad_and_tobago.gif"
},
{
"Word": "Tunisia",
@@ -1496,15 +1496,15 @@
},
{
"Word": "United Arab Emirates",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/united-arab-emirates.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/united_arab_emirates.gif"
},
{
"Word": "United Kingdom",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/united-kingdom.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/united_kingdom.gif"
},
{
"Word": "United States of America",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/united-states-of-america.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/united_states_of_america.gif"
},
{
"Word": "Uruguay",
@@ -1524,7 +1524,7 @@
},
{
"Word": "Vatican City",
- "ImageUrl": "https://www.randomlists.com/img/national-flags/vatican-city.gif"
+ "ImageUrl": "https://www.randomlists.com/img/national-flags/vatican_city.gif"
},
{
"Word": "Venezuela",