Advertisement
Guest User

TwitchChat.cs

a guest
Jun 24th, 2021
1,513
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.97 KB | None | 0 0
  1. using System.IO;
  2. using System.Net.Sockets;
  3. using UnityEngine;
  4. using System;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using UnityEngine.Networking;
  8. using System.Linq;
  9. using TMPro;
  10.  
  11. [Serializable]
  12. public class ChatAvatar
  13. {
  14.     public string UserName;
  15.     public Color color;
  16. }
  17.  
  18. public class TwitchChat : MonoBehaviour
  19. {
  20.  
  21.     private TcpClient twitchClient;
  22.     private StreamReader reader;
  23.     private StreamWriter writer;
  24.     //Oauth password can be generated at https://twitchapps.com/tmi
  25.     // [HideInInspector]
  26.     public string username, password, channel;
  27.  
  28.     public string custom_rewards_id;
  29.  
  30.     public GameObject emotePrefab;
  31.  
  32.     public Transform startPoint;
  33.  
  34.     public TextMeshProUGUI chatBox;
  35.  
  36.     public GameObject avatarSpawn;
  37.  
  38.     public List<ChatAvatar> avatars = new List<ChatAvatar>();
  39.     // testing index
  40.     int indext = 0;
  41.     void Start()
  42.     {
  43.         Connect();
  44.     }
  45.  
  46.     void Update()
  47.     {
  48.         // if not connected, reconnect
  49.         if (!twitchClient.Connected)
  50.         {
  51.             Connect();
  52.         }
  53.  
  54.         // testing
  55.         if (Input.GetKeyDown(KeyCode.A))
  56.         {
  57.             ConvertText("testing" + indext, "Testing Chat");
  58.             CheckAvatars("testing" + indext);
  59.             indext++;
  60.  
  61.         }
  62.  
  63.         ProcessChat();
  64.     }
  65.  
  66.  
  67.     IEnumerator GetTexture(string url)
  68.     {
  69.         // find the emote texture
  70.         UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
  71.         yield return www.SendWebRequest();
  72.  
  73.         // set it to an image, and spawn a particle with that image
  74.         Texture2D img = DownloadHandlerTexture.GetContent(www);
  75.         GameObject emotePart = Instantiate(emotePrefab, startPoint.position, startPoint.rotation);
  76.         emotePart.GetComponent<ParticleSystem>().GetComponent<Renderer>().material.mainTexture = img;
  77.  
  78.     }
  79.  
  80.     private void Connect()
  81.     {
  82.         // log into the twitch chat of a channel
  83.         twitchClient = new TcpClient("irc.chat.twitch.tv", 6667);
  84.         reader = new StreamReader(twitchClient.GetStream());
  85.         writer = new StreamWriter(twitchClient.GetStream());
  86.         writer.WriteLine("PASS " + password);
  87.         writer.WriteLine("NICK " + username);
  88.         writer.WriteLine("USER " + username + " 8 * :" + username);
  89.         writer.WriteLine("JOIN #" + channel);
  90.         // add the capabilities for more info
  91.         writer.WriteLine("CAP REQ :twitch.tv/tags");
  92.         writer.WriteLine("CAP REQ :twitch.tv/commands");
  93.         writer.WriteLine("CAP REQ :twitch.tv/membership");
  94.         writer.Flush();
  95.     }
  96.  
  97.     private void ProcessChat()
  98.     {
  99.         // check if there is any data to read
  100.         if (twitchClient.Available > 0)
  101.         {
  102.             string message = reader.ReadLine();
  103.             print(message);
  104.             // if its a chat message and not an event, it has PRIVMSG in it
  105.             if (message.Contains("PRIVMSG"))
  106.             {
  107.                 // if the emotes list is not empty, get the emote texture
  108.                 if (!message.Contains("emotes=;"))
  109.                 {
  110.                     string[] stringSeparatorsE = new string[] { "emotes=" };
  111.                     string[] resultE = message.Split(stringSeparatorsE, StringSplitOptions.None);
  112.                     // split the emote string in case of multiple emotes
  113.                     var splitPointallEmotes = resultE[1].IndexOf(";", 0);
  114.                     var allemotes = resultE[1].Substring(0, splitPointallEmotes);
  115.                     string[] seperateEmotes = allemotes.Split('/');
  116.                     // grab all emote textures
  117.                     for (int i = 0; i < seperateEmotes.Length; i++)
  118.                     {
  119.                         var id = seperateEmotes[i].IndexOf(":", 0);
  120.                         var emoteID = seperateEmotes[i].Substring(0, id);
  121.                         // 1.0 / 2.0 / 3.0 is texture sizes
  122.                         StartCoroutine(GetTexture("https://static-cdn.jtvnw.net/emoticons/v1/" + emoteID + "/3.0"));
  123.                     }
  124.                 }
  125.                 // check if chatter is a subscriber
  126.                 if (message.Contains("@badge-info=subscriber"))
  127.                 {
  128.                     print("this person is a subscriber");
  129.                 }
  130.                 // custom reward
  131.                 if (message.Contains("custom-reward-id=" + custom_rewards_id))
  132.                 {
  133.                     print("Redeemed a custom reward");
  134.                 }
  135.                 // get the name
  136.                 string[] stringSeparators = new string[] { "display-name=" };
  137.                 string[] result = message.Split(stringSeparators, StringSplitOptions.None);
  138.                 var splitPoint = result[1].IndexOf(";", 0);
  139.                 var chatName = result[1].Substring(0, splitPoint);
  140.  
  141.                 //Get the users message by splitting it from the string
  142.                 string[] stringSeparators2 = new string[] { "PRIVMSG" };
  143.                 string[] result2 = message.Split(stringSeparators2, StringSplitOptions.None);
  144.                 var splitPoint2 = result2[1].Split(':');
  145.                 string chatText = splitPoint2[1];
  146.                 //output the username and chat message
  147.                 ConvertText(chatName, chatText);
  148.                 CheckAvatars(chatName);
  149.             }
  150.             //reply to ping to stay connected
  151.             if (message.Contains("PING :tmi.twitch.tv"))
  152.             {
  153.                 writer.WriteLine("PONG " + "tmi.twitch.tv" + "\r\n");
  154.                 writer.Flush();
  155.                 print("replied");
  156.             }
  157.         }
  158.     }
  159.  
  160.     void ConvertText(string chatName, string chatText)
  161.     {
  162.         // set the username and text to the text box
  163.         chatBox.text += "<color=blue>" + chatName + "</color> :" + chatText + "\n";
  164.     }
  165.  
  166.     ChatAvatar AddNewAvatar(string UserName)
  167.     {
  168.         // set avatar data
  169.         ChatAvatar newAv = new ChatAvatar();
  170.         newAv.UserName = UserName;
  171.         newAv.color = UnityEngine.Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f);
  172.         return newAv;
  173.     }
  174.     void CheckAvatars(string name)
  175.     {
  176.         // check if avatar is already in list
  177.         if (avatars.Any(x => x.UserName == name))
  178.         {
  179.             return;
  180.         }
  181.         // otherwise add it and a spawn an avatar
  182.         else
  183.         {
  184.             ChatAvatar newAvatar = AddNewAvatar(name);
  185.             avatars.Add(newAvatar);
  186.             SpawnNewAv(newAvatar);
  187.         }
  188.     }
  189.  
  190.     void SpawnNewAv(ChatAvatar data)
  191.     {
  192.         // spawn a new avatar from startPoint, and set its color, username, and give it a little push
  193.         GameObject spawned = Instantiate(avatarSpawn);
  194.         spawned.transform.position = startPoint.transform.position;
  195.         spawned.GetComponent<Renderer>().material.color = data.color;
  196.         spawned.GetComponentInChildren<TextMeshPro>().text = data.UserName;
  197.         spawned.GetComponent<Rigidbody>().velocity = Vector3.right * UnityEngine.Random.Range(0.5f, 1.5f);
  198.     }
  199.  
  200. }
  201.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement