Twitch Integrations - 用大写字母获取聊天者的角色和名字

Twitch Integrations - Getting chatter's roles and name with capital letters

我通过几个不同的来源创建了一个 class 来连接、保持连接、阅读和与选定的 Twitch 频道互动,但似乎没有关于如何做某些事情的信息。

其中一个问题是聊天者的名字总是全部小写。 另一个问题是似乎没有任何用户信息。即他们是 mod、订户、VIP 吗?

虽然角色部分对我来说不是那么重要,但我希望名称的大小写适当。

有什么技巧可以做到这一点吗?

using System;
using System.IO;
using System.Net.Sockets;
using UnityEngine;

public class TwitchConnect : MonoBehaviour
{
    public static TwitchConnect instance;

    public TwitchAccountData TwitchSettings = new();

    public event Action<string, string> OnChatMessage;
    public event Action<string> OnLoggedIn;
    public event Action OnLoggedOut;
    public event Action<string> OnInvalidLogin;

    public bool loggedIn = false;

    private TcpClient Twitch;
    private StreamReader Reader;
    private StreamWriter Writer;

    //private const string URL = "irc.chat.twitch.tv";
    private const string URL = "irc.twitch.tv";
    private const int PORT = 6667;

    private float PingCounter = 0;

    private string saveTwitchPath = "twitchauth.json";

    private void Awake()
    {
        DontDestroyOnLoad(gameObject);

        instance = this;

        saveTwitchPath = Application.persistentDataPath + "/twitchauth.json";

        LoadAccount();
    }

    public void UpdateAccount(string nUser, string nOAuth, string nChannel)
    {
        TwitchSettings.User = nUser;
        TwitchSettings.OAuth = nOAuth;
        TwitchSettings.Channel = nChannel;
    }

    public void ConnectToTwitch()
    {
        DisconnectFromTwitch();

        Twitch = new TcpClient(URL, PORT);
        Reader = new StreamReader(Twitch.GetStream());
        Writer = new StreamWriter(Twitch.GetStream());

        TwitchSettings.User = TwitchSettings.User.ToLower();
        TwitchSettings.Channel = TwitchSettings.Channel.ToLower();

        Writer.WriteLine("PASS " + TwitchSettings.OAuth);
        Writer.WriteLine("NICK " + TwitchSettings.User);
        Writer.WriteLine($"USER {TwitchSettings.User} 8 * :{TwitchSettings.User}");
        Writer.WriteLine("JOIN #" + TwitchSettings.Channel);
        Writer.Flush();//initiate connection
    }

    public void DisconnectFromTwitch()
    {
        loggedIn = false;
        PingCounter = 0;

        Twitch?.Dispose();
        Reader?.Dispose();
        Writer?.Dispose();

        Twitch = null;
        Reader = null;
        Writer = null;

        OnLoggedOut?.Invoke();
    }

    public void SaveAccount()
    {
        string jsonTwitch = JsonUtility.ToJson(TwitchSettings, true);
        File.WriteAllText(saveTwitchPath, jsonTwitch, System.Text.Encoding.Unicode);

        Debug.LogWarning("Twitch account settings saved!");
    }

    public void LoadAccount()
    {
        //twitch saved account settings - user, oauth, channel
        if (File.Exists(saveTwitchPath))
        {
            string jsonSettings = File.ReadAllText(saveTwitchPath, System.Text.Encoding.Unicode);
            JsonUtility.FromJsonOverwrite(jsonSettings, TwitchSettings);

            Debug.LogWarning("Twitch account loaded, logging in...");

            ConnectToTwitch();
        }
    }

    public void SendIrcMessage(string message)
    {
        Writer.WriteLine(message);
        Writer.Flush();
    }

    public void SendChatMessage(string message)
    {
        Writer.WriteLine($":{TwitchSettings.User}!{TwitchSettings.User}@{TwitchSettings.User}.tmi.twitch.tv PRIVMSG #{TwitchSettings.Channel} :{message}");
        Writer.Flush();
    }

    private void Update()
    {
        if (Twitch == null) return;

        if (!Twitch.Connected && loggedIn)
        {
            ConnectToTwitch();
        }

        PingCounter += Time.deltaTime;
        if (PingCounter > 50)
        {
            Writer.WriteLine("PING " + URL);
            Writer.Flush();
            PingCounter = 0;
        }
        
        if (Twitch.Available > 0)
        {
            string message = Reader.ReadLine();
#if UNITY_EDITOR
            Debug.Log(message);//DEBUG
#endif

            if (message.Contains("PRIVMSG"))
            {
                int splitPoint = message.IndexOf("!");
                string chatter = message[1..splitPoint];//get chatter name

                splitPoint = message.IndexOf(":", 1);
                string msg = message[(splitPoint + 1)..];//get message only

                OnChatMessage?.Invoke(chatter, msg);
            }
            else if (message.Contains(":Welcome, GLHF!"))//successful login
            {
                SaveAccount();

                loggedIn = true;
                OnLoggedIn?.Invoke(TwitchSettings.User);
            }
            else if (message.Contains(":Invalid NICK"))
            {
                OnInvalidLogin?.Invoke("Invalid NICK");
            }
            else if (message.Contains(":Improperly formatted auth"))
            {
                OnInvalidLogin?.Invoke("Improperly formatted auth");
            }
        }
    }

    private void OnDestroy()
    {
        DisconnectFromTwitch();
    }
}

对于 TMI - Twitch 消息接口获取显示名称和角色信息,您需要启用一些 IRCv3 功能,然后更新您的解析器以提取数据。

在通过之前你应该发送

CAP REQ :twitch.tv/commands twitch.tv/tags

所以,

Writer.WriteLine("PASS " + TwitchSettings.OAuth);

变成

Writer.WriteLine("CAP REQ :twitch.tv/commands twitch.tv/tags");
Writer.WriteLine("PASS " + TwitchSettings.OAuth);

启用附加数据 - https://dev.twitch.tv/docs/irc/capabilities

这会将额外数据添加到 Twitch 发送的 PRIVMSG 中。

这些通常被称为 IRCv3 标签。

这是文档中的示例

@badge-info=;badges=broadcaster/1;client-nonce=28e05b1c83f1e916ca1710c44b014515;color=#0000FF;display-name=foofoo;emotes=62835:0-10;first-msg=0;flags=;id=f80a19d6-e35a-4273-82d0-cd87f614e767;mod=0;room-id=713936733;subscriber=0;tmi-sent-ts=1642696567751;turbo=0;user-id=713936733;user-type= :foofoo!foofoo@foofoo.tmi.twitch.tv PRIVMSG #bar :bleedPurple

https://dev.twitch.tv/docs/irc/send-receive-messages#receiving-chat-messages

这个用户:

  • 在频道bar
  • 中发送了消息bleedpurple
  • display-name of foofoo 这将是用户的首字母大写字母 如果用户设置了
  • 拥有 broadcaster 的徽章(所述徽章的第 1 版)

因此,对于 VIP 或版主,您将监控 vipmoderator 的徽章,依此类推,以查找您正在寻找的任何角色。

进一步阅读 https://dev.twitch.tv/docs/irc/tags#privmsg-tags

一些徽章示例:

Comma-separated list of chat badges in the form, <badge>/<version>. For example, admin/1. There are many possible badge values, but here are few:
admin
bits
broadcaster
moderator
subscriber
staff
turbo

您通常会戳徽章 API(频道或全球)以获取可用徽章和这些徽章的版本。

但是基于重要角色的徽章在这个非详尽的列表中。