diff --git a/NadekoBot/Classes/ServerSpecificConfig.cs b/NadekoBot/Classes/ServerSpecificConfig.cs index bf2e76e3..01a0deb3 100644 --- a/NadekoBot/Classes/ServerSpecificConfig.cs +++ b/NadekoBot/Classes/ServerSpecificConfig.cs @@ -121,6 +121,7 @@ namespace NadekoBot.Classes { public enum StreamType { Twitch, + Beam, Hitbox, YoutubeGaming } diff --git a/NadekoBot/Commands/StreamNotifications.cs b/NadekoBot/Commands/StreamNotifications.cs index cc58228b..f7a980d4 100644 --- a/NadekoBot/Commands/StreamNotifications.cs +++ b/NadekoBot/Commands/StreamNotifications.cs @@ -1,39 +1,47 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; -using System.Timers; -using Discord.Commands; +using Discord.Commands; using NadekoBot.Classes; using NadekoBot.Classes.JSONModels; using NadekoBot.Classes.Permissions; using NadekoBot.Modules; using Newtonsoft.Json.Linq; +using System; +using System.Linq; +using System.Threading.Tasks; +using System.Timers; -namespace NadekoBot.Commands { - internal class StreamNotifications : DiscordCommand { +namespace NadekoBot.Commands +{ + internal class StreamNotifications : DiscordCommand + { - private readonly Timer checkTimer = new Timer { + private readonly Timer checkTimer = new Timer + { Interval = new TimeSpan(0, 0, 15).TotalMilliseconds, }; - public StreamNotifications(DiscordModule module) : base(module) { + public StreamNotifications(DiscordModule module) : base(module) + { - checkTimer.Elapsed += async (s, e) => { - try { + checkTimer.Elapsed += async (s, e) => + { + try + { var streams = SpecificConfigurations.Default.AllConfigs.SelectMany(c => c.ObservingStreams); if (!streams.Any()) return; - foreach (var stream in streams) { + foreach (var stream in streams) + { Tuple data; - try { + try + { data = await GetStreamStatus(stream); - } catch { + } + catch + { continue; } - if (data.Item1 != stream.LastStatus) { + if (data.Item1 != stream.LastStatus) + { stream.LastStatus = data.Item1; var server = NadekoBot.Client.GetServer(stream.ServerId); var channel = server?.GetChannel(stream.ChannelId); @@ -47,23 +55,27 @@ namespace NadekoBot.Commands { msg += $"\n`Here is the Link:`【 http://www.hitbox.tv/{stream.Username}/ 】"; else if (stream.Type == StreamNotificationConfig.StreamType.Twitch) msg += $"\n`Here is the Link:`【 http://www.twitch.tv/{stream.Username}/ 】"; + else if (stream.Type == StreamNotificationConfig.StreamType.Beam) + msg += $"\n`Here is the Link:`【 http://www.beam.pro/{stream.Username}/ 】"; else if (stream.Type == StreamNotificationConfig.StreamType.YoutubeGaming) msg += $"\n`Here is the Link:`【 not implemented yet - {stream.Username} 】"; await channel.SendMessage(msg); } } - } catch { } + } + catch { } ConfigHandler.SaveConfig(); }; - checkTimer.Start(); } - private async Task> GetStreamStatus(StreamNotificationConfig stream) { + private async Task> GetStreamStatus(StreamNotificationConfig stream) + { bool isLive; string response; JObject data; - switch (stream.Type) { + switch (stream.Type) + { case StreamNotificationConfig.StreamType.Hitbox: response = await SearchHelper.GetResponseStringAsync($"https://api.hitbox.tv/media/status/{stream.Username}"); data = JObject.Parse(response); @@ -74,13 +86,19 @@ namespace NadekoBot.Commands { data = JObject.Parse(response); isLive = !string.IsNullOrWhiteSpace(data["stream"].ToString()); return new Tuple(isLive, isLive ? data["stream"]["viewers"].ToString() : "0"); + case StreamNotificationConfig.StreamType.Beam: + response = await SearchHelper.GetResponseStringAsync($"https://beam.pro/api/v1/channels/{stream.Username}"); + data = JObject.Parse(response); + isLive = data["online"].ToObject() == true; + return new Tuple(isLive, data["viewersCurrent"].ToString()); default: break; } return new Tuple(false, "0"); } - internal override void Init(CommandGroupBuilder cgb) { + internal override void Init(CommandGroupBuilder cgb) + { cgb.CreateCommand(Module.Prefix + "hitbox") .Alias(Module.Prefix + "hb") .Description("Notifies this channel when a certain user starts streaming." + @@ -97,13 +115,22 @@ namespace NadekoBot.Commands { .Parameter("username", ParameterType.Unparsed) .Do(TrackStream(StreamNotificationConfig.StreamType.Twitch)); + cgb.CreateCommand(Module.Prefix + "beam") + .Alias(Module.Prefix + "bm") + .Description("Notifies this channel when a certain user starts streaming." + + "\n**Usage**: ~beam SomeStreamer") + .AddCheck(SimpleCheckers.ManageServer()) + .Parameter("username", ParameterType.Unparsed) + .Do(TrackStream(StreamNotificationConfig.StreamType.Beam)); + cgb.CreateCommand(Module.Prefix + "removestream") .Alias(Module.Prefix + "rms") .Description("Removes notifications of a certain streamer on this channel." + "\n**Usage**: ~rms SomeGuy") .AddCheck(SimpleCheckers.ManageServer()) .Parameter("username", ParameterType.Unparsed) - .Do(async e => { + .Do(async e => + { var username = e.GetArg("username")?.ToLower().Trim(); if (string.IsNullOrWhiteSpace(username)) return; @@ -113,7 +140,8 @@ namespace NadekoBot.Commands { var toRemove = config.ObservingStreams .FirstOrDefault(snc => snc.ChannelId == e.Channel.Id && snc.Username.ToLower().Trim() == username); - if (toRemove == null) { + if (toRemove == null) + { await e.Channel.SendMessage(":anger: No such stream."); return; } @@ -127,7 +155,8 @@ namespace NadekoBot.Commands { .Alias(Module.Prefix + "ls") .Description("Lists all streams you are following on this server." + "\n**Usage**: ~ls") - .Do(async e => { + .Do(async e => + { var config = SpecificConfigurations.Default.Of(e.Server.Id); @@ -136,15 +165,19 @@ namespace NadekoBot.Commands { var streamsArray = streams as StreamNotificationConfig[] ?? streams.ToArray(); - if (streamsArray.Length == 0) { + if (streamsArray.Length == 0) + { await e.Channel.SendMessage("You are not following any streams on this server."); return; } - var text = string.Join("\n", streamsArray.Select(snc => { - try { + var text = string.Join("\n", streamsArray.Select(snc => + { + try + { return $"`{snc.Username}`'s stream on **{e.Server.GetChannel(e.Channel.Id).Name}** channel. 【`{snc.Type.ToString()}`】"; - } catch { } + } + catch { } return ""; })); @@ -153,27 +186,34 @@ namespace NadekoBot.Commands { } private Func TrackStream(StreamNotificationConfig.StreamType type) => - async e => { + async e => + { var username = e.GetArg("username")?.ToLowerInvariant(); if (string.IsNullOrWhiteSpace(username)) return; var config = SpecificConfigurations.Default.Of(e.Server.Id); - var stream = new StreamNotificationConfig { + var stream = new StreamNotificationConfig + { ServerId = e.Server.Id, ChannelId = e.Channel.Id, Username = username, Type = type, }; var exists = config.ObservingStreams.Contains(stream); - if (exists) { + if (exists) + { await e.Channel.SendMessage(":anger: I am already notifying that stream on this channel."); + return; } Tuple data; - try { + try + { data = await GetStreamStatus(stream); - } catch { + } + catch + { await e.Channel.SendMessage(":anger: Stream probably doesn't exist."); return; } @@ -183,6 +223,8 @@ namespace NadekoBot.Commands { msg += $"\n`Here is the Link:`【 http://www.hitbox.tv/{stream.Username}/ 】"; else if (type == StreamNotificationConfig.StreamType.Twitch) msg += $"\n`Here is the Link:`【 http://www.twitch.tv/{stream.Username}/ 】"; + else if (type == StreamNotificationConfig.StreamType.Beam) + msg += $"\n`Here is the Link:`【 https://beam.pro/{stream.Username}/ 】"; else if (type == StreamNotificationConfig.StreamType.YoutubeGaming) msg += $"\n`Here is the Link:` not implemented yet - {stream.Username}"; stream.LastStatus = data.Item1;