using Godot;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class Privmsg : TwitchChatMessage
{
///
/// Contains metadata related to the chat badges in the badges tag.
/// According to Twitch's documentation this should only include info about
/// subscription length, but it also contains prediction info and who knows what else.
///
public IEnumerable BadgeInfo => TryGetTag("badge-info").Split(',');
///
/// Contains the total number of months the user has subscribed, even if they aren't
/// subscribed currently.
///
public int SubscriptionLength
{ get
{
//TODO redo this, functional style clearly didn't work here
if (int.TryParse((BadgeInfo.FirstOrDefault(
b => b.StartsWith("SUBSCRIBER", StringComparison.CurrentCultureIgnoreCase)) ?? "")
.Split("/", 2).ElementAtOrDefault(1) ?? "", out int value))
return value;
return 0;
}
}
// ///
// /// List of chat badges. Most badges have only 1 version, but some badges like
// /// subscriber badges offer different versions of the badge depending on how
// /// long the user has subscribed. To get the badge, use the Get Global Chat
// /// Badges and Get Channel Chat Badges APIs. Match the badge to the set-id field’s
// /// value in the response. Then, match the version to the id field in the list of versions.
// ///
// public List Badges
// { get
// {
// if (!MessageTags.TryGetValue("badges", out string? value))
// return [];
// if (value == null)
// return [];
// List badges = [];
// foreach (var item in value.Split(',', StringSplitOptions.RemoveEmptyEntries))
// {
// var spl = item.Split('/', 2);
// badges.Add(new Badge(spl[0], spl[1]));
// }
// return badges;
// }
// }
///
/// The amount of bits cheered. Equals 0 if message did not contain a cheer.
///
public int Bits
{ get
{
if (!MessageTags.TryGetValue("bits", out string value))
return 0;
if (!int.TryParse(value, out int bits))
return 0;
return bits;
}
}
///
/// The color of the user’s name in the chat room. This is a hexadecimal
/// RGB color code in the form, #. This tag may be empty if it is never set.
///
public Color? Color
{ get
{
//should have format "#RRGGBB"
if (!MessageTags.TryGetValue("color", out string value))
return null;
if (value.Length < 7)
return null;
int r = Convert.ToInt32(value.Substring(1, 2), 16);
int g = Convert.ToInt32(value.Substring(3, 2), 16);
int b = Convert.ToInt32(value.Substring(5, 2), 16);
return new Color(r / 255f, g / 255f, b / 255f, 1);
}
}
///
/// The user’s display name. This tag may be empty if it is never set.
///
public string DisplayName
{ get
{
if (!MessageTags.TryGetValue("display-name", out string value))
return "";
return value ?? "";
}
}
// public IEnumerable Emotes
// { get
// {
// var tag = TryGetTag("emotes");
// foreach (var emote in tag.Split('/', StringSplitOptions.RemoveEmptyEntries))
// {
// var split = emote.Split(':', 2);
// Debug.Assert(split.Length == 2);
// var name = split[0];
// foreach (var indeces in split[1].Split(','))
// {
// var split2 = indeces.Split('-');
// if (!int.TryParse(split2[0], out int start) ||
// !int.TryParse(split2[1], out int end))
// throw new InvalidDataException();
// yield return new Emote(name, start, end - start + 1);
// }
// }
// }
// }
///
/// An ID that uniquely identifies the message.
///
public string Id => TryGetTag("id");
///
/// Whether the user is a moderator in this channel
///
public bool Moderator
{ get
{
if (!MessageTags.TryGetValue("mod", out string value))
return false;
return value == "1";
}
}
///
/// An ID that identifies the chat room (channel).
///
public string RoomId => TryGetTag("room-id");
///
/// Whether the user is subscribed to the channel
///
public bool Subscriber
{ get
{
if (!MessageTags.TryGetValue("subscriber", out string value))
return false;
return value == "1";
}
}
// public DateTime Timestamp
// { get
// {
// var s = TryGetTag("tmi-sent-ts");
// if (!double.TryParse(s, out double result))
// throw new InvalidDataException();
// return DateTime.UnixEpoch.AddSeconds(result / 1000);
// }
// }
///
/// A Boolean value that indicates whether the user has site-wide commercial
/// free mode enabled
///
public bool Turbo
{ get
{
if (!MessageTags.TryGetValue("turbo", out string value))
return false;
return value == "1";
}
}
///
/// The user’s ID
///
public string UserId
{ get
{
if (!MessageTags.TryGetValue("user-id", out string value))
return "";
return value ?? "";
}
}
// ///
// /// The type of the user. Assumes a normal user if this is not provided or is invalid.
// ///
// public UserType UserType
// { get
// {
// if (!MessageTags.TryGetValue("user-type", out string? value))
// return UserType.Normal;
// switch (value)
// {
// case "admin":
// return UserType.Admin;
// case "global_mod":
// return UserType.GlobalMod;
// case "staff":
// return UserType.Staff;
// default:
// return UserType.Normal;
// }
// }
// }
///
/// A Boolean value that determines whether the user that sent the chat is a VIP.
///
public bool Vip => MessageTags.ContainsKey("vip");
///
/// The level of the Hype Chat. Proper values are 1-10, or 0 if not a Hype Chat.
///
public int HypeChatLevel
{ get
{
var value = TryGetTag("pinned-chat-paid-level");
switch (value.ToUpper())
{
case "ONE":
return 1;
case "TWO":
return 2;
case "THREE":
return 3;
case "FOUR":
return 4;
case "FIVE":
return 5;
case "SIX":
return 6;
case "SEVEN":
return 7;
case "EIGHT":
return 8;
case "NINE":
return 9;
case "TEN":
return 10;
default:
return 0;
}
}
}
///
/// The ISO 4217 alphabetic currency code the user has sent the Hype Chat in.
///
public string HypeChatCurrency => TryGetTag("pinned-chat-paid-currency");
public decimal? HypeChatValue
{ get
{
var numeric = TryGetTag("pinned-chat-paid-amount");
var exp = TryGetTag("pinned-chat-paid-exponent");
if (int.TryParse(numeric, out int d_numeric) && int.TryParse(exp, out int d_exp))
return d_numeric / ((decimal)Math.Pow(10, d_exp));
return null;
}
}
public bool FirstMessage => TryGetTag("first-msg") == "1";
public string ChatMessage => Parameters.Last();
public Privmsg(TwitchChatMessage message) : base(message)
{
}
}