/// <summary> /// Checks which users are live, along with who has gone offline. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void Tick(object sender, ElapsedEventArgs e) { if (ticking == true) { return; } ticking = true; List <string> liveUsers = new List <string>(); var s = await GetStreams(); if (s != null) { for (int i = 0; i < s.Length; i++) { liveUsers.Add(s[i].UserName); // User is/was live. if (LiveStreams.ContainsKey(s[i].UserName)) { // It's the same stream. if (LiveStreams[s[i].UserName].Id == s[i].Id) { LiveStreams[s[i].UserName] = s[i]; // Invoke event. OnStreamArgs onStreamUpdateArgs = new OnStreamArgs(s[i].UserName, s[i]); OnStreamUpdate?.Invoke(this, onStreamUpdateArgs); continue; } // Different stream. else { if (LiveStreams.TryRemove(s[i].UserName, out Stream v)) { if (LiveStreams.TryAdd(s[i].UserName, s[i])) { // Invoke event. OnStreamArgs onStreamOnlineArgs = new OnStreamArgs(s[i].UserName, s[i]); OnStreamOnline?.Invoke(this, onStreamOnlineArgs); } } } } // User was not live before. else { if (LiveStreams.TryAdd(s[i].UserName, s[i])) { // Invoke event. OnStreamArgs oso = new OnStreamArgs(s[i].UserName, s[i]); OnStreamOnline?.Invoke(this, oso); } } } Cleanup(liveUsers); } ticking = false; SaveLoadService.Save(monitoredUsersFilename, LiveStreams); }
private void _checkOnlineStreams() { var liveStreamers = _getLiveStreamers().Result; foreach (var channel in _channelIds) { var currentStream = liveStreamers.Where(x => x.Channel.Id == channel).FirstOrDefault(); if (currentStream == null) { //offline if (_statuses[channel] != null) { var channelName = _statuses[channel].Channel.Name; //have gone offline _statuses[channel] = null; if (!_isStartup || (_isStartup && _invokeEventsOnStart)) { OnStreamOffline?.Invoke(this, new OnStreamOfflineArgs { ChannelId = channel, Channel = channelName, CheckIntervalSeconds = CheckIntervalSeconds }); } } } else { var channelName = currentStream.Channel.Name; //online if (_statuses[channel] == null) { //have gone online if (!_isStartup || (_isStartup && _invokeEventsOnStart)) { OnStreamOnline?.Invoke(this, new OnStreamOnlineArgs { ChannelId = channel, Channel = channelName, Stream = currentStream, CheckIntervalSeconds = CheckIntervalSeconds }); } } else { //stream updated if (!_isStartup || (_isStartup && _invokeEventsOnStart)) { OnStreamUpdate?.Invoke(this, new OnStreamUpdateArgs { ChannelId = channel, Channel = channelName, Stream = currentStream, CheckIntervalSeconds = CheckIntervalSeconds }); } } _statuses[channel] = currentStream; } } }
private async Task CheckStreamStatus(V5 twitchClient, int intervallTime) { List <TwitchLib.Api.V5.Models.Streams.Stream> onlineStreams = new List <TwitchLib.Api.V5.Models.Streams.Stream>(); while (true) { try { await Task.Delay(intervallTime * 1000); using var db = Database.Open(); var twitchChannels = db.TwitchChannels.ToList(); if (!twitchChannels.Any()) { continue; } foreach (var twitchChannel in twitchChannels) { var userId = twitchClient.Users.GetUserByNameAsync(twitchChannel.ChannelName).Result.Matches?.FirstOrDefault()?.Id; if (userId == null) { continue; } var stream = twitchClient.Streams?.GetStreamByUserAsync(userId).Result?.Stream; if (stream != null && stream.StreamType != "playlist") { if (!onlineStreams.Contains(stream)) { onlineStreams.Add(stream); OnStreamOnline?.Invoke(this, new StreamEventArgs { Stream = stream, GuildId = twitchChannel.GuildId }); } } else { if (onlineStreams.Contains(stream)) { onlineStreams.Remove(stream); } } await Task.Delay(1000); } } catch (Exception e) { _logger.Error(e, $"Error while checking Twitch streams"); } } }
private void HandleLiveStreamUpdate(string channel, Stream liveStream, bool callEvents) { var wasAlreadyLive = LiveStreams.ContainsKey(channel); LiveStreams[channel] = liveStream; if (!callEvents) { return; } if (!wasAlreadyLive) { OnStreamOnline?.Invoke(this, new OnStreamOnlineArgs { Channel = channel, Stream = liveStream }); } else { OnStreamUpdate?.Invoke(this, new OnStreamUpdateArgs { Channel = channel, Stream = liveStream }); } }
private async void _streamMonitorTimerElapsed(object sender, ElapsedEventArgs e) { foreach (string channel in Channels) { bool current = await _checkStreamOnline(channel); if (current && !_statuses[channel]) { OnStreamOnline?.Invoke(this, new OnStreamOnlineArgs { Channel = channel, IdentifierType = IdentifierType, CheckIntervalSeconds = CheckIntervalSeconds }); _statuses[channel] = true; } else if (!current && _statuses[channel]) { OnStreamOffline?.Invoke(this, new OnStreamOfflineArgs { Channel = channel, IdentifierType = IdentifierType, CheckIntervalSeconds = CheckIntervalSeconds }); _statuses[channel] = false; } } }
public UnityLiveStreamMonitor(ITwitchAPI api, int checkIntervalSeconds = 60, bool checkStatusOnStart = true, bool invokeEventsOnStart = false) : base(api, checkIntervalSeconds, checkStatusOnStart, invokeEventsOnStart) { ThreadDispatcher.EnsureCreated(); base.OnStreamOnline += ((object sender, OnStreamOnlineArgs e) => { ThreadDispatcher.Enqueue(() => OnStreamOnline?.Invoke(sender, e)); }); base.OnStreamOffline += ((object sender, OnStreamOfflineArgs e) => { ThreadDispatcher.Enqueue(() => OnStreamOffline?.Invoke(sender, e)); }); base.OnStreamUpdate += ((object sender, OnStreamUpdateArgs e) => { ThreadDispatcher.Enqueue(() => OnStreamUpdate?.Invoke(sender, e)); }); base.OnStreamMonitorStarted += ((object sender, OnStreamMonitorStartedArgs e) => { ThreadDispatcher.Enqueue(() => OnStreamMonitorStarted?.Invoke(sender, e)); }); base.OnStreamMonitorEnded += ((object sender, OnStreamMonitorEndedArgs e) => { ThreadDispatcher.Enqueue(() => OnStreamMonitorEnded?.Invoke(sender, e)); }); base.OnStreamsSet += ((object sender, OnStreamsSetArgs e) => { ThreadDispatcher.Enqueue(() => OnStreamsSet?.Invoke(sender, e)); }); }
public UnityFollowerService(ITwitchAPI api, int checkIntervalSeconds = 60, bool checkStatusOnStart = true, bool invokeEventsOnStart = false) : base(api, checkIntervalSeconds, checkStatusOnStart, invokeEventsOnStart) { _threadDispatcher = new GameObject("ThreadDispatcher"); _threadDispatcher.AddComponent <ThreadDispatcher>(); UnityEngine.Object.DontDestroyOnLoad(_threadDispatcher); base.OnStreamOnline += ((object sender, OnStreamOnlineArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnStreamOnline?.Invoke(sender, e)); }); base.OnStreamOffline += ((object sender, OnStreamOfflineArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnStreamOffline?.Invoke(sender, e)); }); base.OnStreamUpdate += ((object sender, OnStreamUpdateArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnStreamUpdate?.Invoke(sender, e)); }); base.OnStreamMonitorStarted += ((object sender, OnStreamMonitorStartedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnStreamMonitorStarted?.Invoke(sender, e)); }); base.OnStreamMonitorEnded += ((object sender, OnStreamMonitorEndedArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnStreamMonitorEnded?.Invoke(sender, e)); }); base.OnStreamsSet += ((object sender, OnStreamsSetArgs e) => { ThreadDispatcher.Instance().Enqueue(() => OnStreamsSet?.Invoke(sender, e)); }); }
public UnityLiveStreamMonitor(ITwitchAPI api, int checkIntervalSeconds = 60, int maxStreamRequestCountPerRequest = 100) : base(api, checkIntervalSeconds, maxStreamRequestCountPerRequest) { ThreadDispatcher.EnsureCreated(); base.OnStreamOnline += ((object sender, OnStreamOnlineArgs e) => { ThreadDispatcher.Enqueue(() => OnStreamOnline?.Invoke(sender, e)); }); base.OnStreamOffline += ((object sender, OnStreamOfflineArgs e) => { ThreadDispatcher.Enqueue(() => OnStreamOffline?.Invoke(sender, e)); }); base.OnStreamUpdate += ((object sender, OnStreamUpdateArgs e) => { ThreadDispatcher.Enqueue(() => OnStreamUpdate?.Invoke(sender, e)); }); base.OnServiceStarted += ((object sender, OnServiceStartedArgs e) => { ThreadDispatcher.Enqueue(() => OnServiceStarted?.Invoke(sender, e)); }); base.OnServiceStopped += ((object sender, OnServiceStoppedArgs e) => { ThreadDispatcher.Enqueue(() => OnServiceStopped?.Invoke(sender, e)); }); base.OnChannelsSet += ((object sender, OnChannelsSetArgs e) => { ThreadDispatcher.Enqueue(() => OnChannelsSet?.Invoke(sender, e)); }); }