Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections.Generic;
- using UnityEngine;
- using System;
- using System.Net.Sockets;
- using System.IO;
- using UnityEngine.UI;
- using System.Text.RegularExpressions;
- using System.Linq;
- using UnityEngine.EventSystems;
- using TMPro;
- [ExecuteInEditMode]
- public class TwitchChat : MonoBehaviour
- {
- public LineData selfUserData; // collected from GLOBALUSERSTATE on login
- public TMP_SpriteAsset defSpriteAsset;
- VerticalLayoutGroup contentGroup;
- public GameObject chatMessagePrefab;
- //for sending messages to chat
- public TMPro.TMP_InputField inputField;
- private TcpClient twitchClient;
- private StreamReader reader;
- private StreamWriter writer;
- public bool verbose = false;
- public bool connected = false;
- public List<EmojiPacker.TextureAtlas> textureAtlases = new List<EmojiPacker.TextureAtlas>();
- public void updateLookupTables()
- {
- defSpriteAsset.UpdateLookupTables();
- }
- public string username, password, channelName; //pw from: https://twitchapps.com/tmi
- public EmoteJsonDataManager jsonDataManager;
- public EmojiPacker emojiPacker;
- public delegate void Command(string[] commandData);
- public static Command CommandEventHandler;
- public void OnEnable()
- {
- contentGroup = transform.FindDeepChild("ChatLog").GetComponent<VerticalLayoutGroup>();
- //Connect();
- //jsonDataManager = new EmoteJsonDataManager(Application.dataPath +"/");
- //jsonDataManager.LoadData(this);
- //emojiPacker = new EmojiPacker();
- //building a list of all the global id's for the sprite packer
- //string[] ids = new string[jsonDataManager.globalData.Keys.Count/20];
- //string[] names = jsonDataManager.globalData.Keys.ToArray();
- //for (int i = 0; i < ids.Length; i++)
- //{
- // ids[i] = jsonDataManager.globalData[names[i]].id.ToString();
- //}
- //StartCoroutine(emojiPacker.PackIDS(this, ids, FilterMode.Point, 2048,
- // (t2d, dict_idStr_uvRect) => {
- // StartCoroutine(emojiPacker.SaveTexture(t2d, Application.dataPath + "/Resources/Sprite Assets/Global.png"));
- // defSpriteAsset.spriteInfoList.Clear();
- // defSpriteAsset.spriteSheet = t2d; // this produces a TypeMismatch in unity and doesnt seem to work;
- // for (int j = 0; j < ids.Length; j++)
- // {
- // string id = ids[j];
- // string name = names[j];
- // var rect = dict_idStr_uvRect[id];
- // var sprite = new TMP_Sprite
- // {
- // id = j,
- // name = name.ToLower(),
- // x = rect.x * t2d.width,
- // y = rect.y * t2d.height,
- // width = rect.width * t2d.width,
- // height = rect.height * t2d.height,
- // unicode = 0,
- // hashCode = 0,
- // xOffset = 0,
- // pivot = Vector2.zero,
- // sprite = null,
- // scale = 1,
- // yOffset = rect.width * t2d.width * .833f,
- // xAdvance = rect.width * t2d.width
- // };
- // defSpriteAsset.spriteInfoList.Add(sprite);
- // }
- // defSpriteAsset.UpdateLookupTables();
- // Debug.Log(defSpriteAsset.GetSpriteIndexFromName("kappa"));
- // //defSpriteAsset.fallbackSpriteAssets.Add((TMP_SpriteAsset));
- //}));
- }
- public void OnDisable()
- {
- jsonDataManager = null;
- if (twitchClient != null)
- {
- twitchClient.Close();
- }
- if (contentGroup != null)
- {
- for (int i = contentGroup.transform.childCount - 1; i >= 0; i--)
- {
- }
- }
- }
- //public void Start()
- //{
- // if (!jsonDataManager.loaded)
- // {
- // jsonDataManager.LoadData(this);
- // }
- // Connect();
- //}
- bool allowEnter;
- void Update()
- {
- if (twitchClient == null)
- {
- Connect();
- return;
- }
- if (!twitchClient.Connected)
- {
- Connect();
- return;
- }
- ReadChat();
- if (allowEnter && (inputField.text.Length > 0) && (Input.GetKey(KeyCode.Return) || Input.GetKey(KeyCode.KeypadEnter)))
- {
- SendChat();
- inputField.text = "";
- allowEnter = false;
- }
- else
- {
- allowEnter = inputField.isFocused;
- }
- if (contentGroup.transform.childCount > 10)
- {
- var child = contentGroup.transform.GetChild(0);
- DestroyImmediate(child.gameObject);
- }
- }
- private void Connect()
- {
- twitchClient = new TcpClient("irc.chat.twitch.tv", 6667);
- reader = new StreamReader(twitchClient.GetStream());
- writer = new StreamWriter(twitchClient.GetStream());
- writer.WriteLine("CAP REQ :twitch.tv/tags twitch.tv/commands twitch.tv/membership");
- writer.Flush();
- writer.WriteLine("PASS " + Oauth.auth);
- writer.WriteLine("NICK " + username);
- writer.WriteLine("USER " + username + " 8 * :" + username);
- writer.WriteLine("JOIN #" + channelName);
- writer.Flush();
- connected = true;
- }
- public void Send(string text)
- {
- writer.WriteLine(text);
- writer.Flush();
- }
- public void SendChat()
- {
- if (inputField != null)
- {
- writer.WriteLine($"PRIVMSG #{channelName} :{inputField.text}");
- writer.Flush();
- var newMessage = Instantiate(chatMessagePrefab, contentGroup.transform);
- var tmp = newMessage.GetComponent<TMPro.TextMeshProUGUI>();
- tmp.text = "<" + selfUserData.colorHex + ">" + username + "</color>: " + inputField.text;
- }
- }
- private void ReadChat()
- {
- if (twitchClient.Available > 0)
- {
- var message = reader.ReadLine(); //Read in the current message
- if (message == "PING :tmi.twitch.tv")
- {
- Send("PONG :tmi.twitch.tv");
- Debug.Log("PONG :tmi.twitch.tv");
- } else if (message.Contains("GLOBALUSERSTATE"))
- {
- //Recieved GLOBALUSERSTATE data
- selfUserData = new LineData(message);
- } else if (message.Contains("PRIVMSG"))
- {
- LineData data = new LineData(message);
- //matching pattern !<command> <value>
- Match commandMatch = Regex.Match(data.chatText, "^!(\\w+)\\s(-?\\d+\\.?\\d*|\"(.*)\")");
- if (commandMatch.Success)
- {
- string[] commandArray = new string[commandMatch.Groups.Count - 1];
- for (int i = 0; i < commandArray.Length; i++)
- {
- commandArray[i] = commandMatch.Groups[i+1].Value;
- }
- CommandEventHandler(commandArray);
- }
- var newMessage = Instantiate(chatMessagePrefab, contentGroup.transform);
- var tmp = newMessage.GetComponent<TMPro.TextMeshProUGUI>();
- tmp.text = "<" + data.colorHex + ">" + data.displayName + "</color>: " + data.chatText ;
- //chatBox.text = chatBox.text + "\n" + String.Format("{0}: {1}", chatName, message);
- }else if (verbose)
- {
- print(message);
- }
- }
- }
- public void ClearChatLog()
- {
- for (int i = contentGroup.transform.childCount - 1; i >= 0; i--)
- {
- DestroyImmediate(contentGroup.transform.GetChild(i).gameObject);
- }
- }
- }
- interface ICommand
- {
- void OnCommand(string[] commandText);
- }
- //https://dev.twitch.tv/docs/irc PRIVMSG
- // EXAMPLE:
- // @badges=<badges>;color=<color>;display-name=<display-name>;emotes=<emotes>;id=<id-of-msg>;mod=<mod>;room-id=<room-id>;
- // subscriber=<subscriber>;tmi-sent-ts=<timestamp>;turbo=<turbo>;user-id=<user-id>;user-type=<user-type>
- // :<user>!<user>@<user>.tmi.twitch.tv PRIVMSG #<channel> :<message>
- //
- //Decomposing chat message from a user
- [System.Serializable]
- public class LineData
- {
- public Color color = Color.white;
- public string colorHex = "";
- public string displayName = "";
- public bool mod = false;
- public bool subscriber = false;
- public bool turbo = false;
- public string badges = "";
- public string emotes = "";
- public string id = "";
- public string roomID = "";
- public string tmi_timestamp = "";
- public string userID = "";
- public string userType = "";
- public bool emoteOnly = false;
- public string channel = "";
- public string chatText = "";
- public LineData(string messageText)
- {
- MatchCollection regexData = Regex.Matches(messageText.Substring(0, messageText.IndexOf("PRIVMSG")), @"(?<key>[\w-]+)(?:=)(?<value>[:\w\,d\/\#\-]+)?");
- Dictionary<string, string> matchData = regexData.Cast<Match>().ToDictionary(
- m => m.Groups["key"].Value,
- m => m.Groups["value"].Value
- );
- foreach (var item in matchData)
- {
- switch (item.Key)
- {
- case "badges":
- badges = item.Value;
- break;
- case "display-name":
- displayName = item.Value;
- break;
- case "emotes":
- emotes = item.Value;
- break;
- case "emote-only":
- emoteOnly = item.Value == "1";
- break;
- case "id":
- id = item.Value;
- break;
- case "color":
- if (item.Value.Length < 7)
- {
- color = new Color(218 / 255f, 156 / 255f, 28 / 255f);
- colorHex = "#" + 218.ToString("X2") + 156.ToString("X2") + 28.ToString("X2");
- }
- else
- {
- colorHex = item.Value;
- int r = Convert.ToInt32(item.Value.Substring(1, 2), 16);
- int g = Convert.ToInt32(item.Value.Substring(3, 2), 16);
- int b = Convert.ToInt32(item.Value.Substring(5, 2), 16);
- color = new Color(r / 255f, g / 255f, b / 255f);
- }
- break;
- case "mod":
- mod = item.Value == "1";
- break;
- case "room-id":
- roomID = item.Value;
- break;
- case "tmi-sent-ts":
- tmi_timestamp = item.Value;
- break;
- case "turbo":
- turbo = item.Value == "1";
- break;
- case "user-id":
- userID = item.Value;
- break;
- case "user-type":
- userType = item.Value;
- break;
- }
- }
- var chatMatch = Regex.Match(messageText, @"(?:PRIVMSG.)#(\w+) :(.+)");
- if (chatMatch.Success)
- {
- channel = chatMatch.Groups[1].Value;
- chatText = chatMatch.Groups[2].Value;
- }
- }
- string getAfterEquals(string str)
- {
- return str.Substring(str.IndexOf('=')+1);
- }
- public interface ITwitchCommandEvents : IEventSystemHandler
- {
- // functions that can be called via the messaging system
- void OnChatTwitchCommand(LineData message);
- void Message2();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement