/// <summary> /// Breaks up the full message from Twitch and splits it into pieces (in FilterTags()) /// and places each piece into its respective TwitchData properties /// </summary> /// <param name="message"></param> /// <returns>returns TwitchData object if successfully mapped, null otherewise</returns> private TwitchData MapMessageToObject(ref string message) { TwitchData twitchObj = new TwitchData(); Dictionary <string, string> tags = FilterTags(message); try { twitchObj.message = FilterMessage(tags["user-type"]); twitchObj.messageId = tags["id"]; twitchObj.username = tags["display-name"]; twitchObj.tags.color = tags["color"]; twitchObj.tags.isMod = (tags["mod"] == "1") ? true : false; string b = tags["badges"]; if (b.Contains("broadcaster/1")) { twitchObj.tags.isMod = true; // special case to make broadcasters count as moderators } twitchObj.tags.isTurbo = (tags["turbo"] == "1") ? true : false; twitchObj.tags.isSubscriber = (tags["subscriber"] == "1") ? true : false; twitchObj.tags.userId = tags["user-id"]; } catch (Exception e) { logger.PushError($"[{e.Message}] Could not map message to object :( {message}"); } return(twitchObj); }
/// <summary> /// This writes a message to the selected Twitch channel using the bot using Twitch's message template. /// </summary> /// <param name="message">The message text to write</param> public void WriteBotMessage(string message) { twitchWriter.WriteLine(messageTemplate + message); twitchWriter.Flush(); TwitchData td = new TwitchData(username, message, "#d703fc"); OnReceiveMsg?.Invoke(this, td); //Application.Current.Dispatcher.BeginInvoke((Action<TwitchData>)MainWindowHandle.UpdateChat, td); }
/// <summary> /// This function looks at a message sent in chat to see if it is a command or not. /// </summary> /// <param name="data">The data to be analyzed</param> public void DetectCommand(TwitchData data) { string text = data.message; string command; // where the actual command is stored if (text.StartsWith("!")) { string[] pieces = text.Split(' '); // if message is like "!command extra text we don't need" then split it command = pieces[0]; // "!command" goes here CommandHandler(command, data); // call the command handler to do something } }
/// <summary> /// Updates the RichTextBox (TChatTextBox) with a colorful message from someone on Twitch. /// </summary> /// <param name="data">The TwitchData to process and format</param> public void UpdateChat(TwitchData data) { chat.PushMessage(data.username, data.message); if (lines >= 100) { TChatTextBox.Document.Blocks.Clear(); lines = 0; } if (data.tags.color != "") { // if the user has a color already selected TextRange tr = new TextRange(TChatTextBox.Document.ContentEnd, TChatTextBox.Document.ContentEnd); tr.Text = data.username; SolidColorBrush s = (SolidColorBrush)(new BrushConverter().ConvertFrom(data.tags.color)); tr.ApplyPropertyValue(TextElement.ForegroundProperty, s); tr.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold); TextRange selection = new TextRange(TChatTextBox.Document.ContentEnd, TChatTextBox.Document.ContentEnd); selection.Text = ": " + data.message + Environment.NewLine; selection.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.DarkGray); } else { // no color selected, so use default powder blue color TextRange tr = new TextRange(TChatTextBox.Document.ContentEnd, TChatTextBox.Document.ContentEnd); tr.Text = data.username + ": "; tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.PowderBlue); tr.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold); TextRange selection = new TextRange(TChatTextBox.Document.ContentEnd, TChatTextBox.Document.ContentEnd); selection.Text = ": " + data.message + Environment.NewLine; selection.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.DarkGray); } TChatTextBox.ScrollToEnd(); lines++; return; }
/// <summary> /// Invoker will format the message into a data struct object and will pass /// it to the function that was set for the EventHandler OnReceiveMsg. /// </summary> /// <param name="objArray">The message to pass convert into a TwitchData message object</param> private void Invoker(object objArray) { object[] array = objArray as object[]; CancellationToken token = (CancellationToken)array[1]; if (token.IsCancellationRequested) { return; } string message = array[0].ToString(); TwitchData data = MapMessageToObject(ref message); OnReceiveMsg?.Invoke(this, data); if (data != null && data.message != null) { DetectCommand(data); } }
/// <summary> /// Sends a dispatcher to update the chat, fixing weird UI threading issues. /// </summary> /// <param name="sender"></param> /// <param name="data"></param> private void OnReceiveMsg(object sender, TwitchData data) { Application.Current.Dispatcher.BeginInvoke((Action <TwitchData>)UpdateChat, data); }
/// <summary> /// This function will lookup a detected command to see if it exists in the commandsList /// </summary> /// <param name="command">The command to try and lookup</param> /// <param name="data">The full message from Twitch, with info about the user</param> public void CommandHandler(string command, TwitchData data) { if (commandsList.ContainsKey(command)) // check that this is an actual command { Command comm = commandsList[command]; // save the command object string output = SwapVariables(comm.output, data); DateTime curTime = DateTime.Now; TimeSpan elapsedTime = curTime.Subtract(comm.timeLastUsed); // time difference if (elapsedTime > comm.cooldown) // if enough time has passed since the command was last used { DateTime date = new DateTime(1979, 07, 28, 22, 35, 5); // the default date if (comm.timerlength != TimeSpan.Zero && !comm.timerstart.Equals(date)) { // this is a count down timer TimeSpan elaspedTimeTimer = curTime.Subtract(comm.timerstart); if (elaspedTimeTimer > comm.timerlength) { // timer has expired TimeSpan expire = elaspedTimeTimer.Subtract(comm.timerlength); output = SwapTimer("Timer expired {timer} ago", expire); } else { // timer still going TimeSpan remain = comm.timerlength.Subtract(elaspedTimeTimer); output = SwapTimer(comm.output, remain); } } else if (!comm.timerstart.Equals(date)) { // this is a count up timer TimeSpan elaspedTimeTimer = curTime.Subtract(comm.timerstart); output = SwapTimer(comm.output, elaspedTimeTimer); } switch (comm.permission) { case "mods+": { if (!data.tags.isMod) { WriteBotMessage("Sorry, only moderators and above can use that command!"); } else { WriteBotMessage(output); } break; } case "everyone": { WriteBotMessage(output); break; } } comm.timeLastUsed = curTime; // update the timeLastUsed } else { WriteBotMessage("That command is on cooldown :("); } } else { //WriteBotMessage("Sorry, command not found!"); } }
/// <summary> /// Replaces {user} with the user's name! /// </summary> /// <param name="output">string to modify</param> /// <param name="data">information about Twitch message and user</param> /// <returns></returns> private string SwapVariables(string output, TwitchData data) { output = output.Replace("{user}", data.username); return(output); }
private void OnReceiveMsg(object sender, TwitchData eData) { //MessageBox.Show("I have received the event!"); //MessageBox.Show("Message: " + eData.message, eData.username); }