This commit is contained in:
Kwoth
2016-11-09 16:50:40 +01:00
20 changed files with 638 additions and 108 deletions

View File

@@ -311,7 +311,8 @@ namespace NadekoBot.Modules.Administration
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequirePermission(GuildPermission.BanMembers)]
[RequirePermission(GuildPermission.KickMembers)]
[RequirePermission(GuildPermission.ManageMessages)]
public async Task Softban(IUserMessage umsg, IGuildUser user, [Remainder] string msg = null)
{
var channel = (ITextChannel)umsg.Channel;

View File

@@ -80,7 +80,7 @@ namespace NadekoBot.Modules.Administration
{
var firstOwnerChannel = ownerChannels.First();
if (firstOwnerChannel.Recipient.Id != msg.Author.Id)
try { await firstOwnerChannel.SendMessageAsync(msg.Content).ConfigureAwait(false); } catch { }
try { await firstOwnerChannel.SendMessageAsync(toSend).ConfigureAwait(false); } catch { }
}
}
}

View File

@@ -384,7 +384,7 @@ namespace NadekoBot.Modules.Administration
👤`{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);
await logChannel.SendMessageAsync(str.SanitizeMentions()).ConfigureAwait(false);
}
catch (Exception ex) { _log.Warn(ex); }
});
@@ -421,8 +421,8 @@ namespace NadekoBot.Modules.Administration
{
try { await logChannel.SendMessageAsync($@"🕔`{prettyCurrentTime}` **Message** 📝 `#{channel.Name}`
👤`{before.Author.Username}`
`Old:` {before.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator)}
`New:` {after.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator)}").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
`Old:` {before.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator).SanitizeMentions()}
`New:` {after.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator).SanitizeMentions()}").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
});
return Task.CompletedTask;

View File

@@ -159,7 +159,7 @@ namespace NadekoBot.Modules.Administration
return old;
});
await channel.SendMessageAsync($"Repeating \"{rep.Repeater.Message}\" every {rep.Repeater.Interval} minutes").ConfigureAwait(false);
await channel.SendMessageAsync($"Repeating \"{rep.Repeater.Message}\" every {rep.Repeater.Interval.Days} days, {rep.Repeater.Interval.Hours} hours and {rep.Repeater.Interval.Minutes} minutes.").ConfigureAwait(false);
}
}
}

View File

@@ -114,7 +114,7 @@ namespace NadekoBot.Modules.Administration
var channel = (ITextChannel)msg.Channel;
var guild = channel.Guild;
var botUser = guild.GetCurrentUser();
var botUser = await guild.GetCurrentUserAsync().ConfigureAwait(false);
if (!botUser.GuildPermissions.ManageRoles || !botUser.GuildPermissions.ManageChannels)
{
await channel.SendMessageAsync(":anger: `I require atleast manage roles and manage channels permissions to enable this feature (preffered Administration permission).`");
@@ -166,7 +166,8 @@ namespace NadekoBot.Modules.Administration
{
var channel = (ITextChannel)msg.Channel;
var guild = channel.Guild;
if (!guild.GetCurrentUser().GuildPermissions.Administrator)
var botUser = await guild.GetCurrentUserAsync().ConfigureAwait(false);
if (!botUser.GuildPermissions.Administrator)
{
await channel.SendMessageAsync("`I need Administrator permission to do that.`").ConfigureAwait(false);
return;

View File

@@ -19,6 +19,7 @@ namespace NadekoBot.Modules.CustomReactions
{
public static ConcurrentHashSet<CustomReaction> GlobalReactions { get; } = new ConcurrentHashSet<CustomReaction>();
public static ConcurrentDictionary<ulong, ConcurrentHashSet<CustomReaction>> GuildReactions { get; } = new ConcurrentDictionary<ulong, ConcurrentHashSet<CustomReaction>>();
static CustomReactions()
{
using (var uow = DbHandler.UnitOfWork())
@@ -30,49 +31,43 @@ namespace NadekoBot.Modules.CustomReactions
}
public CustomReactions(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client)
{
client.MessageReceived += (imsg) =>
}
public static async Task<bool> TryExecuteCustomReaction(IUserMessage umsg)
{
var channel = umsg.Channel as ITextChannel;
if (channel == null)
return false;
var content = umsg.Content.Trim().ToLowerInvariant();
ConcurrentHashSet<CustomReaction> reactions;
GuildReactions.TryGetValue(channel.Guild.Id, out reactions);
if (reactions != null && reactions.Any())
{
var umsg = imsg as IUserMessage;
if (umsg == null || imsg.Author.IsBot)
return Task.CompletedTask;
var channel = umsg.Channel as ITextChannel;
if (channel == null)
return Task.CompletedTask;
var t = Task.Run(async () =>
var reaction = reactions.Where(cr => {
var hasTarget = cr.Response.ToLowerInvariant().Contains("%target%");
var trigger = cr.TriggerWithContext(umsg).Trim().ToLowerInvariant();
return ((hasTarget && content.StartsWith(trigger + " ")) || content == trigger);
}).Shuffle().FirstOrDefault();
if (reaction != null)
{
var content = umsg.Content.Trim().ToLowerInvariant();
ConcurrentHashSet<CustomReaction> reactions;
GuildReactions.TryGetValue(channel.Guild.Id, out reactions);
if (reactions != null && reactions.Any())
{
var reaction = reactions.Where(cr => {
var hasTarget = cr.Response.ToLowerInvariant().Contains("%target%");
var trigger = cr.TriggerWithContext(umsg).Trim().ToLowerInvariant();
return ((hasTarget && content.StartsWith(trigger + " ")) || content == trigger);
}).Shuffle().FirstOrDefault();
if (reaction != null)
{
try { await channel.SendMessageAsync(reaction.ResponseWithContext(umsg)).ConfigureAwait(false); } catch { }
return;
}
}
var greaction = GlobalReactions.Where(cr =>
{
var hasTarget = cr.Response.ToLowerInvariant().Contains("%target%");
var trigger = cr.TriggerWithContext(umsg).Trim().ToLowerInvariant();
return ((hasTarget && content.StartsWith(trigger + " ")) || content == trigger);
}).Shuffle().FirstOrDefault();
try { await channel.SendMessageAsync(reaction.ResponseWithContext(umsg)).ConfigureAwait(false); } catch { }
return true;
}
}
var greaction = GlobalReactions.Where(cr =>
{
var hasTarget = cr.Response.ToLowerInvariant().Contains("%target%");
var trigger = cr.TriggerWithContext(umsg).Trim().ToLowerInvariant();
return ((hasTarget && content.StartsWith(trigger + " ")) || content == trigger);
}).Shuffle().FirstOrDefault();
if (greaction != null)
{
try { await channel.SendMessageAsync(greaction.ResponseWithContext(umsg)).ConfigureAwait(false); } catch { }
return;
}
});
return Task.CompletedTask;
};
if (greaction != null)
{
try { await channel.SendMessageAsync(greaction.ResponseWithContext(umsg)).ConfigureAwait(false); } catch { }
return true;
}
return false;
}
[NadekoCommand, Usage, Description, Aliases]

View File

@@ -218,6 +218,47 @@ namespace NadekoBot.Modules.Games
await channel.SendMessageAsync("Added new article for typing game.").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Typelist(IUserMessage imsg, int page = 1)
{
var channel = (ITextChannel)imsg.Channel;
if (page < 1)
return;
var articles = TypingArticles.Skip((page - 1) * 15).Take(15);
if (!articles.Any())
{
await channel.SendMessageAsync($"{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)}")))
.ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[OwnerOnly]
public async Task Typedel(IUserMessage imsg, int index)
{
var channel = (ITextChannel)imsg.Channel;
index -= 1;
if (index < 0 || index >= TypingArticles.Count)
return;
var removed = TypingArticles[index];
TypingArticles.RemoveAt(index);
File.WriteAllText(typingArticlesPath, JsonConvert.SerializeObject(TypingArticles));
await channel.SendMessageAsync($"`Removed typing article:` #{index + 1} - {removed.Text.TrimTo(50)}")
.ConfigureAwait(false);
}
}
}
}

View File

@@ -38,14 +38,23 @@ namespace NadekoBot.Modules.Music
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public Task Next(IUserMessage umsg)
public Task Next(IUserMessage umsg, int skipCount = 1)
{
var channel = (ITextChannel)umsg.Channel;
if (skipCount < 1)
return Task.CompletedTask;
MusicPlayer musicPlayer;
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return Task.CompletedTask;
if (musicPlayer.PlaybackVoiceChannel == ((IGuildUser)umsg.Author).VoiceChannel)
{
while (--skipCount > 0)
{
musicPlayer.RemoveSongAt(0);
}
musicPlayer.Next();
}
return Task.CompletedTask;
}

View File

@@ -30,17 +30,71 @@ namespace NadekoBot.Modules.NSFW
tag = tag?.Trim() ?? "";
var links = await Task.WhenAll(GetGelbooruImageLink("rating%3Aexplicit+" + tag), GetDanbooruImageLink("rating%3Aexplicit+" + tag)).ConfigureAwait(false);
tag = "rating%3Aexplicit+" + tag;
var rng = new NadekoRandom();
Task<string> provider = Task.FromResult("");
switch (rng.Next(0,4))
{
case 0:
provider = GetDanbooruImageLink(tag);
break;
case 1:
provider = GetGelbooruImageLink(tag);
break;
case 2:
provider = GetATFbooruImageLink(tag);
break;
case 3:
provider = GetKonachanImageLink(tag);
break;
default:
break;
}
var link = await provider.ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(link))
await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false);
else
await channel.SendMessageAsync(link).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task HentaiBomb(IUserMessage umsg, [Remainder] string tag = null)
{
var channel = (ITextChannel)umsg.Channel;
tag = tag?.Trim() ?? "";
tag = "rating%3Aexplicit+" + tag;
var links = await Task.WhenAll(GetGelbooruImageLink(tag),
GetDanbooruImageLink(tag),
GetKonachanImageLink(tag),
GetATFbooruImageLink(tag)).ConfigureAwait(false);
if (links.All(l => l == null))
{
await channel.SendMessageAsync("`No results.`");
await channel.SendMessageAsync("`No results.`").ConfigureAwait(false);
return;
}
await channel.SendMessageAsync(String.Join("\n\n", links)).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task ATFbooru(IUserMessage umsg, [Remainder] string tag = null)
{
var channel = (ITextChannel)umsg.Channel;
tag = tag?.Trim() ?? "";
var link = await GetATFbooruImageLink(tag).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(link))
await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false);
else
await channel.SendMessageAsync(link).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Danbooru(IUserMessage umsg, [Remainder] string tag = null)
@@ -50,7 +104,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 ;(");
await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false);
else
await channel.SendMessageAsync(link).ConfigureAwait(false);
}
@@ -64,7 +118,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 ;(");
await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false);
else
await channel.SendMessageAsync(link).ConfigureAwait(false);
}
@@ -78,7 +132,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 ;(");
await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false);
else
await channel.SendMessageAsync(link).ConfigureAwait(false);
}
@@ -92,7 +146,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 ;(");
await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false);
else
await channel.SendMessageAsync(link).ConfigureAwait(false);
}
@@ -106,7 +160,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 ;(");
await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false);
else
await channel.SendMessageAsync(link).ConfigureAwait(false);
}
@@ -176,7 +230,7 @@ namespace NadekoBot.Modules.NSFW
if (matches.Count == 0)
return null;
return await NadekoBot.Google.ShortenUrl(matches[rng.Next(0, matches.Count)].Groups["ll"].Value).ConfigureAwait(false);
return matches[rng.Next(0, matches.Count)].Groups["ll"].Value;
}
}
@@ -255,5 +309,25 @@ namespace NadekoBot.Modules.NSFW
return "Error, do you have too many tags?";
}
}
public static async Task<string> GetATFbooruImageLink(string tag)
{
var rng = new NadekoRandom();
var link = $"https://atfbooru.ninja/posts?" +
$"limit=100";
if (!string.IsNullOrWhiteSpace(tag))
link += $"&tags={tag.Replace(" ", "+")}";
using (var http = new HttpClient())
{
var webpage = await http.GetStringAsync(link).ConfigureAwait(false);
var matches = Regex.Matches(webpage, "data-file-url=\"(?<id>.*?)\"");
if (matches.Count == 0)
return null;
return $"https://atfbooru.ninja" +
$"{matches[rng.Next(0, matches.Count)].Groups["id"].Value}";
}
}
}
}

View File

@@ -80,7 +80,7 @@ namespace NadekoBot.Modules.Permissions
}
await uow.CompleteAsync().ConfigureAwait(false);
}
if (action == AddRemove.Rem)
if (action == AddRemove.Add)
{
TriviaGame tg;
switch (type)

View File

@@ -58,7 +58,7 @@ namespace NadekoBot.Modules.Searches
{
if (i % 2 == 0 && i != 0)
sb.AppendLine();
sb.Append($"`{i + 1}.` **{dataList[i]["name"]}** ");
sb.Append($"`{i + 1}.` **{dataList[i]["name"]}** {dataList[i]["general"]["banRate"]}% ");
//sb.AppendLine($" ({dataList[i]["general"]["banRate"]}%)");
}
@@ -67,7 +67,7 @@ namespace NadekoBot.Modules.Searches
}
catch (Exception)
{
await channel.SendMessageAsync($":anger: Fail: Champion.gg didsabled ban data until next patch. Sorry for the inconvenience.").ConfigureAwait(false);
await channel.SendMessageAsync($":anger: `Something went wrong.`").ConfigureAwait(false);
}
}
}

View File

@@ -4,6 +4,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using System.Text;
using System.Net.Http;
using NadekoBot.Services;
using System.Threading.Tasks;
@@ -271,7 +272,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
try
{
var items = JObject.Parse(res);
var sb = new System.Text.StringBuilder();
var sb = new StringBuilder();
sb.AppendLine($"`Term:` {items["list"][0]["word"].ToString()}");
sb.AppendLine($"`Definition:` {items["list"][0]["definition"].ToString()}");
sb.Append($"`Link:` <{await _google.ShortenUrl(items["list"][0]["permalink"].ToString()).ConfigureAwait(false)}>");
@@ -463,6 +464,118 @@ $@"🌍 **Weather for** 【{obj["target"]}】
return matches[rng.Next(0, matches.Count)].Groups["url"].Value;
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Wikia(IUserMessage umsg, string targ, [Remainder] string query = null)
{
var channel = (ITextChannel)umsg.Channel;
var arg = query;
if (string.IsNullOrWhiteSpace(targ) || string.IsNullOrWhiteSpace(arg))
{
await channel.SendMessageAsync("💢 Please enter `target query`.").ConfigureAwait(false);
return;
}
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
string target = targ;
string search = arg;
try
{
var res = await http.GetStringAsync($"http://www.{Uri.EscapeUriString(target)}.wikia.com/api/v1/Search/List?query={Uri.EscapeUriString(search)}&limit=25&minArticleQuality=10&batch=1&namespaces=0%2C14").ConfigureAwait(false);
var items = JObject.Parse(res);
var sb = new StringBuilder();
sb.AppendLine($"`Found:` {items["items"][0]["title"].ToString()}");
sb.AppendLine($"`Total Found:` {items["total"].ToString()}");
sb.AppendLine($"`Batch:` {items["currentBatch"].ToString()}/{items["batches"].ToString()}");
sb.Append($"`URL:` <{await _google.ShortenUrl(items["items"][0]["url"].ToString()).ConfigureAwait(false)}> / `Quality`: {items["items"][0]["quality"].ToString()}");
await channel.SendMessageAsync(sb.ToString());
}
catch
{
await channel.SendMessageAsync($"💢 Failed finding `{arg}`.").ConfigureAwait(false);
}
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task MCPing(IUserMessage umsg, [Remainder] string query = null)
{
var channel = (ITextChannel)umsg.Channel;
var arg = query;
if (string.IsNullOrWhiteSpace(arg))
{
await channel.SendMessageAsync("💢 Please enter a `ip:port`.").ConfigureAwait(false);
return;
}
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
string ip = arg.Split(':')[0];
string port = arg.Split(':')[1];
var res = await http.GetStringAsync($"https://api.minetools.eu/ping/{Uri.EscapeUriString(ip)}/{Uri.EscapeUriString(port)}").ConfigureAwait(false);
try
{
var items = JObject.Parse(res);
var sb = new StringBuilder();
int ping = (int)Math.Ceiling(Double.Parse(items["latency"].ToString()));
sb.AppendLine($"`Server:` {arg}");
sb.AppendLine($"`Version:` {items["version"]["name"].ToString()} / Protocol {items["version"]["protocol"].ToString()}");
sb.AppendLine($"`Description:` {items["description"].ToString()}");
sb.AppendLine($"`Online Players:` {items["players"]["online"].ToString()}/{items["players"]["max"].ToString()}");
sb.Append($"`Latency:` {ping}");
await channel.SendMessageAsync(sb.ToString());
}
catch
{
await channel.SendMessageAsync($"💢 Failed finding `{arg}`.").ConfigureAwait(false);
}
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task MCQ(IUserMessage umsg, [Remainder] string query = null)
{
var channel = (ITextChannel)umsg.Channel;
var arg = query;
if (string.IsNullOrWhiteSpace(arg))
{
await channel.SendMessageAsync("💢 Please enter a `ip:port`.").ConfigureAwait(false);
return;
}
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
try
{
string ip = arg.Split(':')[0];
string port = arg.Split(':')[1];
var res = await http.GetStringAsync($"https://api.minetools.eu/query/{Uri.EscapeUriString(ip)}/{Uri.EscapeUriString(port)}").ConfigureAwait(false);
var items = JObject.Parse(res);
var sb = new StringBuilder();
sb.AppendLine($"`Server:` {arg.ToString()} 〘Status: {items["status"]}〙");
sb.AppendLine($"`Player List (First 5):`");
foreach (var item in items["Playerlist"].Take(5))
{
sb.AppendLine($":rosette: {item}");
}
sb.AppendLine($"`Online Players:` {items["Players"]} / {items["MaxPlayers"]}");
sb.AppendLine($"`Plugins:` {items["Plugins"]}");
sb.Append($"`Version:` {items["Version"]}");
await channel.SendMessageAsync(sb.ToString());
}
catch
{
await channel.SendMessageAsync($"💢 Failed finding server `{arg}`.").ConfigureAwait(false);
}
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]

View File

@@ -169,14 +169,35 @@ namespace NadekoBot.Modules.Utility
{
var matches = emojiFinder.Matches(emojis);
var result = string.Join("\n", matches.Cast<Match>()
.Select(m => $"`Name:` {m.Groups["name"]} `Link:` http://discordapp.com/api/emojis/{m.Groups["id"]}.png"));
await msg.Channel.SendMessageAsync(result).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[OwnerOnly]
public async Task ListServers(IUserMessage imsg, int page = 1)
{
var channel = (ITextChannel)imsg.Channel;
page -= 1;
if (page < 0)
return;
var guilds = NadekoBot.Client.GetGuilds().OrderBy(g => g.Name).Skip((page - 1) * 15).Take(15);
if (!guilds.Any())
{
await channel.SendMessageAsync("`No servers found on that page.`").ConfigureAwait(false);
return;
}
await channel.SendMessageAsync(String.Join("\n", guilds.Select(g => $"`Name:` {g.Name} `Id:` {g.Id} `Members:` {g.GetUsers().Count} `OwnerId:`{g.OwnerId}"))).ConfigureAwait(false);
}
//[NadekoCommand, Usage, Description, Aliases]
//[RequireContext(ContextType.Guild)]
//public async Task TextToImage(IUserMessage msg, [Remainder] string arg)