reworked music controls, prune fix, cleanup, other fixes

This commit is contained in:
Master Kwoth 2016-01-31 19:51:27 +01:00
parent 40b64407f2
commit e869972127
7 changed files with 105 additions and 139 deletions

View File

@ -23,7 +23,6 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
FullDebug|Any CPU = FullDebug|Any CPU FullDebug|Any CPU = FullDebug|Any CPU
PRIVATE|Any CPU = PRIVATE|Any CPU
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
@ -31,40 +30,30 @@ Global
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Debug|Any CPU.Build.0 = Debug|Any CPU {27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Debug|Any CPU.Build.0 = Debug|Any CPU
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU {27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.FullDebug|Any CPU.Build.0 = Debug|Any CPU {27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.PRIVATE|Any CPU.ActiveCfg = PRIVATE|Any CPU
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.PRIVATE|Any CPU.Build.0 = PRIVATE|Any CPU
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Release|Any CPU.ActiveCfg = Release|Any CPU {27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Release|Any CPU.ActiveCfg = Release|Any CPU
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Release|Any CPU.Build.0 = Release|Any CPU {27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Release|Any CPU.Build.0 = Release|Any CPU
{8D71A857-879A-4A10-859E-5FF824ED6688}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8D71A857-879A-4A10-859E-5FF824ED6688}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8D71A857-879A-4A10-859E-5FF824ED6688}.Debug|Any CPU.Build.0 = Debug|Any CPU {8D71A857-879A-4A10-859E-5FF824ED6688}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8D71A857-879A-4A10-859E-5FF824ED6688}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU {8D71A857-879A-4A10-859E-5FF824ED6688}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
{8D71A857-879A-4A10-859E-5FF824ED6688}.FullDebug|Any CPU.Build.0 = Debug|Any CPU {8D71A857-879A-4A10-859E-5FF824ED6688}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
{8D71A857-879A-4A10-859E-5FF824ED6688}.PRIVATE|Any CPU.ActiveCfg = TestResponses|Any CPU
{8D71A857-879A-4A10-859E-5FF824ED6688}.PRIVATE|Any CPU.Build.0 = TestResponses|Any CPU
{8D71A857-879A-4A10-859E-5FF824ED6688}.Release|Any CPU.ActiveCfg = Release|Any CPU {8D71A857-879A-4A10-859E-5FF824ED6688}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8D71A857-879A-4A10-859E-5FF824ED6688}.Release|Any CPU.Build.0 = Release|Any CPU {8D71A857-879A-4A10-859E-5FF824ED6688}.Release|Any CPU.Build.0 = Release|Any CPU
{3091164F-66AE-4543-A63D-167C1116241D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3091164F-66AE-4543-A63D-167C1116241D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3091164F-66AE-4543-A63D-167C1116241D}.Debug|Any CPU.Build.0 = Debug|Any CPU {3091164F-66AE-4543-A63D-167C1116241D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3091164F-66AE-4543-A63D-167C1116241D}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU {3091164F-66AE-4543-A63D-167C1116241D}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
{3091164F-66AE-4543-A63D-167C1116241D}.FullDebug|Any CPU.Build.0 = Debug|Any CPU {3091164F-66AE-4543-A63D-167C1116241D}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
{3091164F-66AE-4543-A63D-167C1116241D}.PRIVATE|Any CPU.ActiveCfg = Release|Any CPU
{3091164F-66AE-4543-A63D-167C1116241D}.PRIVATE|Any CPU.Build.0 = Release|Any CPU
{3091164F-66AE-4543-A63D-167C1116241D}.Release|Any CPU.ActiveCfg = Release|Any CPU {3091164F-66AE-4543-A63D-167C1116241D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3091164F-66AE-4543-A63D-167C1116241D}.Release|Any CPU.Build.0 = Release|Any CPU {3091164F-66AE-4543-A63D-167C1116241D}.Release|Any CPU.Build.0 = Release|Any CPU
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1B5603B4-6F8F-4289-B945-7BAAE523D740}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Debug|Any CPU.Build.0 = Debug|Any CPU {1B5603B4-6F8F-4289-B945-7BAAE523D740}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU {1B5603B4-6F8F-4289-B945-7BAAE523D740}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.FullDebug|Any CPU.Build.0 = Debug|Any CPU {1B5603B4-6F8F-4289-B945-7BAAE523D740}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.PRIVATE|Any CPU.ActiveCfg = Release|Any CPU
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.PRIVATE|Any CPU.Build.0 = Release|Any CPU
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Release|Any CPU.ActiveCfg = Release|Any CPU {1B5603B4-6F8F-4289-B945-7BAAE523D740}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Release|Any CPU.Build.0 = Release|Any CPU {1B5603B4-6F8F-4289-B945-7BAAE523D740}.Release|Any CPU.Build.0 = Release|Any CPU
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Debug|Any CPU.Build.0 = Debug|Any CPU {7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU {7BFEF748-B934-4621-9B11-6302E3A9F6B3}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.FullDebug|Any CPU.Build.0 = Debug|Any CPU {7BFEF748-B934-4621-9B11-6302E3A9F6B3}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.PRIVATE|Any CPU.ActiveCfg = Release|Any CPU
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.PRIVATE|Any CPU.Build.0 = Release|Any CPU
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Release|Any CPU.ActiveCfg = Release|Any CPU {7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Release|Any CPU.Build.0 = Release|Any CPU {7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection

View File

@ -9,15 +9,17 @@ namespace NadekoBot.Classes.Music {
public class MusicControls { public class MusicControls {
public bool NextSong = false; public bool NextSong = false;
public IAudioClient Voice; public IAudioClient Voice;
public Channel VoiceChannel;
public bool Pause = false; public bool Pause = false;
public List<StreamRequest> SongQueue = new List<StreamRequest>(); public List<StreamRequest> SongQueue = new List<StreamRequest>();
public StreamRequest CurrentSong; public StreamRequest CurrentSong = null;
public bool IsPaused { get; internal set; } = false; public bool IsPaused { get; internal set; } = false;
public bool Stopped { get; private set; } public bool Stopped { get; private set; }
public IAudioClient VoiceClient; public Channel VoiceChannel;
public IAudioClient VoiceClient = null;
private readonly object _voiceLock = new object(); private readonly object _voiceLock = new object();
@ -27,12 +29,13 @@ namespace NadekoBot.Classes.Music {
lock (_voiceLock) { lock (_voiceLock) {
if (CurrentSong == null) { if (CurrentSong == null) {
if (SongQueue.Count > 0) if (SongQueue.Count > 0)
LoadNextSong(); LoadNextSong().Wait();
} else if (CurrentSong.State == StreamState.Completed || NextSong) { } else if (CurrentSong.State == StreamState.Completed || NextSong) {
NextSong = false; NextSong = false;
LoadNextSong(); LoadNextSong().Wait();
} }
} }
await Task.Delay(1000); await Task.Delay(1000);
} }
@ -43,22 +46,24 @@ namespace NadekoBot.Classes.Music {
VoiceChannel = voiceChannel; VoiceChannel = voiceChannel;
} }
public void LoadNextSong() { public async Task LoadNextSong() {
lock (_voiceLock) { CurrentSong?.Stop();
CurrentSong?.Stop(); CurrentSong = null;
CurrentSong = null; if (SongQueue.Count != 0) {
if (SongQueue.Count != 0) { CurrentSong = SongQueue[0];
CurrentSong = SongQueue[0]; SongQueue.RemoveAt(0);
SongQueue.RemoveAt(0); } else {
} else { VoiceClient?.Disconnect();
VoiceClient?.Disconnect(); VoiceClient = null;
VoiceClient = null; return;
return;
}
} }
try { try {
CurrentSong?.Start(); if (VoiceChannel == null)
VoiceChannel = CurrentSong.Channel;
if (VoiceClient == null)
VoiceClient = await NadekoBot.client.Audio().Join(VoiceChannel);
await CurrentSong.Start();
} catch (Exception ex) { } catch (Exception ex) {
Console.WriteLine($"Starting failed: {ex}"); Console.WriteLine($"Starting failed: {ex}");
CurrentSong?.Stop(); CurrentSong?.Stop();
@ -69,7 +74,7 @@ namespace NadekoBot.Classes.Music {
lock (_voiceLock) { lock (_voiceLock) {
Stopped = true; Stopped = true;
foreach (var kvp in SongQueue) { foreach (var kvp in SongQueue) {
if(kvp != null) if (kvp != null)
kvp.Stop(); kvp.Stop();
} }
SongQueue.Clear(); SongQueue.Clear();
@ -80,22 +85,6 @@ namespace NadekoBot.Classes.Music {
} }
} }
internal async Task<StreamRequest> CreateStreamRequest(CommandEventArgs e, string query, Channel voiceChannel) {
if (VoiceChannel == null)
throw new ArgumentNullException("Please join a voicechannel.");
StreamRequest sr = null;
if (VoiceClient == null) {
VoiceChannel = voiceChannel;
VoiceClient = await NadekoBot.client.Audio().Join(VoiceChannel);
}
sr = new StreamRequest(e, query, this);
lock (_voiceLock) {
SongQueue.Add(sr);
}
return sr;
}
internal bool TogglePause() => IsPaused = !IsPaused; internal bool TogglePause() => IsPaused = !IsPaused;
} }
} }

View File

@ -30,7 +30,6 @@ namespace NadekoBot.Classes.Music {
public string Query { get; } public string Query { get; }
public string Title { get; internal set; } = String.Empty; public string Title { get; internal set; } = String.Empty;
public IAudioClient VoiceClient { get; private set; }
private MusicStreamer musicStreamer = null; private MusicStreamer musicStreamer = null;
public StreamState State => musicStreamer?.State ?? privateState; public StreamState State => musicStreamer?.State ?? privateState;
@ -38,23 +37,22 @@ namespace NadekoBot.Classes.Music {
public bool IsPaused => MusicControls.IsPaused; public bool IsPaused => MusicControls.IsPaused;
private MusicControls MusicControls; public MusicControls MusicControls;
public StreamRequest(CommandEventArgs e, string query, MusicControls mc) { public StreamRequest(CommandEventArgs e, string query, MusicControls mc) {
if (e == null) if (e == null)
throw new ArgumentNullException(nameof(e)); throw new ArgumentNullException(nameof(e));
if (query == null) if (query == null)
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
if (mc.VoiceClient == null)
throw new NullReferenceException($"{nameof(mc.VoiceClient)} is null, bot didn't join any server.");
this.MusicControls = mc; this.MusicControls = mc;
this.VoiceClient = mc.VoiceClient;
this.Server = e.Server; this.Server = e.Server;
this.Query = query; this.Query = query;
Task.Run(async () => await ResolveStreamLink()); Task.Run(() => ResolveStreamLink());
Console.WriteLine("6");
mc.SongQueue.Add(this);
} }
private async Task ResolveStreamLink() { private void ResolveStreamLink() {
VideoInfo video = null; VideoInfo video = null;
try { try {
if (OnResolving != null) if (OnResolving != null)
@ -165,7 +163,6 @@ namespace NadekoBot.Classes.Music {
Arguments = $"-i {Url} -f s16le -ar 48000 -ac 2 pipe:1", Arguments = $"-i {Url} -f s16le -ar 48000 -ac 2 pipe:1",
UseShellExecute = false, UseShellExecute = false,
RedirectStandardOutput = true, RedirectStandardOutput = true,
RedirectStandardError = false,
CreateNoWindow = true, CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden, WindowStyle = ProcessWindowStyle.Hidden,
}); });
@ -282,13 +279,13 @@ namespace NadekoBot.Classes.Music {
break; break;
} }
parent.VoiceClient.Send(voiceBuffer, 0, voiceBuffer.Length); parent.MusicControls.VoiceClient.Send(voiceBuffer, 0, voiceBuffer.Length);
while (IsPaused) { while (IsPaused) {
await Task.Delay(50); await Task.Delay(50);
} }
} }
parent.VoiceClient.Wait(); parent.MusicControls.VoiceClient.Wait();
Stop(); Stop();
} }

View File

@ -13,8 +13,8 @@ using System.IO;
namespace NadekoBot.Modules { namespace NadekoBot.Modules {
class Administration : DiscordModule { class Administration : DiscordModule {
public Administration() : base() { public Administration() : base() {
commands.Add(new HelpCommand()); // commands.Add(new HelpCommand());
commands.Add(new ServerGreetCommand()); // commands.Add(new ServerGreetCommand());
} }
public override void Install(ModuleManager manager) { public override void Install(ModuleManager manager) {
@ -381,18 +381,12 @@ namespace NadekoBot.Modules {
return; return;
} }
try { try {
var msgs = await e.Channel.DownloadMessages(100); Message last = null;
var lastmessage = e.Channel.Messages.LastOrDefault(); while (num > 0) {
while (num > 0 && lastmessage != null) { var msgs = await e.Channel.DownloadMessages(num, last?.Id);
last = msgs.LastOrDefault();
msgs.ForEach(async m => await m.Delete()); msgs.ForEach(async m => await m.Delete());
int toDelete; num -= 100;
if (num > 100)
toDelete = 100;
else
toDelete = num;
num -= toDelete;
lastmessage = msgs.LastOrDefault();
msgs = await e.Channel.DownloadMessages(toDelete, lastmessage?.Id);
} }
} catch (Exception) { await e.Send("Failed pruning. Make sure the bot has correct permissions."); } } catch (Exception) { await e.Send("Failed pruning. Make sure the bot has correct permissions."); }

View File

@ -372,7 +372,17 @@ namespace NadekoBot.Modules {
await e.Send($"Got invites for {i} servers and failed to get invites for {j} servers"); await e.Send($"Got invites for {i} servers and failed to get invites for {j} servers");
}); });
cgb.CreateCommand("ab")
.Description("Try to get 'abalabahaha'")
.Do(async e => {
string[] strings = { "ba", "la", "ha" };
string construct = "@a";
int cnt = rng.Next(4,7);
while (cnt-- > 0) {
construct += strings[rng.Next(0, strings.Length)];
}
await e.Send(construct);
});
cgb.CreateCommand("av").Alias("avatar") cgb.CreateCommand("av").Alias("avatar")
.Parameter("mention", ParameterType.Required) .Parameter("mention", ParameterType.Required)

View File

@ -77,6 +77,7 @@ namespace NadekoBot.Modules {
.Description("Queue a song using keywords or link. **You must be in a voice channel**.\n**Usage**: `!m q Dream Of Venice`") .Description("Queue a song using keywords or link. **You must be in a voice channel**.\n**Usage**: `!m q Dream Of Venice`")
.Parameter("query", ParameterType.Unparsed) .Parameter("query", ParameterType.Unparsed)
.Do(async e => { .Do(async e => {
if (musicPlayers.ContainsKey(e.Server) == false) if (musicPlayers.ContainsKey(e.Server) == false)
if (!musicPlayers.TryAdd(e.Server, new MusicControls(e.User.VoiceChannel))) { if (!musicPlayers.TryAdd(e.Server, new MusicControls(e.User.VoiceChannel))) {
await e.Send("Failed to create a music player for this server"); await e.Send("Failed to create a music player for this server");
@ -94,16 +95,18 @@ namespace NadekoBot.Modules {
try { try {
if (e.User.VoiceChannel?.Server != e.Server) if (e.User.VoiceChannel?.Server != e.Server)
throw new ArgumentException("You need to be in the voice channel on this server."); throw new ArgumentException("You need to be in the voice channel on this server.");
var sr = await player.CreateStreamRequest(e, e.GetArg("query"), e.User.VoiceChannel); Message qmsg = await e.Channel.SendMessage(":musical_note: **Searching...**");
var sr = new StreamRequest(e, e.GetArg("query"), player);
if (sr == null) if (sr == null)
throw new NullReferenceException("StreamRequest is null."); throw new NullReferenceException("StreamRequest is null.");
Message msg = null; Message msg = null;
Message qmsg = null;
sr.OnResolving += async () => { sr.OnResolving += async () => {
qmsg = await e.Send($":musical_note: **Resolving**... \"{e.GetArg("query")}\""); await qmsg.Edit($":musical_note: **Resolving**... \"{e.GetArg("query")}\"");
}; };
sr.OnResolvingFailed += async (err) => { sr.OnResolvingFailed += async (err) => {
qmsg = await e.Send($":anger: :musical_note: **Resolving failed** for `{e.GetArg("query")}`"); await qmsg.Edit($":anger: :musical_note: **Resolving failed** for `{e.GetArg("query")}`");
}; };
sr.OnQueued += async () => { sr.OnQueued += async () => {
await qmsg.Edit($":musical_note:**Queued** {sr.Title.TrimTo(55)}"); await qmsg.Edit($":musical_note:**Queued** {sr.Title.TrimTo(55)}");
@ -162,14 +165,14 @@ namespace NadekoBot.Modules {
player.SongQueue.Shuffle(); player.SongQueue.Shuffle();
await e.Send(":musical_note: Songs shuffled!"); await e.Send(":musical_note: Songs shuffled!");
}); });
bool setgameEnabled = true;
bool setgameEnabled = false;
Timer setgameTimer = new Timer(); Timer setgameTimer = new Timer();
setgameTimer.Interval = 20000; setgameTimer.Interval = 20000;
setgameTimer.Elapsed += (s, e) => { setgameTimer.Elapsed += (s, e) => {
int num = musicPlayers.Count; int num = musicPlayers.Where(kvp=>kvp.Value.CurrentSong != null).Count();
NadekoBot.client.SetGame($"{num} songs".SnPl(num) + $", {musicPlayers.Sum(kvp => kvp.Value.SongQueue.Count())} queued"); NadekoBot.client.SetGame($"{num} songs".SnPl(num) + $", {musicPlayers.Sum(kvp => kvp.Value.SongQueue.Count())} queued");
}; };
setgameTimer.Start();
cgb.CreateCommand("setgame") cgb.CreateCommand("setgame")
.Description("Sets the game of the bot to the number of songs playing.**Owner only**") .Description("Sets the game of the bot to the number of songs playing.**Owner only**")
.Do(async e => { .Do(async e => {

View File

@ -9,48 +9,40 @@ using Newtonsoft.Json;
using Discord.Commands; using Discord.Commands;
using NadekoBot.Extensions; using NadekoBot.Extensions;
namespace NadekoBot.Modules namespace NadekoBot.Modules {
{ class Searches : DiscordModule {
class Searches : DiscordModule public Searches() : base() {
{
public Searches() : base()
{
} }
public override void Install(ModuleManager manager) public override void Install(ModuleManager manager) {
{
var client = NadekoBot.client; var client = NadekoBot.client;
manager.CreateCommands("",cgb => manager.CreateCommands("", cgb => {
{
cgb.CreateCommand("~yt") cgb.CreateCommand("~yt")
.Parameter("query",Discord.Commands.ParameterType.Unparsed) .Parameter("query", Discord.Commands.ParameterType.Unparsed)
.Description("Queries youtubes and embeds the first result") .Description("Queries youtubes and embeds the first result")
.Do(async e => .Do(async e => {
{
if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return; if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return;
var str = ShortenUrl(FindYoutubeUrlByKeywords(e.GetArg("query"))); var str = ShortenUrl(FindYoutubeUrlByKeywords(e.GetArg("query")));
if (string.IsNullOrEmpty(str.Trim())) if (string.IsNullOrEmpty(str.Trim())) {
{ await e.Send("Query failed");
await e.Send( "Query failed");
return; return;
} }
await e.Send( str); await e.Send(str);
}); });
cgb.CreateCommand("~ani") cgb.CreateCommand("~ani")
.Alias("~anime").Alias("~aq") .Alias("~anime").Alias("~aq")
.Parameter("query", Discord.Commands.ParameterType.Unparsed) .Parameter("query", Discord.Commands.ParameterType.Unparsed)
.Description("Queries anilist for an anime and shows the first result.") .Description("Queries anilist for an anime and shows the first result.")
.Do(async e => .Do(async e => {
{
if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return; if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return;
var result = GetAnimeQueryResultLink(e.GetArg("query")); var result = GetAnimeQueryResultLink(e.GetArg("query"));
if (result == null) { if (result == null) {
await e.Send( "Failed to find that anime."); await e.Send("Failed to find that anime.");
return; return;
} }
@ -61,17 +53,15 @@ namespace NadekoBot.Modules
.Alias("~manga").Alias("~mq") .Alias("~manga").Alias("~mq")
.Parameter("query", Discord.Commands.ParameterType.Unparsed) .Parameter("query", Discord.Commands.ParameterType.Unparsed)
.Description("Queries anilist for a manga and shows the first result.") .Description("Queries anilist for a manga and shows the first result.")
.Do(async e => .Do(async e => {
{
if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return; if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return;
var result = GetMangaQueryResultLink(e.GetArg("query")); var result = GetMangaQueryResultLink(e.GetArg("query"));
if (result == null) if (result == null) {
{ await e.Send("Failed to find that anime.");
await e.Send( "Failed to find that anime.");
return; return;
} }
await e.Send( result.ToString()); await e.Send(result.ToString());
}); });
cgb.CreateCommand("~randomcat") cgb.CreateCommand("~randomcat")
@ -146,10 +136,8 @@ namespace NadekoBot.Modules
new StreamReader(((HttpWebRequest)WebRequest.Create(v)).GetResponse().GetResponseStream()).ReadToEnd(); new StreamReader(((HttpWebRequest)WebRequest.Create(v)).GetResponse().GetResponseStream()).ReadToEnd();
private string token = ""; private string token = "";
private AnimeResult GetAnimeQueryResultLink(string query) private AnimeResult GetAnimeQueryResultLink(string query) {
{ try {
try
{
var cl = new RestSharp.RestClient("http://anilist.co/api"); var cl = new RestSharp.RestClient("http://anilist.co/api");
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST); var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
@ -163,39 +151,32 @@ namespace NadekoBot.Modules
rq = new RestSharp.RestRequest("anime/" + smallObj["id"]); rq = new RestSharp.RestRequest("anime/" + smallObj["id"]);
rq.AddParameter("access_token", token); rq.AddParameter("access_token", token);
return JsonConvert.DeserializeObject<AnimeResult>(cl.Execute(rq).Content); return JsonConvert.DeserializeObject<AnimeResult>(cl.Execute(rq).Content);
} } catch (Exception) {
catch (Exception)
{
return null; return null;
} }
} }
private MangaResult GetMangaQueryResultLink(string query) private MangaResult GetMangaQueryResultLink(string query) {
{ try {
try
{
RefreshToken(); RefreshToken();
var cl = new RestSharp.RestClient("http://anilist.co/api"); var cl = new RestSharp.RestClient("http://anilist.co/api");
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST); var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
rq = new RestSharp.RestRequest("/manga/search/"+Uri.EscapeUriString(query)); rq = new RestSharp.RestRequest("/manga/search/" + Uri.EscapeUriString(query));
rq.AddParameter("access_token", token); rq.AddParameter("access_token", token);
var smallObj = JArray.Parse(cl.Execute(rq).Content)[0]; var smallObj = JArray.Parse(cl.Execute(rq).Content)[0];
rq = new RestSharp.RestRequest("manga/" + smallObj["id"]); rq = new RestSharp.RestRequest("manga/" + smallObj["id"]);
rq.AddParameter("access_token", token); rq.AddParameter("access_token", token);
return JsonConvert.DeserializeObject<MangaResult> (cl.Execute(rq).Content); return JsonConvert.DeserializeObject<MangaResult>(cl.Execute(rq).Content);
} } catch (Exception ex) {
catch (Exception ex)
{
Console.WriteLine(ex.ToString()); Console.WriteLine(ex.ToString());
return null; return null;
} }
} }
private void RefreshToken() private void RefreshToken() {
{
var cl = new RestSharp.RestClient("http://anilist.co/api"); var cl = new RestSharp.RestClient("http://anilist.co/api");
var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST); var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST);
rq.AddParameter("grant_type", "client_credentials"); rq.AddParameter("grant_type", "client_credentials");
@ -211,9 +192,8 @@ namespace NadekoBot.Modules
token = JObject.Parse(exec.Content)["access_token"].ToString(); token = JObject.Parse(exec.Content)["access_token"].ToString();
} }
private static async Task<bool> ValidateQuery(Discord.Channel ch,string query) { private static async Task<bool> ValidateQuery(Discord.Channel ch, string query) {
if (string.IsNullOrEmpty(query.Trim())) if (string.IsNullOrEmpty(query.Trim())) {
{
await ch.Send("Please specify search parameters."); await ch.Send("Please specify search parameters.");
return false; return false;
} }
@ -226,6 +206,14 @@ namespace NadekoBot.Modules
return @"https://www.youtube.com/watch?v=dQw4w9WgXcQ"; return @"https://www.youtube.com/watch?v=dQw4w9WgXcQ";
} }
try { try {
//maybe it is already a youtube url, in which case we will just extract the id and prepend it with youtube.com?v=
var match = new Regex("(?:youtu\\.be\\/|v=)(?<id>[\\da-zA-Z\\-_]*)").Match(v);
if (match.Length > 1) {
string str = $"http://www.youtube.com?v={ match.Groups["id"].Value }";
return str;
}
WebRequest wr = WebRequest.Create("https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q=" + Uri.EscapeDataString(v) + "&key=" + NadekoBot.GoogleAPIKey); WebRequest wr = WebRequest.Create("https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q=" + Uri.EscapeDataString(v) + "&key=" + NadekoBot.GoogleAPIKey);
var sr = new StreamReader(wr.GetResponse().GetResponseStream()); var sr = new StreamReader(wr.GetResponse().GetResponseStream());
@ -233,7 +221,8 @@ namespace NadekoBot.Modules
dynamic obj = JObject.Parse(sr.ReadToEnd()); dynamic obj = JObject.Parse(sr.ReadToEnd());
string toReturn = "http://www.youtube.com/watch?v=" + obj.items[0].id.videoId.ToString(); string toReturn = "http://www.youtube.com/watch?v=" + obj.items[0].id.videoId.ToString();
return toReturn; return toReturn;
} catch (Exception) { } catch (Exception ex) {
Console.WriteLine($"Error in findyoutubeurl: {ex.Message}");
return string.Empty; return string.Empty;
} }
} }
@ -245,7 +234,7 @@ namespace NadekoBot.Modules
if (tag == "loli") //loli doesn't work for some reason atm if (tag == "loli") //loli doesn't work for some reason atm
tag = "flat_chest"; tag = "flat_chest";
var webpage = MakeRequestAndGetResponse($"http://danbooru.donmai.us/posts?page={ rng.Next(0, 30) }&tags={ tag.Replace(" ","_") }"); var webpage = MakeRequestAndGetResponse($"http://danbooru.donmai.us/posts?page={ rng.Next(0, 30) }&tags={ tag.Replace(" ", "_") }");
var matches = Regex.Matches(webpage, "data-large-file-url=\"(?<id>.*?)\""); var matches = Regex.Matches(webpage, "data-large-file-url=\"(?<id>.*?)\"");
return $"http://danbooru.donmai.us{ matches[rng.Next(0, matches.Count)].Groups["id"].Value }".ShortenUrl(); return $"http://danbooru.donmai.us{ matches[rng.Next(0, matches.Count)].Groups["id"].Value }".ShortenUrl();
@ -270,30 +259,25 @@ namespace NadekoBot.Modules
} }
} }
public static string ShortenUrl(string url) public static string ShortenUrl(string url) {
{
if (NadekoBot.GoogleAPIKey == null || NadekoBot.GoogleAPIKey == "") return url; if (NadekoBot.GoogleAPIKey == null || NadekoBot.GoogleAPIKey == "") return url;
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/urlshortener/v1/url?key=" + NadekoBot.GoogleAPIKey); var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/urlshortener/v1/url?key=" + NadekoBot.GoogleAPIKey);
httpWebRequest.ContentType = "application/json"; httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST"; httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) {
{
string json = "{\"longUrl\":\"" + url + "\"}"; string json = "{\"longUrl\":\"" + url + "\"}";
streamWriter.Write(json); streamWriter.Write(json);
} }
try try {
{
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse(); var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) {
{
var responseText = streamReader.ReadToEnd(); var responseText = streamReader.ReadToEnd();
string MATCH_PATTERN = @"""id"": ?""(?<id>.+)"""; string MATCH_PATTERN = @"""id"": ?""(?<id>.+)""";
return Regex.Match(responseText, MATCH_PATTERN).Groups["id"].Value; return Regex.Match(responseText, MATCH_PATTERN).Groups["id"].Value;
} }
} } catch (Exception ex) { Console.WriteLine(ex.ToString()); return ""; }
catch (Exception ex) { Console.WriteLine(ex.ToString()); return ""; }
} }
} }
} }