From e86997212751ea00ca1adc7f3436f7bec6f84701 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Sun, 31 Jan 2016 19:51:27 +0100 Subject: [PATCH] reworked music controls, prune fix, cleanup, other fixes --- NadekoBot.sln | 11 --- NadekoBot/Classes/Music/MusicControls.cs | 59 +++++-------- NadekoBot/Classes/Music/StreamRequest.cs | 17 ++-- NadekoBot/Modules/Administration.cs | 20 ++--- NadekoBot/Modules/Conversations.cs | 12 ++- NadekoBot/Modules/Music.cs | 17 ++-- NadekoBot/Modules/Searches.cs | 108 ++++++++++------------- 7 files changed, 105 insertions(+), 139 deletions(-) diff --git a/NadekoBot.sln b/NadekoBot.sln index 528cb2c2..af29b679 100644 --- a/NadekoBot.sln +++ b/NadekoBot.sln @@ -23,7 +23,6 @@ Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU FullDebug|Any CPU = FullDebug|Any CPU - PRIVATE|Any CPU = PRIVATE|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection 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}.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}.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.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.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.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.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.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.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.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.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.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.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.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.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.Build.0 = Release|Any CPU EndGlobalSection diff --git a/NadekoBot/Classes/Music/MusicControls.cs b/NadekoBot/Classes/Music/MusicControls.cs index c9265cea..f6a48136 100644 --- a/NadekoBot/Classes/Music/MusicControls.cs +++ b/NadekoBot/Classes/Music/MusicControls.cs @@ -9,15 +9,17 @@ namespace NadekoBot.Classes.Music { public class MusicControls { public bool NextSong = false; public IAudioClient Voice; - public Channel VoiceChannel; + public bool Pause = false; public List SongQueue = new List(); - public StreamRequest CurrentSong; + public StreamRequest CurrentSong = null; public bool IsPaused { get; internal set; } = false; public bool Stopped { get; private set; } - public IAudioClient VoiceClient; + public Channel VoiceChannel; + + public IAudioClient VoiceClient = null; private readonly object _voiceLock = new object(); @@ -27,12 +29,13 @@ namespace NadekoBot.Classes.Music { lock (_voiceLock) { if (CurrentSong == null) { if (SongQueue.Count > 0) - LoadNextSong(); + LoadNextSong().Wait(); } else if (CurrentSong.State == StreamState.Completed || NextSong) { NextSong = false; - LoadNextSong(); + LoadNextSong().Wait(); } + } await Task.Delay(1000); } @@ -43,22 +46,24 @@ namespace NadekoBot.Classes.Music { VoiceChannel = voiceChannel; } - public void LoadNextSong() { - lock (_voiceLock) { - CurrentSong?.Stop(); - CurrentSong = null; - if (SongQueue.Count != 0) { - CurrentSong = SongQueue[0]; - SongQueue.RemoveAt(0); - } else { - VoiceClient?.Disconnect(); - VoiceClient = null; - return; - } + public async Task LoadNextSong() { + CurrentSong?.Stop(); + CurrentSong = null; + if (SongQueue.Count != 0) { + CurrentSong = SongQueue[0]; + SongQueue.RemoveAt(0); + } else { + VoiceClient?.Disconnect(); + VoiceClient = null; + return; } 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) { Console.WriteLine($"Starting failed: {ex}"); CurrentSong?.Stop(); @@ -69,7 +74,7 @@ namespace NadekoBot.Classes.Music { lock (_voiceLock) { Stopped = true; foreach (var kvp in SongQueue) { - if(kvp != null) + if (kvp != null) kvp.Stop(); } SongQueue.Clear(); @@ -80,22 +85,6 @@ namespace NadekoBot.Classes.Music { } } - internal async Task 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; } } diff --git a/NadekoBot/Classes/Music/StreamRequest.cs b/NadekoBot/Classes/Music/StreamRequest.cs index ce60ec6c..fbb44ee9 100644 --- a/NadekoBot/Classes/Music/StreamRequest.cs +++ b/NadekoBot/Classes/Music/StreamRequest.cs @@ -30,7 +30,6 @@ namespace NadekoBot.Classes.Music { public string Query { get; } public string Title { get; internal set; } = String.Empty; - public IAudioClient VoiceClient { get; private set; } private MusicStreamer musicStreamer = null; public StreamState State => musicStreamer?.State ?? privateState; @@ -38,23 +37,22 @@ namespace NadekoBot.Classes.Music { public bool IsPaused => MusicControls.IsPaused; - private MusicControls MusicControls; + public MusicControls MusicControls; public StreamRequest(CommandEventArgs e, string query, MusicControls mc) { if (e == null) throw new ArgumentNullException(nameof(e)); if (query == null) 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.VoiceClient = mc.VoiceClient; this.Server = e.Server; 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; try { if (OnResolving != null) @@ -165,7 +163,6 @@ namespace NadekoBot.Classes.Music { Arguments = $"-i {Url} -f s16le -ar 48000 -ac 2 pipe:1", UseShellExecute = false, RedirectStandardOutput = true, - RedirectStandardError = false, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, }); @@ -282,13 +279,13 @@ namespace NadekoBot.Classes.Music { break; } - parent.VoiceClient.Send(voiceBuffer, 0, voiceBuffer.Length); + parent.MusicControls.VoiceClient.Send(voiceBuffer, 0, voiceBuffer.Length); while (IsPaused) { await Task.Delay(50); } } - parent.VoiceClient.Wait(); + parent.MusicControls.VoiceClient.Wait(); Stop(); } diff --git a/NadekoBot/Modules/Administration.cs b/NadekoBot/Modules/Administration.cs index cddeb315..436181ec 100644 --- a/NadekoBot/Modules/Administration.cs +++ b/NadekoBot/Modules/Administration.cs @@ -13,8 +13,8 @@ using System.IO; namespace NadekoBot.Modules { class Administration : DiscordModule { public Administration() : base() { - commands.Add(new HelpCommand()); - commands.Add(new ServerGreetCommand()); + // commands.Add(new HelpCommand()); + // commands.Add(new ServerGreetCommand()); } public override void Install(ModuleManager manager) { @@ -381,18 +381,12 @@ namespace NadekoBot.Modules { return; } try { - var msgs = await e.Channel.DownloadMessages(100); - var lastmessage = e.Channel.Messages.LastOrDefault(); - while (num > 0 && lastmessage != null) { + Message last = null; + while (num > 0) { + var msgs = await e.Channel.DownloadMessages(num, last?.Id); + last = msgs.LastOrDefault(); msgs.ForEach(async m => await m.Delete()); - int toDelete; - if (num > 100) - toDelete = 100; - else - toDelete = num; - num -= toDelete; - lastmessage = msgs.LastOrDefault(); - msgs = await e.Channel.DownloadMessages(toDelete, lastmessage?.Id); + num -= 100; } } catch (Exception) { await e.Send("Failed pruning. Make sure the bot has correct permissions."); } diff --git a/NadekoBot/Modules/Conversations.cs b/NadekoBot/Modules/Conversations.cs index 40d0a92a..ca61bd25 100644 --- a/NadekoBot/Modules/Conversations.cs +++ b/NadekoBot/Modules/Conversations.cs @@ -372,7 +372,17 @@ namespace NadekoBot.Modules { 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") .Parameter("mention", ParameterType.Required) diff --git a/NadekoBot/Modules/Music.cs b/NadekoBot/Modules/Music.cs index 4befb6f9..bd51e474 100644 --- a/NadekoBot/Modules/Music.cs +++ b/NadekoBot/Modules/Music.cs @@ -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`") .Parameter("query", ParameterType.Unparsed) .Do(async e => { + if (musicPlayers.ContainsKey(e.Server) == false) if (!musicPlayers.TryAdd(e.Server, new MusicControls(e.User.VoiceChannel))) { await e.Send("Failed to create a music player for this server"); @@ -94,16 +95,18 @@ namespace NadekoBot.Modules { try { if (e.User.VoiceChannel?.Server != e.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) throw new NullReferenceException("StreamRequest is null."); Message msg = null; - Message qmsg = null; 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) => { - 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 () => { await qmsg.Edit($":musical_note:**Queued** {sr.Title.TrimTo(55)}"); @@ -162,14 +165,14 @@ namespace NadekoBot.Modules { player.SongQueue.Shuffle(); await e.Send(":musical_note: Songs shuffled!"); }); - bool setgameEnabled = true; + + bool setgameEnabled = false; Timer setgameTimer = new Timer(); setgameTimer.Interval = 20000; 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"); }; - setgameTimer.Start(); cgb.CreateCommand("setgame") .Description("Sets the game of the bot to the number of songs playing.**Owner only**") .Do(async e => { diff --git a/NadekoBot/Modules/Searches.cs b/NadekoBot/Modules/Searches.cs index 391abd49..d055293d 100644 --- a/NadekoBot/Modules/Searches.cs +++ b/NadekoBot/Modules/Searches.cs @@ -9,48 +9,40 @@ using Newtonsoft.Json; using Discord.Commands; using NadekoBot.Extensions; -namespace NadekoBot.Modules -{ - class Searches : DiscordModule - { - public Searches() : base() - { +namespace NadekoBot.Modules { + class Searches : DiscordModule { + public Searches() : base() { } - public override void Install(ModuleManager manager) - { + public override void Install(ModuleManager manager) { var client = NadekoBot.client; - manager.CreateCommands("",cgb => - { + manager.CreateCommands("", cgb => { cgb.CreateCommand("~yt") - .Parameter("query",Discord.Commands.ParameterType.Unparsed) + .Parameter("query", Discord.Commands.ParameterType.Unparsed) .Description("Queries youtubes and embeds the first result") - .Do(async e => - { + .Do(async e => { if (!(await ValidateQuery(e.Channel, e.GetArg("query")))) return; var str = ShortenUrl(FindYoutubeUrlByKeywords(e.GetArg("query"))); - if (string.IsNullOrEmpty(str.Trim())) - { - await e.Send( "Query failed"); + if (string.IsNullOrEmpty(str.Trim())) { + await e.Send("Query failed"); return; } - await e.Send( str); + await e.Send(str); }); cgb.CreateCommand("~ani") .Alias("~anime").Alias("~aq") .Parameter("query", Discord.Commands.ParameterType.Unparsed) .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; var result = GetAnimeQueryResultLink(e.GetArg("query")); - if (result == null) { - await e.Send( "Failed to find that anime."); + if (result == null) { + await e.Send("Failed to find that anime."); return; } @@ -61,17 +53,15 @@ namespace NadekoBot.Modules .Alias("~manga").Alias("~mq") .Parameter("query", Discord.Commands.ParameterType.Unparsed) .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; var result = GetMangaQueryResultLink(e.GetArg("query")); - if (result == null) - { - await e.Send( "Failed to find that anime."); + if (result == null) { + await e.Send("Failed to find that anime."); return; } - await e.Send( result.ToString()); + await e.Send(result.ToString()); }); cgb.CreateCommand("~randomcat") @@ -92,7 +82,7 @@ namespace NadekoBot.Modules .Parameter("all", ParameterType.Unparsed) .Do(async e => { await e.Send("This feature is being reconstructed."); - + }); cgb.CreateCommand("~ir") @@ -146,10 +136,8 @@ namespace NadekoBot.Modules new StreamReader(((HttpWebRequest)WebRequest.Create(v)).GetResponse().GetResponseStream()).ReadToEnd(); private string token = ""; - private AnimeResult GetAnimeQueryResultLink(string query) - { - try - { + private AnimeResult GetAnimeQueryResultLink(string query) { + try { var cl = new RestSharp.RestClient("http://anilist.co/api"); 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.AddParameter("access_token", token); return JsonConvert.DeserializeObject(cl.Execute(rq).Content); - } - catch (Exception) - { + } catch (Exception) { return null; } } - private MangaResult GetMangaQueryResultLink(string query) - { - try - { + private MangaResult GetMangaQueryResultLink(string query) { + try { RefreshToken(); var cl = new RestSharp.RestClient("http://anilist.co/api"); 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); - + var smallObj = JArray.Parse(cl.Execute(rq).Content)[0]; rq = new RestSharp.RestRequest("manga/" + smallObj["id"]); rq.AddParameter("access_token", token); - return JsonConvert.DeserializeObject (cl.Execute(rq).Content); - } - catch (Exception ex) - { + return JsonConvert.DeserializeObject(cl.Execute(rq).Content); + } catch (Exception ex) { Console.WriteLine(ex.ToString()); return null; } } - private void RefreshToken() - { + private void RefreshToken() { var cl = new RestSharp.RestClient("http://anilist.co/api"); var rq = new RestSharp.RestRequest("/auth/access_token", RestSharp.Method.POST); rq.AddParameter("grant_type", "client_credentials"); @@ -211,9 +192,8 @@ namespace NadekoBot.Modules token = JObject.Parse(exec.Content)["access_token"].ToString(); } - private static async Task ValidateQuery(Discord.Channel ch,string query) { - if (string.IsNullOrEmpty(query.Trim())) - { + private static async Task ValidateQuery(Discord.Channel ch, string query) { + if (string.IsNullOrEmpty(query.Trim())) { await ch.Send("Please specify search parameters."); return false; } @@ -226,6 +206,14 @@ namespace NadekoBot.Modules return @"https://www.youtube.com/watch?v=dQw4w9WgXcQ"; } 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=)(?[\\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); var sr = new StreamReader(wr.GetResponse().GetResponseStream()); @@ -233,7 +221,8 @@ namespace NadekoBot.Modules dynamic obj = JObject.Parse(sr.ReadToEnd()); string toReturn = "http://www.youtube.com/watch?v=" + obj.items[0].id.videoId.ToString(); return toReturn; - } catch (Exception) { + } catch (Exception ex) { + Console.WriteLine($"Error in findyoutubeurl: {ex.Message}"); return string.Empty; } } @@ -245,7 +234,7 @@ namespace NadekoBot.Modules if (tag == "loli") //loli doesn't work for some reason atm 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=\"(?.*?)\""); 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; var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/urlshortener/v1/url?key=" + NadekoBot.GoogleAPIKey); httpWebRequest.ContentType = "application/json"; httpWebRequest.Method = "POST"; - using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) - { + using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) { string json = "{\"longUrl\":\"" + url + "\"}"; streamWriter.Write(json); } - try - { + try { var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse(); - using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) - { + using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) { var responseText = streamReader.ReadToEnd(); string MATCH_PATTERN = @"""id"": ?""(?.+)"""; 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 ""; } } } }