Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2017
536
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.70 KB | None | 0 0
  1. using UnityEngine;
  2. using UnityEngine.Events;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Threading;
  6. using System.IO;
  7. using System.Net.Sockets;
  8. using System;
  9.  
  10. public class IRCClient {
  11. public enum ConnectionState { DISCONNECTED, CONNECTING, CONNECTED };
  12. public UnityEvent OnConnected = new UnityEvent();
  13. public UnityEvent OnDisconnected = new UnityEvent();
  14. public MessageEvent OnMessage = new MessageEvent();
  15. public UnityEvent OnAuthenticationFailed = new UnityEvent();
  16. public UserStateReceivedEvent OnUserStateReceived = new UserStateReceivedEvent();
  17. public volatile ConnectionState connectionState = ConnectionState.DISCONNECTED;
  18. private string server;
  19. private int port;
  20. private string nickname;
  21. private string password;
  22. private TcpClient client;
  23. private NetworkStream socket;
  24. private StreamReader socketIn;
  25. private StreamWriter socketOut;
  26. private Thread readThread;
  27.  
  28. public IRCClient(string server, int port, string nickname, string password) {
  29. this.server = server;
  30. this.port = port;
  31. this.nickname = nickname;
  32. this.password = password;
  33.  
  34. OnConnected.AddListener(() => {
  35. connectionState = ConnectionState.CONNECTED;
  36. });
  37. }
  38.  
  39. public void Connect() {
  40. if (connectionState != ConnectionState.DISCONNECTED)
  41. throw new Exception("irc client connected or connecting");
  42.  
  43. connectionState = ConnectionState.CONNECTING;
  44. client = new TcpClient(server, port);
  45. socket = client.GetStream();
  46. socketIn = new StreamReader(socket);
  47. socketOut = new StreamWriter(socket);
  48.  
  49. SendRaw("PASS "+password);
  50. SendRaw("NICK "+nickname);
  51. SendRaw("USER "+nickname+" 0 * :"+nickname);
  52.  
  53. readThread = new Thread(() => ReadThread());
  54. readThread.Start();
  55. }
  56.  
  57. private void ReadThread() {
  58. // :joefrompixelmaniacs!joefrompixelmaniacs@joefrompixelmaniacs.tmi.twitch.tv PRIVMSG #pixel_maniacs :MVGame
  59. // @badges=;color=#1E90FF;display-name=Niceguy_3210;emotes=;id=cbda9782-8021-44a3-9e43-04dac248ce33;mod=0;room-id=122085144;sent-ts=1481462264220;subscriber=0;tmi-sent-ts=1481462262017;turbo=0;user-id=72111011;user-type= :niceguy_3210!niceguy_3210@niceguy_3210.tmi.twitch.tv PRIVMSG #pixel_maniacs :Registration is now open. Type !dance <Number of beers> to enter
  60. // @badges=premium/1;color=#57001D;display-name=Joe16_;emotes=;id=ec9dac1c-ab89-433d-91de-f3737a77e479;mod=0;room-id=122085144;sent-ts=1481462307547;subscriber=0;tmi-sent-ts=1481462296699;turbo=0;user-id=115813457;user-type= :joe16_!joe16_@joe16_.tmi.twitch.tv PRIVMSG #pixel_maniacs :!dance math.sqrt(pi)
  61. // @badges=moderator/1;color=#0000FF;display-name=Lumiangames;emotes=;id=94a3815a-955e-419e-b282-b9abb7ba7f48;mod=1;room-id=122085144;sent-ts=1481462296568;subscriber=0;tmi-sent-ts=1481462297531;turbo=0;user-id=64742088;user-type=mod :lumiangames!lumiangames@lumiangames.tmi.twitch.tv PRIVMSG #pixel_maniacs :lel, du droll XD
  62. //@badges=broadcaster/1;color=;display-name=pixel_maniacs;emotes=;id=52a3a89b-2c4f-4cd3-8f9d-dc366e57d02d;mod=0;room-id=122085144;sent-ts=1481467694637;subscriber=0;tmi-sent-ts=1481467694820;turbo=0;user-id=122085144;user-type= :pixel_maniacs!pixel_maniacs@pixel_maniacs.tmi.twitch.tv PRIVMSG #pixel_maniacs :bello
  63. //@badges=broadcaster/1;color=;display-name=pixel_maniacs;emotes=;id=afc572a6-efa0-4cbf-b16d-be6fcfa162a2;mod=0;room-id=122085144;sent-ts=1481467695965;subscriber=0;tmi-sent-ts=1481467696143;turbo=0;user-id=122085144;user-type= :pixel_maniacs!pixel_maniacs@pixel_maniacs.tmi.twitch.tv PRIVMSG #pixel_maniacs :test
  64.  
  65. string line;
  66. while (connectionState != ConnectionState.DISCONNECTED && (line = socketIn.ReadLine()) != null) {
  67. //Debug.Log("> "+line);
  68.  
  69. string[] parts = line.Split(' ');
  70.  
  71. //for(int i = 0; i < parts.Length; i++)
  72. //{
  73. // Debug.Log("part " + i + " => " + parts[i]);
  74. //}
  75.  
  76.  
  77. if (parts[0] == "PING") {
  78. SendRaw("PONG "+parts[1]);
  79. } else if (parts[1] == "001") {
  80.  
  81. Debug.LogWarning("Connected " + line);
  82. UnityMainThreadDispatcher.Instance().Enqueue(() => {
  83. OnConnected.Invoke();
  84. });
  85. continue;
  86. } else if (parts[0].StartsWith("@") && parts[2] == "PRIVMSG") {
  87. string channel = parts[3];
  88. Dictionary<string,string> data = ParseQueryString(parts[0].Substring(1));
  89.  
  90. string color = data["color"];
  91. if (color == "") color = "#000000";
  92.  
  93. string username = parts[1].Substring(1, parts[1].IndexOf('!') - 1);
  94.  
  95. User user = new User(Int32.Parse(data["user-id"]), username, data["display-name"], color, data["user-type"] == "mod" || data["badges"].Contains("broadcaster"), data["badges"].Contains("broadcaster"), data["subscriber"] == "1");
  96. string message = String.Join(" ", new List<string>(parts).GetRange(4, parts.Length-4).ToArray()).Substring(1);
  97. UnityMainThreadDispatcher.Instance().Enqueue(() => {
  98. OnMessage.Invoke(channel, user, message);
  99. });
  100. continue;
  101. } else if (parts[0].StartsWith("@") && parts[2] == "USERSTATE") {
  102. //@badges=moderator/1;color=;display-name=metalmoshpitbot;emote-sets=0;mod=1;subscriber=0;user-type=mod :tmi.twitch.tv USERSTATE #pixel_maniacs
  103. string channel = parts[3];
  104. Dictionary<string,string> data = ParseQueryString(parts[0].Substring(1));
  105.  
  106. string color = data["color"];
  107. if (color == "") color = "#000000";
  108.  
  109. string username = data["display-name"].ToLower();
  110. User user = new User(0, username, data["display-name"], color, data["user-type"] == "mod" || data["badges"].Contains("broadcaster"), data["badges"].Contains("broadcaster"), data["subscriber"] == "1");
  111. UnityMainThreadDispatcher.Instance().Enqueue(() => {
  112. OnUserStateReceived.Invoke(user, channel);
  113. });
  114. continue;
  115. } else if (parts[0].StartsWith(":") && parts[1] == "PRIVMSG") {
  116. string channel = parts[2];
  117. User user = new User(parts[0].Substring(1, parts[0].IndexOf('!') - 1));
  118. string message = String.Join(" ", new List<string>(parts).GetRange(3, parts.Length-3).ToArray()).Substring(1);
  119. UnityMainThreadDispatcher.Instance().Enqueue(() => {
  120. OnMessage.Invoke(channel, user, message);
  121. });
  122. continue;
  123. } else if (parts[0] == ":tmi.twitch.tv" && parts[1] == "NOTICE" && parts[3] == ":Login") {
  124. UnityMainThreadDispatcher.Instance().Enqueue(() => {
  125. OnAuthenticationFailed.Invoke();
  126. });
  127. continue;
  128. }
  129. }
  130.  
  131. if (connectionState != ConnectionState.DISCONNECTED) {
  132. Debug.LogWarning("IRCClient disconnected");
  133. UnityMainThreadDispatcher.Instance().Enqueue(() => {
  134. Disconnect();
  135. OnDisconnected.Invoke();
  136. });
  137. }
  138. }
  139.  
  140. public void SendRaw(string message) {
  141. //Debug.Log("< "+message);
  142. socketOut.WriteLine(message);
  143. socketOut.Flush();
  144. }
  145.  
  146. public void Join(string channel) {
  147. SendRaw("JOIN "+channel);
  148. }
  149.  
  150. public void RequestCapability(string capability) {
  151. SendRaw("CAP REQ :"+capability);
  152. }
  153.  
  154. public void Part(string channel) {
  155. SendRaw("PART "+channel);
  156. }
  157.  
  158. public void SendMessage(string channel, string message) {
  159. SendRaw("PRIVMSG "+channel+" :"+message);
  160. }
  161.  
  162. public void Disconnect() {
  163. if (connectionState == ConnectionState.DISCONNECTED)
  164. throw new Exception("irc client disconnected");
  165.  
  166. connectionState = ConnectionState.DISCONNECTED;
  167. readThread.Abort();
  168. socket.Close();
  169. client.Close();
  170. }
  171.  
  172. private Dictionary<string,string> ParseQueryString(string qs) {
  173. Dictionary<string,string> data = new Dictionary<string,string>();
  174. string[] args = qs.Split(';');
  175. foreach (string arg in args) {
  176. string[] parts = arg.Split('=');
  177. data[parts[0]] = parts[1];
  178. }
  179. return data;
  180. }
  181.  
  182. public class MessageEvent : UnityEvent<string,User,string> {}
  183. public class UserStateReceivedEvent : UnityEvent<User,string> {}
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement