Advertisement
Guest User

Untitled

a guest
Dec 18th, 2013
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 15.57 KB | None | 0 0
  1. using System;
  2. using System.ComponentModel;
  3. using CatchException.StreamJob.Settings;
  4. using ChatSharp;
  5. using CatchException.Logging;
  6. using System.Net.Sockets;
  7. using CatchException.Injection;
  8. using ChatSharp.Events;
  9. using System.Text.RegularExpressions;
  10. using System.Collections.Generic;
  11. using CatchException.StreamJob.Common;
  12.  
  13. namespace CatchException.StreamJob.Services
  14. {
  15.     public class TwitchMessage
  16.     {
  17.         public string Username { get; internal set; }
  18.  
  19.         public string Message { get; internal set; }
  20.     }
  21.  
  22.     public class IrcService
  23.     {
  24.         // sub notification
  25.         // <twitchnotify> Beatemen just subscribed!
  26.  
  27.         private static Random random = new Random();
  28.         private static Regex subscriptionNotificationRegex = new Regex("(.*) just subscribed!");
  29.         private static Regex jtvMessage = new Regex(@"(?<type>.+) (?<user>.+) (?<arguments>.+)?");
  30.  
  31.         private IrcClient ircClient;
  32.         private IrcChannel channel;
  33.  
  34.         [Inject]
  35.         private Settings.Core coreSettings;
  36.  
  37.         [Inject]
  38.         private Irc ircSettings;
  39.  
  40.         [Inject]
  41.         private Logger log;
  42.  
  43.         private Dictionary<string, IrcMessageStager> messageStagers;
  44.  
  45.         protected class IrcMessageStager
  46.         {
  47.             public IrcMessageStager()
  48.             {
  49.                 Emotes = new List<int>();
  50.                 Groups = new List<string>();
  51.             }
  52.  
  53.             public string User { get; set; }
  54.             public string Channel { get; set; }
  55.             public string Message { get; set; }
  56.             public string Color { get; set; }
  57.             public bool IsRandomColor { get; set; }
  58.             public List<int> Emotes { get; private set; }
  59.             public List<string> Groups { get; private set; }
  60.  
  61.             public ChatMessageEventArgs Create()
  62.             {
  63.                 string color = this.Color;
  64.                 bool isRandomColor = false;
  65.                 if (color == null)
  66.                 {
  67.                     color = TwitchColors[Math.Abs(User.GetHashCode()) % (TwitchColors.Length - 1)];
  68.                     isRandomColor = true;
  69.                 }
  70.                 ChatMessageEventArgs message = new ChatMessageEventArgs()
  71.                 {
  72.                     User = this.User,
  73.                     Channel = this.Channel,
  74.                     Message = this.Message,
  75.                     Color = color,
  76.                     IsRandomColor = isRandomColor,
  77.                     Emotes = new List<int>(this.Emotes),
  78.                     Groups = new List<string>(this.Groups)
  79.                 };
  80.  
  81.                 return message;
  82.             }
  83.  
  84.             public void Clear()
  85.             {
  86.                 User = null;
  87.                 Channel = null;
  88.                 Message = null;
  89.                 Color = null;
  90.                 Emotes.Clear();
  91.                 Groups.Clear();
  92.             }
  93.  
  94.             public override string ToString()
  95.             {
  96.                 return String.Format(@"User {0}[[{1}],[{2}]] to {3}{4}: {5}", User, string.Join(",", Groups), string.Join(",", Emotes), Channel, Color, Message);
  97.             }
  98.         }
  99.  
  100.         public class ChatMessageEventArgs : EventArgs
  101.         {
  102.             public string User { get; set; }
  103.             public string Channel { get; set; }
  104.             public string Message { get; set; }
  105.             public string Color { get; set; }
  106.             public bool IsRandomColor { get; set; }
  107.             public List<int> Emotes { get; set; }
  108.             public List<string> Groups { get; set; }
  109.            
  110.         }
  111.  
  112.         public IrcService()
  113.         {
  114.             messageStagers = new Dictionary<string, IrcMessageStager>(StringComparer.InvariantCultureIgnoreCase);
  115.         }
  116.  
  117.         private IrcMessageStager GetMessageStager(string user)
  118.         {
  119.             IrcMessageStager messageStager;
  120.             if (!messageStagers.TryGetValue(user, out messageStager))
  121.             {
  122.                 log.Debug("No message stager found for {0}, creating", user);
  123.                 messageStager = new IrcMessageStager()
  124.                 {
  125.                     User = user
  126.                 };
  127.  
  128.                 messageStagers.Add(user, messageStager);
  129.             }
  130.  
  131.             return messageStager;
  132.         }
  133.  
  134.         private void PurgeMessageStager(string user)
  135.         {
  136.             log.Debug("Purging message stager for {0}", user);
  137.             messageStagers.Remove(user);
  138.         }
  139.  
  140.         public bool Start()
  141.         {
  142.             log.Debug("Starting service");
  143.  
  144.             IrcUser ircUser;
  145.  
  146.             if (ircSettings.Data.IsAnonymous)
  147.             {
  148.                 log.Debug("Connection type set to anonymous");
  149.                 string nickname = GenerateRandomNickname();
  150.                 ircUser = new IrcUser(nickname, "justinfan");
  151.             }
  152.             else
  153.             {
  154.                 log.Debug("Connection type set to registered user");
  155.                 ircUser = new IrcUser(
  156.                     coreSettings.Data.TwitchUsername,
  157.                     "justinfan",
  158.                     coreSettings.Data.TwitchAuthorizationToken);
  159.             }
  160.  
  161.             log.Debug("Connecting to {0} with username {1}", ircSettings.Data.Server, ircUser.Nick);
  162.  
  163.             ircClient = new IrcClient(ircSettings.Data.Server, ircUser);
  164.  
  165.             ircClient.ConnectionComplete += HandleConnectionComplete;
  166.             ircClient.NetworkError += HandleNetworkError;
  167.             ircClient.NickInUse += HandleNickInUse;
  168.             ircClient.UserJoinedChannel += HandleUserJoinedChannel;
  169.             ircClient.PrivateMessageRecieved += HandlePrivateMessageRecieved;
  170.  
  171.             ircClient.ConnectAsync();
  172.             return true;
  173.         }
  174.  
  175.         public void Stop()
  176.         {
  177.             log.Debug("Stopping service");
  178.             ircClient.ConnectionComplete -= HandleConnectionComplete;
  179.             ircClient.NetworkError -= HandleNetworkError;
  180.             ircClient.NickInUse -= HandleNickInUse;
  181.             ircClient.UserJoinedChannel -= HandleUserJoinedChannel;
  182.             ircClient.PrivateMessageRecieved -= HandlePrivateMessageRecieved;
  183.  
  184.             try
  185.             {
  186.                 ircClient.Quit();
  187.             }
  188.             catch (Exception ex)
  189.             {
  190.                 log.Debug(ex, "IRC exited with an exception (99.99% ignorable)");
  191.             }
  192.  
  193.             ircClient = null;
  194.             channel = null;
  195.         }
  196.  
  197.         void HandlePrivateMessageRecieved(object sender, PrivateMessageEventArgs e)
  198.         {
  199.  
  200.             if (e.PrivateMessage.IsChannelMessage)
  201.             {
  202.                 if ("twitchnotify".Equals(e.PrivateMessage.User.Nick))
  203.                 {
  204.                     Match match = subscriptionNotificationRegex.Match(e.PrivateMessage.Message);
  205.                     if (match.Success && match.Groups.Count == 2)
  206.                     {
  207.                         log.Info("{0} subscribed to {1}", match.Groups[1].ToString(), e.PrivateMessage.Source);
  208.                         OnUserSubscribed(new ChatUserEventArgs(e.PrivateMessage.Source.Substring(1), match.Groups[1].ToString()));
  209.                     }
  210.                 }
  211.                 else
  212.                 {
  213.                     IrcMessageStager messageStager = GetMessageStager(e.PrivateMessage.User.Nick);
  214.  
  215.                     messageStager.Channel = e.PrivateMessage.Source;
  216.                     if (channel.UsersByMode['o'].Contains(messageStager.User))
  217.                     {
  218.                         messageStager.Groups.Add("moderator");
  219.                     }
  220.                     messageStager.Message = e.PrivateMessage.Message;
  221.  
  222.                     log.Debug(messageStager.ToString());
  223.  
  224.                     OnChatMessage(messageStager.Create());
  225.  
  226.                     PurgeMessageStager(e.PrivateMessage.User.Nick);
  227.                 }
  228.             }
  229.             else
  230.             {
  231.                 if (channel != null)
  232.                 {
  233.                     if ("jtv".Equals(e.PrivateMessage.User.Nick))
  234.                     {
  235.                         Match match;
  236.                         if (TryMatch(jtvMessage, e.PrivateMessage.Message, out match))
  237.                         {
  238.                             string type = match.Groups["type"].ToString().Trim();
  239.                             string user = match.Groups["user"].ToString().Trim();
  240.                             string arguments = match.Groups["arguments"].ToString().Trim();
  241.  
  242.  
  243.  
  244.                             switch (type)
  245.                             {
  246.                                 case "USERCOLOR":
  247.                                     {
  248.                                         log.Debug("Color for user {0} set to {1}", user, arguments);
  249.                                        
  250.                                         IrcMessageStager messageStager = GetMessageStager(user);
  251.                                         messageStager.Color = arguments;
  252.                                         break;
  253.                                     }
  254.                                 case "SPECIALUSER":
  255.                                     {
  256.                                         log.Debug("Set membership for user {0} to {1}", user, arguments);
  257.  
  258.                                         IrcMessageStager messageStager = GetMessageStager(user);
  259.                                         messageStager.Groups.Add(arguments);
  260.                                         break;
  261.                                     }
  262.                                 case "EMOTESET":
  263.                                     {
  264.                                         arguments = arguments.Replace("[", "").Replace("]", "");
  265.  
  266.                                         string[] emoteStrings = arguments.Split(',');
  267.                                         List<int> emotes = new List<int>();
  268.                                         foreach (string emote in emoteStrings)
  269.                                         {
  270.                                             int result;
  271.                                             if (!Int32.TryParse(emote, out result))
  272.                                             {
  273.                                                 log.Debug("User {0} had invalid emote. (Message: '{1}', Invalid Emote: '{2}')", user, e.PrivateMessage.Message, emote);
  274.                                                 continue;
  275.                                             }
  276.  
  277.                                             emotes.Add(result);
  278.                                         }
  279.  
  280.                                         if (emotes.Count != emoteStrings.Length)
  281.                                         {
  282.                                             log.Debug("User {0} unexpected emote count. (Expected: {1}, Found: {2})", user, emoteStrings.Length, emotes.Count);
  283.                                         }
  284.  
  285.                                         IrcMessageStager messageStager = GetMessageStager(user);
  286.                                         messageStager.Emotes.AddRange(emotes);
  287.                                         break;
  288.                                     }
  289.                                 case "CLEARCHAT":
  290.                                     {
  291.                                         log.Debug("Users {0} had their chat cleared by a moderator", user);
  292.                                         OnChatCleared(new ChatUserEventArgs(channel.Name, user));
  293.                                         break;
  294.                                     }
  295.                             }
  296.                         }
  297.                         else
  298.                         {
  299.                             log.Debug("Unknown JTV message '{0}'", e.PrivateMessage.Message);
  300.                             return;
  301.                         }
  302.                     }
  303.                 }
  304.             }
  305.         }
  306.  
  307.         private bool TryMatch(Regex regex, string message, out Match match)
  308.         {
  309.             return (match = regex.Match(message)).Success;
  310.         }
  311.  
  312.         void HandleConnectionComplete(object sender, EventArgs e)
  313.         {
  314.             log.Debug("Connected to server");
  315.             ircClient.SendRawMessage("TWITCHCLIENT 2");
  316.             ircClient.JoinChannel(ircSettings.Data.Channel);
  317.             ircClient.SendRawMessage("JTVROOMS {0}", ircSettings.Data.Channel);
  318.         }
  319.  
  320.         void HandleNickInUse(object sender, ChatSharp.Events.ErronousNickEventArgs e)
  321.         {
  322.             e.NewNick = GenerateRandomNickname();
  323.  
  324.             log.Debug("Nickname is use or invalid {0}, attempting to use {1}", e.InvalidNick, e.NewNick);
  325.         }
  326.  
  327.         void HandleNetworkError(object sender, ChatSharp.Events.SocketErrorEventArgs e)
  328.         {
  329.             log.Debug("Disconnected from server ({0})", e.SocketError);
  330.             OnChatDisconnected();
  331.         }
  332.  
  333.         void HandleUserJoinedChannel(object sender, ChatSharp.Events.ChannelUserEventArgs e)
  334.         {
  335.             log.Debug("{0} joined channel {1}", e.User, e.Channel.Name);
  336.             if (e.User.Nick.Equals(ircClient.User.Nick))
  337.             {
  338.                 channel = e.Channel;
  339.                 OnChatConnected();
  340.             }
  341.         }
  342.  
  343.         public event EventHandler ChatConnected;
  344.  
  345.         protected internal virtual void OnChatConnected()
  346.         {
  347.             if (ChatConnected != null)
  348.             {
  349.                 ChatConnected(this, new ChatConnectionEventArgs());
  350.             }
  351.         }
  352.  
  353.         public event EventHandler ChatDisconnected;
  354.  
  355.         protected internal virtual void OnChatDisconnected()
  356.         {
  357.             if (ChatDisconnected != null)
  358.             {
  359.                 ChatDisconnected(this, new ChatConnectionEventArgs());
  360.             }
  361.         }
  362.  
  363.         public event EventHandler<ChatUserEventArgs> UserJoined;
  364.  
  365.         protected internal virtual void OnUserJoined(ChatUserEventArgs e)
  366.         {
  367.             if (UserJoined != null)
  368.             {
  369.                 UserJoined(this, e);
  370.             }
  371.         }
  372.  
  373.         public event EventHandler<ChatUserEventArgs> UserSubscribed;
  374.  
  375.         protected internal virtual void OnUserSubscribed(ChatUserEventArgs e)
  376.         {
  377.             if (UserSubscribed != null)
  378.             {
  379.                 UserSubscribed(this, e);
  380.             }
  381.         }
  382.  
  383.         public event EventHandler<ChatMessageEventArgs> ChatMessage;
  384.  
  385.         protected internal virtual void OnChatMessage(ChatMessageEventArgs e)
  386.         {
  387.             if (ChatMessage != null)
  388.             {
  389.                 ChatMessage(this, e);
  390.             }
  391.         }
  392.  
  393.         public event EventHandler<ChatUserEventArgs> ChatCleared;
  394.  
  395.         protected internal virtual void OnChatCleared(ChatUserEventArgs e)
  396.         {
  397.             if (ChatCleared != null)
  398.             {
  399.                 ChatCleared(this, e);
  400.             }
  401.         }
  402.  
  403.         private string GenerateRandomNickname()
  404.         {
  405.             return String.Format("justinfan{0}", random.Next());
  406.         }
  407.  
  408.  
  409.         //Red, Green, Blue, FireBrick, YellowGreen, OrangeRed,
  410.         //SeaGreen, GoldenRod, Coral, Chocolate, CadetBlue, DodgerBlue, HotPink, BlueViolet, SpringGreen),
  411.         private static string[] TwitchColors =
  412.         {
  413.             "#FF0000", // Red
  414.             "#00FF00", // Green
  415.             "#0000FF", // Blue
  416.             "#B22222", // FireBrick
  417.             "#9ACD32", // YellowGreen
  418.             "#FF4500", // OrangeRed
  419.             "#2E8B57", // SeaGreen
  420.             "#DAA520", // GoldenRod
  421.             "#FF7F50", // Coral
  422.             "#D2691E", // Chocolate
  423.             "#5F9EA0", // CadetBlue
  424.             "#1E90FF", // DodgerBlue
  425.             "#FF69B4", // HotPink
  426.             "#8A2BE2", // BlueViolet
  427.             "#00FF7F"  // SpringGreen ... :(
  428.         };
  429.     }
  430.  
  431. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement