/// <summary> /// IRC event: connection established. /// </summary> private void Client_Connected(object sender, EventArgs e) { TmiLog.Log("Connected to Twitch IRC server."); client.SendRawMessage("CAP REQ :twitch.tv/membership"); client.SendRawMessage("CAP REQ :twitch.tv/commands"); client.SendRawMessage("CAP REQ :twitch.tv/tags"); client.SendRawMessage("CAP REQ :twitch.tv/tags twitch.tv/commands"); }
/// <summary> /// IRC event: authenticated was OK, and we received a welcome message from the server. /// </summary> private void Client_Registered(object sender, EventArgs e) { TmiLog.Log("Authed on Twitch IRC server."); if (Status == ClientStatus.Connecting) { Status = ClientStatus.Started; } if (OnStarted != null) { OnStarted.Invoke(this, new EventArgs()); } }
/// <summary> /// Shuts down the client, disconnecting from the IRC server, and shutting down any of our threads. /// </summary> public void Stop() { lock (controlSyncLock) { // Ensure client is killed dead if (client != null) { if (client.IsConnected) { try { client.Disconnect(); } catch (Exception) { } } } if (client != null) { client.Dispose(); client = null; } // Switch status & raise event if we aren't already in stopped state if (Status != ClientStatus.Stopped) { TmiLog.Log("Stopping client..."); if (OnStopped != null) { OnStopped.Invoke(this, new EventArgs()); } } Status = ClientStatus.Stopped; // Kick the queue thread so it quits faster if (channelJoinQueueThread != null) { try { channelJoinQueueThread.Interrupt(); } catch (Exception) { } channelJoinQueueThread = null; } } }
/// <summary> /// Channel join queue thread loop. /// </summary> protected void __RunChannelJoinQueue() { try { while (KeepThreadsAlive) { try { if (Status == ClientStatus.Started && channelJoinQueue.Count > 0) { lock (channelJoinQueue) { string nextToJoin = channelJoinQueue.Dequeue(); if (nextToJoin != null) { if (!channelList.Contains(nextToJoin)) { TmiLog.Error($"Skipping channel join, no longer on list: {nextToJoin}"); } else { TmiLog.Error($"Joining channel: #{nextToJoin}"); client.Channels.Join($"#{nextToJoin}"); } } } } } catch (Exception ex) { TmiLog.Error($"Exception in channel join queue: {ex}"); } finally { Thread.Sleep(100); } } } catch (ThreadAbortException) { } catch (ThreadInterruptedException) { } TmiLog.Log("Channel join queue thread exited."); }
/// <summary> /// Starts the client, connecting to IRC server, and beginning the join queue. /// </summary> public void Start() { lock (controlSyncLock) { Stop(); Status = ClientStatus.Connecting; TmiLog.Log($"Starting client. Connecting to irc://{IRC_HOSTNAME}:{IRC_PORT_NONSSL}..."); // Init IRC client = new TwitchIrcClient(); client.Connected += Client_Connected; client.Registered += Client_Registered; client.ConnectFailed += Client_ConnectFailed; client.ProtocolError += Client_ProtocolError; client.ErrorMessageReceived += Client_ErrorMessageReceived; client.Error += Client_Error; client.MotdReceived += Client_MotdReceived; client.Disconnected += Client_Disconnected; client.RawMessageReceived += Client_RawMessageReceived; client.RawMessageSent += Client_RawMessageSent; client.Connect(new DnsEndPoint(IRC_HOSTNAME, IRC_PORT_NONSSL), false, new IrcUserRegistrationInfo() { UserName = this.userName, NickName = this.userName, Password = this.password }); // Fill the channel join queue, and start the queue thread channelJoinQueue.Clear(); channelList.ForEach((channel) => channelJoinQueue.Enqueue(channel)); // Start the queue thread channelJoinQueueThread = new Thread(new ThreadStart(__RunChannelJoinQueue)); channelJoinQueueThread.Name = "Tmi__RunChannelJoinQueue"; channelJoinQueueThread.Priority = ThreadPriority.BelowNormal; channelJoinQueueThread.Start(); } }