Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- using System.Text.RegularExpressions;
- using UnityEditor;
- using UnityEngine.Events;
- using System.Net.Sockets;
- using System.Threading;
- using System.IO;
- using System.Diagnostics;
- [System.Serializable]
- public class TwitchChat : MonoBehaviour {
- public Twitch twitchBox = new Twitch();
- [SerializeField] public string un;
- [SerializeField] public string pw;
- [SerializeField] public string ch;
- public void Start() {
- twitchBox.nickname = un;
- twitchBox.oauth = pw;
- twitchBox.channel = ch;
- twitchBox.messageRecievedEvent.AddListener(Inbox);
- }
- public void Update() {
- twitchBox.Tick();
- }
- public void Inbox(Twitch.MSGInfo msg) {
- UnityEngine.Debug.Log(msg.name + ": " + msg.message);
- foreach(CommandEntry i in commands) {
- Regex r = new Regex("^" + i.commandTrigger);
- if(r.IsMatch(msg.message)) {
- UnityEngine.Debug.Log(msg.name + " used " + i.commandName);
- i.action.Invoke();
- }
- }
- }
- public CommandEntry[] commands;
- public void SendChatMsg(string msg) {
- twitchBox.SendMsg(msg);
- }
- public void OnDisable() {
- twitchBox.StopTwitchChat();
- }
- }
- [System.Serializable]
- public class CommandEntry {
- [SerializeField] public string commandName;
- [SerializeField] public string commandTrigger;
- [SerializeField] public UnityEvent action;
- public CommandEntry (string name) {
- commandName = name;
- }
- }
- [CustomEditor(typeof(TwitchChat))]
- public class TwitchChatEditor : Editor {
- Twitch th;
- string msg;
- bool isActive;
- bool wasActive;
- public override void OnInspectorGUI() {
- th = (serializedObject.targetObject as TwitchChat).twitchBox;
- if (EditorApplication.isPlaying && Application.isPlaying) {
- GUI.enabled = false;
- }
- if(th != null) {
- isActive = EditorGUILayout.Foldout(isActive, "Configuration");
- if(isActive) {
- EditorGUILayout.PropertyField(serializedObject.FindProperty("un"), new GUIContent("Username:"));
- EditorGUILayout.PropertyField(serializedObject.FindProperty("pw"), new GUIContent("Password:"));
- if(GUILayout.Button("Open twitch.tv/tmi to get oauth/password")) {
- Application.OpenURL("https://twitch.tv/tmi");
- }
- EditorGUILayout.PropertyField(serializedObject.FindProperty("ch"), new GUIContent("Channel:"));
- GUILayout.Space(20);
- EditorGUILayout.PropertyField(serializedObject.FindProperty("commands"));
- GUILayout.Space(20);
- }
- GUI.enabled = true;
- if (!EditorApplication.isPlaying && !Application.isPlaying) {
- GUI.enabled = false;
- }
- if(th.isConnected) {
- if(GUILayout.Button("Disconnect from Twitch")) {
- th.StopTwitchChat();
- msg = "";
- }
- } else {
- if(GUILayout.Button("Connect to Twitch")) {
- th.StartTwitchChat();
- }
- }
- GUI.enabled = th.isConnected;
- GUILayout.BeginHorizontal();
- msg = GUILayout.TextField(msg);
- if (GUILayout.Button("Send", GUILayout.Width(60))) {
- th.SendMsg(msg);
- msg = "";
- }
- GUILayout.EndHorizontal();
- GUI.enabled = true;
- }
- if(serializedObject.hasModifiedProperties) {
- serializedObject.ApplyModifiedProperties();
- }
- }
- }
- public class Twitch {
- public string oauth;
- public string nickname;
- public string channel;
- public class MsgEvent : UnityEvent<MSGInfo> { }
- public MsgEvent messageRecievedEvent = new MsgEvent();
- [HideInInspector]
- public string server = "irc.twitch.tv";
- [HideInInspector]
- public int port = 6667;
- private string buffer = string.Empty;
- private bool stopThreads = false;
- private Queue<string> commandQueue = new Queue<string>();
- private List<string> recievedMsgs = new List<string>();
- private Thread inProc, outProc;
- private Regex r = new Regex("^(.*?)PRIVMSG.*?:(.*)$");
- private Regex r2 = new Regex("^(.*?):");
- [HideInInspector]
- public bool isConnected = false;
- private void StartIRC() {
- // start connection
- TcpClient sock = new TcpClient();
- sock.Connect(server, port);
- if (!sock.Connected) {
- // connection failed
- UnityEngine.Debug.Log("Failed to connect!");
- return;
- }
- // get stream-handlers
- NetworkStream networkStream = sock.GetStream();
- TextReader input = (new StreamReader(networkStream)) as TextReader;
- StreamWriter output = new StreamWriter(networkStream);
- // do the login
- output.WriteLine("PASS " + oauth);
- output.WriteLine("NICK " + nickname.ToLower());
- // add tags-request
- output.WriteLine("CAP REQ :twitch.tv/tags");
- output.Flush();
- // start threats
- isConnected = true;
- outProc = new Thread(() => IRCOutputProcedure(output));
- outProc.Start();
- inProc = new Thread(() => IRCInputProcedure(input, networkStream));
- inProc.Start();
- }
- private void IRCInputProcedure(TextReader input, NetworkStream networkStream) {
- while (!stopThreads) {
- if (!networkStream.DataAvailable) {
- continue;
- }
- buffer = input.ReadLine();
- if (buffer.Contains("PRIVMSG #")) {
- lock (recievedMsgs) {
- recievedMsgs.Add(buffer);
- }
- }
- if (buffer.StartsWith("PING ")) {
- SendCommand(buffer.Replace("PING", "PONG"));
- }
- if (buffer.Split(' ')[1] == "001") {
- SendCommand("JOIN #" + channel);
- }
- }
- isConnected = false;
- }
- private void IRCOutputProcedure(TextWriter output) {
- Stopwatch stopWatch = new Stopwatch();
- stopWatch.Start();
- while (!stopThreads) {
- lock (commandQueue) {
- if (commandQueue.Count > 0) {
- if (stopWatch.ElapsedMilliseconds > 1750) {
- output.WriteLine(commandQueue.Peek());
- output.Flush();
- commandQueue.Dequeue();
- stopWatch.Reset();
- stopWatch.Start();
- }
- }
- }
- }
- isConnected = false;
- }
- public void SendCommand(string cmd) {
- lock (commandQueue) {
- commandQueue.Enqueue(cmd);
- }
- }
- public void SendMsg(string msg) {
- lock (commandQueue) {
- commandQueue.Enqueue("PRIVMSG #" + channel + " :" + msg);
- }
- MSGInfo mi = new MSGInfo(new string[] {"color=#ff0000", "display-name=" + nickname, "subscriber=0", "mod=0"}, msg);
- messageRecievedEvent.Invoke(mi);
- }
- public void StartTwitchChat() {
- stopThreads = false;
- StartIRC();
- }
- public void StopTwitchChat() {
- stopThreads = true;
- }
- void OnDisable() {
- StopTwitchChat();
- }
- void OnDestroy() {
- StopTwitchChat();
- }
- public void Tick() {
- lock (recievedMsgs) {
- if (recievedMsgs.Count > 0) {
- for (int i = 0; i < recievedMsgs.Count; i++) {
- handleMsg(recievedMsgs[i]);
- }
- recievedMsgs.Clear();
- }
- }
- }
- private void handleMsg(string msg) {
- Match match = r.Match(msg);
- string infoBlock = match.Groups[1].Value;
- Match match2 = r2.Match(infoBlock);
- MSGInfo mi = new MSGInfo(match2.Groups[1].Value.Split(';'), match.Groups[2].Value);
- messageRecievedEvent.Invoke(mi);
- }
- public class MSGInfo {
- public string name {get; private set;}
- public Color color {get; private set;}
- public bool isSubscriber {get; private set;}
- public bool isModerator {get; private set;}
- public string message {get; private set;}
- public MSGInfo(string[] data, string txt) {
- message = txt;
- string colorData = "";
- foreach(string j in data) {
- string[] v = j.Split('=');
- if(v[0] == "display-name") {
- name = v[1];
- } else if(v[0] == "color") {
- colorData = v[1];
- } else if(v[0] == "subscriber") {
- isSubscriber = (v[1] == "1");
- } else if(v[0] == "mod") {
- isModerator = (v[1] == "1");
- }
- }
- color = cfu(name);
- if(colorData != "") {
- Color genColor = color;
- if(ColorUtility.TryParseHtmlString(colorData, out genColor)) {
- color = genColor;
- }
- }
- }
- private Color cfu(string username) {
- Random.InitState(username.Length + (int)username[0] + (int)username[username.Length - 1]);
- return new Color(Random.Range(0.25f, 0.55f), Random.Range(0.20f, 0.55f), Random.Range(0.25f, 0.55f));
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement