/// <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 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 }); } }
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)); }); }
/// <summary> /// Runs the server /// </summary> public void Start(object state) { NetBuffer buffer = new NetBuffer(bufferSize); CancellationToken cts = (CancellationToken)state; while (true) { // Listen for a new connection server.Listen(1); using (Socket socket = server.Accept()) { // Attempt pairing with the new client socket.Receive(buffer); // Receive the dimensions of the image uint requestedWidth = buffer.GetUInt(0); uint requestedHeight = buffer.GetUInt(4); // Dimesions are too large if (requestedHeight > MAX_DIMENSION_SIZE || requestedWidth > MAX_DIMENSION_SIZE) { socket.Send(buffer.Reset().Write(DIMENSIONS_TOO_LARGE)); continue; } // Sends the dimensions to client to verify socket.Send(buffer); socket.Receive(buffer); // Dimensions mismatch if (requestedHeight != buffer.GetUInt(4) || requestedWidth != buffer.GetUInt(0)) { socket.Send(buffer.Write(DIMENSIONS_MISMATCH)); continue; } StreamImage image = new StreamImage((int)requestedWidth, (int)requestedHeight); IndexCompressor compressor = new IndexCompressor(requestedWidth, requestedHeight, 0x01000000); // Initialize image socket.Send(buffer.Reset().Write(REQUEST_IMAGE)); int x = 0; int y = 0; bool ended = false; do { socket.Receive(buffer); int i = 0; while (i < buffer.Length - sizeof(int)) { image.SetPixel(x, y, buffer.GetInt(i)); i += sizeof(int); x++; if (x >= requestedWidth) { x = 0; y++; } } if (buffer.GetUInt(i) == END_OF_IMAGE) { ended = true; } else { image.SetPixel(x, y, buffer.GetInt(i)); x++; if (x >= requestedWidth) { x = 0; y++; } } } while (!ended); OnConnectionAstablished?.Invoke(image.Width, image.Height, image.image, this); socket.Send(buffer.Reset().Write(PAIR_SUCCESSFUL)); IIndexable pixel = new RISPImagePixel(); // Start streaming loop while (true) { try { socket.Receive(buffer); if (buffer.GetULong(0) == TERMINATE_CONNECTION) { break; } int index = 0; RISPImagePixel[] diffrences = new RISPImagePixel[buffer.Length / sizeof(ulong)]; while (index < buffer.Length) { ulong compressedValue = buffer.GetULong(index); compressor.Decompress(compressedValue, ref pixel); RISPImagePixel iPixel = (RISPImagePixel)pixel; System.Console.WriteLine(iPixel.color.ToString("X")); diffrences[index / sizeof(ulong)] = iPixel; image.SetPixel((int)iPixel.x, (int)iPixel.y, new RGB((int)iPixel.color)); index += sizeof(ulong); } // Call stream updates if (diffrences.Length > 0) { OnStreamUpdate?.Invoke(diffrences, this); } } catch (SocketException) { break; } } } } }
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)); }); }