From 56f89f50c3ca22c9ed027a57bdf6e0a293e2a46c Mon Sep 17 00:00:00 2001 From: AoshiW <48525283+AoshiW@users.noreply.github.com> Date: Sat, 16 Sep 2023 15:13:05 +0200 Subject: [PATCH] nullable anotation for the `.Models` project except models for `UserNocice` events and `MessageEmote.cs` (#246) --- TwitchLib.Client.Models/Announcement.cs | 12 +++- .../Builders/ChannelStateBuilder.cs | 3 +- .../Builders/ChatMessageBuilder.cs | 5 +- .../Builders/CheerBadgeBuilder.cs | 5 +- .../Builders/CommunitySubscriptionBuilder.cs | 5 +- .../Builders/ConnectionCredentialsBuilder.cs | 5 +- .../Builders/EmoteBuilder.cs | 3 +- .../Builders/ErrorEventBuilder.cs | 10 +-- .../FromIrcMessageBuilderDataObject.cs | 5 +- .../Builders/GiftedSubscriptionBuilder.cs | 5 +- TwitchLib.Client.Models/Builders/IBuilder.cs | 5 +- .../Builders/IFromIrcMessageBuilder.cs | 5 +- .../Builders/IrcMessageBuilder.cs | 3 +- .../Builders/OutboundChatMessageBuilder.cs | 19 ++--- .../Builders/OutgoingMessageBuilder.cs | 62 ---------------- .../Builders/RaidNotificationBuilder.cs | 4 +- .../Builders/ReSubscriberBuilder.cs | 5 +- .../Builders/RitualNewChatterBuilder.cs | 5 +- .../Builders/SentMessageBuilder.cs | 5 +- .../Builders/SubscriberBaseBuilder.cs | 4 +- .../Builders/SubscriberBuilder.cs | 5 +- .../Builders/TwitchLibMessageBuilder.cs | 5 +- .../Builders/UserBanBuilder.cs | 5 +- .../Builders/UserStateBuilder.cs | 4 +- .../Builders/UserTimeoutBuilder.cs | 5 +- .../Builders/WhisperMessageBuilder.cs | 5 +- TwitchLib.Client.Models/ChannelState.cs | 14 +++- TwitchLib.Client.Models/ChatMessage.cs | 42 ++++++----- TwitchLib.Client.Models/CommandInfo.cs | 16 ++++- TwitchLib.Client.Models/Common/Helpers.cs | 70 ------------------- .../CommunitySubscription.cs | 12 +++- .../ConnectionCredentials.cs | 8 ++- .../ContinuedGiftedSubscription.cs | 12 +++- TwitchLib.Client.Models/EmoteSet.cs | 9 +-- TwitchLib.Client.Models/ErrorEvent.cs | 10 ++- .../Extractors/EmoteExtractor.cs | 4 +- TwitchLib.Client.Models/GiftedSubscription.cs | 12 +++- TwitchLib.Client.Models/HypeChat.cs | 10 +-- .../Internal/IrcMessage.cs | 14 ++-- TwitchLib.Client.Models/Internal/MsgIds.cs | 4 +- TwitchLib.Client.Models/JoinedChannel.cs | 6 +- TwitchLib.Client.Models/MessageEmote.cs | 2 +- .../OutboundChatMessage.cs | 27 +++---- TwitchLib.Client.Models/OutgoingMessage.cs | 28 -------- TwitchLib.Client.Models/RaidNotification.cs | 12 +++- TwitchLib.Client.Models/RitualNewChatter.cs | 12 +++- TwitchLib.Client.Models/SendOptions.cs | 1 + TwitchLib.Client.Models/SentMessage.cs | 10 ++- TwitchLib.Client.Models/SubscriberBase.cs | 9 +++ .../TwitchLib.Client.Models.csproj | 1 + TwitchLib.Client.Models/TwitchLibMessage.cs | 21 +++--- TwitchLib.Client.Models/UserBan.cs | 14 ++-- TwitchLib.Client.Models/UserState.cs | 30 +++++--- TwitchLib.Client.Models/UserTimeout.cs | 30 +++++--- TwitchLib.Client.Models/WhisperMessage.cs | 10 ++- .../ThrottlingServiceTests.cs | 2 +- TwitchLib.Client/TwitchClient.cs | 9 +-- 57 files changed, 353 insertions(+), 312 deletions(-) delete mode 100644 TwitchLib.Client.Models/Builders/OutgoingMessageBuilder.cs delete mode 100644 TwitchLib.Client.Models/Common/Helpers.cs delete mode 100644 TwitchLib.Client.Models/OutgoingMessage.cs diff --git a/TwitchLib.Client.Models/Announcement.cs b/TwitchLib.Client.Models/Announcement.cs index 4bc2b922..e339d416 100644 --- a/TwitchLib.Client.Models/Announcement.cs +++ b/TwitchLib.Client.Models/Announcement.cs @@ -1,4 +1,6 @@ -using TwitchLib.Client.Enums; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using TwitchLib.Client.Enums; using TwitchLib.Client.Models.Interfaces; using TwitchLib.Client.Models.Internal; @@ -73,6 +75,11 @@ public class Announcement : IHexColorProperty /// Property representing the message of the announcement. public string Message { get; } + /// + /// Contains undocumented tags. + /// + public Dictionary? UndocumentedTags { get; } + /// SAMPLE: @badge-info=;badges=broadcaster/1,ambassador/1;color=#033700;display-name=BarryCarlyon;emotes=;flags=;id=55d90904-e515-47d0-ac1d-879f7f1d7b01;login=barrycarlyon;mod=0;msg-id=announcement;msg-param-color=PRIMARY;room-id=15185913;subscriber=0;system-msg=;tmi-sent-ts=1648758023469;user-id=15185913;user-type= :tmi.twitch.tv USERNOTICE #barrycarlyon :test announcment main /// Announcement object constructor. /// The IRC message from Twitch to be processed. @@ -152,6 +159,9 @@ public Announcement(IrcMessage ircMessage) case Tags.UserType: UserType = TagHelper.ToUserType(tag.Value); break; + default: + (UndocumentedTags = new()).Add(tag.Key, tag.Value); + break; } } } diff --git a/TwitchLib.Client.Models/Builders/ChannelStateBuilder.cs b/TwitchLib.Client.Models/Builders/ChannelStateBuilder.cs index bd9bb1ce..e32999d9 100644 --- a/TwitchLib.Client.Models/Builders/ChannelStateBuilder.cs +++ b/TwitchLib.Client.Models/Builders/ChannelStateBuilder.cs @@ -1,4 +1,5 @@ -using System; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member namespace TwitchLib.Client.Models.Builders { diff --git a/TwitchLib.Client.Models/Builders/ChatMessageBuilder.cs b/TwitchLib.Client.Models/Builders/ChatMessageBuilder.cs index b816d714..bbafbae0 100644 --- a/TwitchLib.Client.Models/Builders/ChatMessageBuilder.cs +++ b/TwitchLib.Client.Models/Builders/ChatMessageBuilder.cs @@ -1,4 +1,7 @@ -using TwitchLib.Client.Enums; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using TwitchLib.Client.Enums; namespace TwitchLib.Client.Models.Builders { diff --git a/TwitchLib.Client.Models/Builders/CheerBadgeBuilder.cs b/TwitchLib.Client.Models/Builders/CheerBadgeBuilder.cs index c7b092c8..8e163ad7 100644 --- a/TwitchLib.Client.Models/Builders/CheerBadgeBuilder.cs +++ b/TwitchLib.Client.Models/Builders/CheerBadgeBuilder.cs @@ -1,4 +1,7 @@ -namespace TwitchLib.Client.Models.Builders +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +namespace TwitchLib.Client.Models.Builders { public sealed class CheerBadgeBuilder : IBuilder { diff --git a/TwitchLib.Client.Models/Builders/CommunitySubscriptionBuilder.cs b/TwitchLib.Client.Models/Builders/CommunitySubscriptionBuilder.cs index dff4fbaf..7aff91a5 100644 --- a/TwitchLib.Client.Models/Builders/CommunitySubscriptionBuilder.cs +++ b/TwitchLib.Client.Models/Builders/CommunitySubscriptionBuilder.cs @@ -1,4 +1,7 @@ -namespace TwitchLib.Client.Models.Builders +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +namespace TwitchLib.Client.Models.Builders { public sealed class CommunitySubscriptionBuilder : IFromIrcMessageBuilder { diff --git a/TwitchLib.Client.Models/Builders/ConnectionCredentialsBuilder.cs b/TwitchLib.Client.Models/Builders/ConnectionCredentialsBuilder.cs index fe7de7f2..e63a005c 100644 --- a/TwitchLib.Client.Models/Builders/ConnectionCredentialsBuilder.cs +++ b/TwitchLib.Client.Models/Builders/ConnectionCredentialsBuilder.cs @@ -1,4 +1,7 @@ -namespace TwitchLib.Client.Models.Builders +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +namespace TwitchLib.Client.Models.Builders { public sealed class ConnectionCredentialsBuilder : IBuilder { diff --git a/TwitchLib.Client.Models/Builders/EmoteBuilder.cs b/TwitchLib.Client.Models/Builders/EmoteBuilder.cs index 1830953f..7477124f 100644 --- a/TwitchLib.Client.Models/Builders/EmoteBuilder.cs +++ b/TwitchLib.Client.Models/Builders/EmoteBuilder.cs @@ -1,4 +1,5 @@ -using static TwitchLib.Client.Models.EmoteSet; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member namespace TwitchLib.Client.Models.Builders { diff --git a/TwitchLib.Client.Models/Builders/ErrorEventBuilder.cs b/TwitchLib.Client.Models/Builders/ErrorEventBuilder.cs index 0749d614..e7c41063 100644 --- a/TwitchLib.Client.Models/Builders/ErrorEventBuilder.cs +++ b/TwitchLib.Client.Models/Builders/ErrorEventBuilder.cs @@ -1,4 +1,7 @@ -namespace TwitchLib.Client.Models.Builders +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +namespace TwitchLib.Client.Models.Builders { public sealed class ErrorEventBuilder : IBuilder { @@ -21,10 +24,7 @@ public static ErrorEventBuilder Create() public ErrorEvent Build() { - return new ErrorEvent - { - Message = _message - }; + return new ErrorEvent(_message); } } } diff --git a/TwitchLib.Client.Models/Builders/FromIrcMessageBuilderDataObject.cs b/TwitchLib.Client.Models/Builders/FromIrcMessageBuilderDataObject.cs index bfd279f0..8e46e7ec 100644 --- a/TwitchLib.Client.Models/Builders/FromIrcMessageBuilderDataObject.cs +++ b/TwitchLib.Client.Models/Builders/FromIrcMessageBuilderDataObject.cs @@ -1,4 +1,7 @@ -using TwitchLib.Client.Models.Internal; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using TwitchLib.Client.Models.Internal; namespace TwitchLib.Client.Models.Builders { diff --git a/TwitchLib.Client.Models/Builders/GiftedSubscriptionBuilder.cs b/TwitchLib.Client.Models/Builders/GiftedSubscriptionBuilder.cs index 73765809..14f4a53a 100644 --- a/TwitchLib.Client.Models/Builders/GiftedSubscriptionBuilder.cs +++ b/TwitchLib.Client.Models/Builders/GiftedSubscriptionBuilder.cs @@ -1,4 +1,7 @@ -using TwitchLib.Client.Enums; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using TwitchLib.Client.Enums; namespace TwitchLib.Client.Models.Builders { diff --git a/TwitchLib.Client.Models/Builders/IBuilder.cs b/TwitchLib.Client.Models/Builders/IBuilder.cs index a607fbe3..47adec09 100644 --- a/TwitchLib.Client.Models/Builders/IBuilder.cs +++ b/TwitchLib.Client.Models/Builders/IBuilder.cs @@ -1,4 +1,7 @@ -namespace TwitchLib.Client.Models.Builders +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +namespace TwitchLib.Client.Models.Builders { public interface IBuilder { diff --git a/TwitchLib.Client.Models/Builders/IFromIrcMessageBuilder.cs b/TwitchLib.Client.Models/Builders/IFromIrcMessageBuilder.cs index 8269981b..ddbe7b71 100644 --- a/TwitchLib.Client.Models/Builders/IFromIrcMessageBuilder.cs +++ b/TwitchLib.Client.Models/Builders/IFromIrcMessageBuilder.cs @@ -1,4 +1,7 @@ -namespace TwitchLib.Client.Models.Builders +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +namespace TwitchLib.Client.Models.Builders { public interface IFromIrcMessageBuilder { diff --git a/TwitchLib.Client.Models/Builders/IrcMessageBuilder.cs b/TwitchLib.Client.Models/Builders/IrcMessageBuilder.cs index 33a76d56..1fd67f61 100644 --- a/TwitchLib.Client.Models/Builders/IrcMessageBuilder.cs +++ b/TwitchLib.Client.Models/Builders/IrcMessageBuilder.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using TwitchLib.Client.Enums.Internal; using TwitchLib.Client.Models.Internal; diff --git a/TwitchLib.Client.Models/Builders/OutboundChatMessageBuilder.cs b/TwitchLib.Client.Models/Builders/OutboundChatMessageBuilder.cs index 89f7584b..1f41c8a0 100644 --- a/TwitchLib.Client.Models/Builders/OutboundChatMessageBuilder.cs +++ b/TwitchLib.Client.Models/Builders/OutboundChatMessageBuilder.cs @@ -1,10 +1,12 @@ -namespace TwitchLib.Client.Models.Builders +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +namespace TwitchLib.Client.Models.Builders { public sealed class OutboundChatMessageBuilder : IBuilder { private string _channel; private string _message; - private string _userName; private OutboundChatMessageBuilder() { @@ -27,20 +29,9 @@ public OutboundChatMessageBuilder WithMessage(string message) return this; } - public OutboundChatMessageBuilder WithUsername(string userName) - { - _userName = userName; - return this; - } - public OutboundChatMessage Build() { - return new OutboundChatMessage - { - Channel = _channel, - Message = _message, - Username = _userName, - }; + return new OutboundChatMessage(_channel, _message); } } } \ No newline at end of file diff --git a/TwitchLib.Client.Models/Builders/OutgoingMessageBuilder.cs b/TwitchLib.Client.Models/Builders/OutgoingMessageBuilder.cs deleted file mode 100644 index 7e49b549..00000000 --- a/TwitchLib.Client.Models/Builders/OutgoingMessageBuilder.cs +++ /dev/null @@ -1,62 +0,0 @@ -namespace TwitchLib.Client.Models.Builders -{ - public sealed class OutgoingMessageBuilder : IBuilder - { - private string _channel; - private string _message; - private int _nonce; - private string _sender; - private MessageState _messageState; - - private OutgoingMessageBuilder() - { - } - - public static OutgoingMessageBuilder Create() - { - return new OutgoingMessageBuilder(); - } - - public OutgoingMessageBuilder WithChannel(string channel) - { - _channel = channel; - return this; - } - - public OutgoingMessageBuilder WithMessage(string message) - { - _message = message; - return this; - } - - public OutgoingMessageBuilder WithNonce(int nonce) - { - _nonce = nonce; - return this; - } - - public OutgoingMessageBuilder WithSender(string sender) - { - _sender = sender; - return this; - } - - public OutgoingMessageBuilder WithMessageState(MessageState messageState) - { - _messageState = messageState; - return this; - } - - public OutgoingMessage Build() - { - return new OutgoingMessage - { - Channel = _channel, - Message = _message, - Nonce = _nonce, - Sender = _sender, - State = _messageState - }; - } - } -} \ No newline at end of file diff --git a/TwitchLib.Client.Models/Builders/RaidNotificationBuilder.cs b/TwitchLib.Client.Models/Builders/RaidNotificationBuilder.cs index d2e10d66..cc8688cf 100644 --- a/TwitchLib.Client.Models/Builders/RaidNotificationBuilder.cs +++ b/TwitchLib.Client.Models/Builders/RaidNotificationBuilder.cs @@ -1,4 +1,6 @@ -using System.Drawing; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + using TwitchLib.Client.Enums; namespace TwitchLib.Client.Models.Builders diff --git a/TwitchLib.Client.Models/Builders/ReSubscriberBuilder.cs b/TwitchLib.Client.Models/Builders/ReSubscriberBuilder.cs index 5e18430d..1c864c49 100644 --- a/TwitchLib.Client.Models/Builders/ReSubscriberBuilder.cs +++ b/TwitchLib.Client.Models/Builders/ReSubscriberBuilder.cs @@ -1,4 +1,7 @@ -namespace TwitchLib.Client.Models.Builders +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +namespace TwitchLib.Client.Models.Builders { public sealed class ReSubscriberBuilder : SubscriberBaseBuilder, IBuilder, IFromIrcMessageBuilder { diff --git a/TwitchLib.Client.Models/Builders/RitualNewChatterBuilder.cs b/TwitchLib.Client.Models/Builders/RitualNewChatterBuilder.cs index af84a44b..fc65d9b3 100644 --- a/TwitchLib.Client.Models/Builders/RitualNewChatterBuilder.cs +++ b/TwitchLib.Client.Models/Builders/RitualNewChatterBuilder.cs @@ -1,4 +1,7 @@ -namespace TwitchLib.Client.Models.Builders +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +namespace TwitchLib.Client.Models.Builders { public sealed class RitualNewChatterBuilder : IFromIrcMessageBuilder { diff --git a/TwitchLib.Client.Models/Builders/SentMessageBuilder.cs b/TwitchLib.Client.Models/Builders/SentMessageBuilder.cs index 534ad578..83dc2ce6 100644 --- a/TwitchLib.Client.Models/Builders/SentMessageBuilder.cs +++ b/TwitchLib.Client.Models/Builders/SentMessageBuilder.cs @@ -1,4 +1,7 @@ -using TwitchLib.Client.Enums; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using TwitchLib.Client.Enums; namespace TwitchLib.Client.Models.Builders { diff --git a/TwitchLib.Client.Models/Builders/SubscriberBaseBuilder.cs b/TwitchLib.Client.Models/Builders/SubscriberBaseBuilder.cs index a7b262b8..bca3443d 100644 --- a/TwitchLib.Client.Models/Builders/SubscriberBaseBuilder.cs +++ b/TwitchLib.Client.Models/Builders/SubscriberBaseBuilder.cs @@ -1,4 +1,6 @@ -using System.Drawing; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + using TwitchLib.Client.Enums; namespace TwitchLib.Client.Models.Builders diff --git a/TwitchLib.Client.Models/Builders/SubscriberBuilder.cs b/TwitchLib.Client.Models/Builders/SubscriberBuilder.cs index d17c4652..3b23eebc 100644 --- a/TwitchLib.Client.Models/Builders/SubscriberBuilder.cs +++ b/TwitchLib.Client.Models/Builders/SubscriberBuilder.cs @@ -1,4 +1,7 @@ -namespace TwitchLib.Client.Models.Builders +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +namespace TwitchLib.Client.Models.Builders { public sealed class SubscriberBuilder : SubscriberBaseBuilder, IBuilder, IFromIrcMessageBuilder { diff --git a/TwitchLib.Client.Models/Builders/TwitchLibMessageBuilder.cs b/TwitchLib.Client.Models/Builders/TwitchLibMessageBuilder.cs index 7d129533..0556c38c 100644 --- a/TwitchLib.Client.Models/Builders/TwitchLibMessageBuilder.cs +++ b/TwitchLib.Client.Models/Builders/TwitchLibMessageBuilder.cs @@ -1,4 +1,7 @@ -using TwitchLib.Client.Enums; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +using TwitchLib.Client.Enums; namespace TwitchLib.Client.Models.Builders { diff --git a/TwitchLib.Client.Models/Builders/UserBanBuilder.cs b/TwitchLib.Client.Models/Builders/UserBanBuilder.cs index 735d06e3..b0a0031a 100644 --- a/TwitchLib.Client.Models/Builders/UserBanBuilder.cs +++ b/TwitchLib.Client.Models/Builders/UserBanBuilder.cs @@ -1,4 +1,7 @@ -namespace TwitchLib.Client.Models.Builders +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +namespace TwitchLib.Client.Models.Builders { public sealed class UserBanBuilder : IBuilder, IFromIrcMessageBuilder { diff --git a/TwitchLib.Client.Models/Builders/UserStateBuilder.cs b/TwitchLib.Client.Models/Builders/UserStateBuilder.cs index bfe0eb12..a14fef08 100644 --- a/TwitchLib.Client.Models/Builders/UserStateBuilder.cs +++ b/TwitchLib.Client.Models/Builders/UserStateBuilder.cs @@ -1,4 +1,6 @@ -using System.Drawing; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + using TwitchLib.Client.Enums; namespace TwitchLib.Client.Models.Builders diff --git a/TwitchLib.Client.Models/Builders/UserTimeoutBuilder.cs b/TwitchLib.Client.Models/Builders/UserTimeoutBuilder.cs index 3f4ac526..ddebfd92 100644 --- a/TwitchLib.Client.Models/Builders/UserTimeoutBuilder.cs +++ b/TwitchLib.Client.Models/Builders/UserTimeoutBuilder.cs @@ -1,4 +1,7 @@ -namespace TwitchLib.Client.Models.Builders +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +namespace TwitchLib.Client.Models.Builders { public sealed class UserTimeoutBuilder : IBuilder, IFromIrcMessageBuilder { diff --git a/TwitchLib.Client.Models/Builders/WhisperMessageBuilder.cs b/TwitchLib.Client.Models/Builders/WhisperMessageBuilder.cs index 8d991b4a..da36860a 100644 --- a/TwitchLib.Client.Models/Builders/WhisperMessageBuilder.cs +++ b/TwitchLib.Client.Models/Builders/WhisperMessageBuilder.cs @@ -1,4 +1,7 @@ -namespace TwitchLib.Client.Models.Builders +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +namespace TwitchLib.Client.Models.Builders { public sealed class WhisperMessageBuilder : IBuilder, IFromIrcMessageBuilder { diff --git a/TwitchLib.Client.Models/ChannelState.cs b/TwitchLib.Client.Models/ChannelState.cs index 6f0b39b5..1135b765 100644 --- a/TwitchLib.Client.Models/ChannelState.cs +++ b/TwitchLib.Client.Models/ChannelState.cs @@ -6,7 +6,7 @@ namespace TwitchLib.Client.Models public class ChannelState { /// Property representing the current broadcaster language. - public string BroadcasterLanguage { get; } + public string BroadcasterLanguage { get; } = default!; /// Property representing the current channel. public string Channel { get; } @@ -27,7 +27,7 @@ public class ChannelState public bool? Rituals { get; } /// Twitch assigned room id - public string RoomId { get; } + public string RoomId { get; } = default!; /// Property representing whether Slow mode is being applied to chat or not. WILL BE NULL IF VALUE NOT PRESENT. public int? SlowMode { get; } @@ -35,6 +35,11 @@ public class ChannelState /// Property representing whether Sub Mode is being applied to chat or not. WILL BE NULL IF VALUE NOT PRESENT. public bool? SubOnly { get; } + /// + /// Contains undocumented tags. + /// + public Dictionary? UndocumentedTags { get; } + /// ChannelState object constructor. public ChannelState(IrcMessage ircMessage) { @@ -76,13 +81,16 @@ public ChannelState(IrcMessage ircMessage) Mercury = TagHelper.ToBool(tagValue); break; default: - Console.WriteLine("[TwitchLib][ChannelState] Unaccounted for: " + tag); + (UndocumentedTags = new()).Add(tag.Key, tag.Value); break; } } Channel = ircMessage.Channel; } + /// + /// Initializes a new instance of the class. + /// public ChannelState( bool r9k, bool rituals, diff --git a/TwitchLib.Client.Models/ChatMessage.cs b/TwitchLib.Client.Models/ChatMessage.cs index e7f8079d..3463014a 100644 --- a/TwitchLib.Client.Models/ChatMessage.cs +++ b/TwitchLib.Client.Models/ChatMessage.cs @@ -1,4 +1,5 @@ using TwitchLib.Client.Enums; +using TwitchLib.Client.Models.Extensions; using TwitchLib.Client.Models.Internal; namespace TwitchLib.Client.Models @@ -6,10 +7,10 @@ namespace TwitchLib.Client.Models /// Class represents ChatMessage in a Twitch channel. public class ChatMessage : TwitchLibMessage { - protected readonly MessageEmoteCollection _emoteCollection; + protected readonly MessageEmoteCollection? _emoteCollection; /// Information associated with badges. Not all badges will be in this list. Use carefully. - public List> BadgeInfo { get; } + public List> BadgeInfo { get; } = default!; /// If viewer sent bits in their message, total amount will be here. public int Bits { get; } @@ -21,16 +22,16 @@ public class ChatMessage : TwitchLibMessage public string Channel { get; } /// If a cheer badge exists, this property represents the raw value and color (more later). Can be null. - public CheerBadge CheerBadge { get; } + public CheerBadge? CheerBadge { get; } /// If a custom reward is present with the message, the ID will be set (null by default) - public string CustomRewardId { get; } + public string? CustomRewardId { get; } /// Text after emotes have been handled (if desired). Will be null if replaceEmotes is false. - public string EmoteReplacedMessage { get; } + public string? EmoteReplacedMessage { get; } /// Unique message identifier assigned by Twitch - public string Id { get; } + public string Id { get; } = default!; /// Chat message from broadcaster identifier flag public bool IsBroadcaster { get; } @@ -69,7 +70,7 @@ public class ChatMessage : TwitchLibMessage public Noisy Noisy { get; } /// Unique identifier of chat room. - public string RoomId { get; } + public string RoomId { get; } = default!; /// Number of months a person has been subbed. public int SubscribedMonthCount { get; } @@ -78,10 +79,10 @@ public class ChatMessage : TwitchLibMessage public DateTimeOffset TmiSent { get; } /// Chat reply information. Will be null if it is not a reply. - public ChatReply ChatReply { get; } + public ChatReply? ChatReply { get; } /// Hype Chat information. - public HypeChat HypeChat { get; } + public HypeChat? HypeChat { get; } //Example IRC message: @badges=moderator/1,warcraft/alliance;color=;display-name=Swiftyspiffyv4;emotes=;mod=1;room-id=40876073;subscriber=0;turbo=0;user-id=103325214;user-type=mod :swiftyspiffyv4!swiftyspiffyv4@swiftyspiffyv4.tmi.twitch.tv PRIVMSG #swiftyspiffy :asd /// Constructor for ChatMessage object. @@ -94,7 +95,7 @@ public class ChatMessage : TwitchLibMessage public ChatMessage( string botUsername, IrcMessage ircMessage, - MessageEmoteCollection emoteCollection = null, + MessageEmoteCollection? emoteCollection = null, bool replaceEmotes = false, string prefix = "", string suffix = "") @@ -268,14 +269,16 @@ public ChatMessage( case Tags.UserType: UserType = TagHelper.ToUserType(tagValue); break; + default: + (UndocumentedTags = new()).Add(tag.Key, tag.Value); + break; } } //Parse the emoteSet - if (_emoteCollection != null && Message != null && EmoteSet?.Emotes.Count > 0) + if (_emoteCollection != null && EmoteSet?.Emotes.Count > 0) { - var uniqueEmotes = EmoteSet.RawEmoteSetString.Split('/'); - foreach (var emote in uniqueEmotes) + foreach (var emote in new SpanSliceEnumerator(EmoteSet.RawEmoteSetString!, '/')) { var firstColon = emote.IndexOf(':'); var firstComma = emote.IndexOf(','); @@ -284,11 +287,11 @@ public ChatMessage( if (firstColon > 0 && firstDash > firstColon && firstComma > firstDash) { #if NETSTANDARD2_0 - var lowStr = emote.Substring(firstColon + 1, firstDash - firstColon - 1); - var highStr = emote.Substring(firstDash + 1, firstComma - firstDash - 1); + var lowStr = emote.Slice(firstColon + 1, firstDash - firstColon - 1).ToString(); + var highStr = emote.Slice(firstDash + 1, firstComma - firstDash - 1).ToString(); #else - var lowStr = emote.AsSpan(firstColon + 1, firstDash - firstColon - 1); - var highStr = emote.AsSpan(firstDash + 1, firstComma - firstDash - 1); + var lowStr = emote.Slice(firstColon + 1, firstDash - firstColon - 1); + var highStr = emote.Slice(firstDash + 1, firstComma - firstDash - 1); #endif if (int.TryParse(lowStr, out var low) && int.TryParse(highStr, out var high)) @@ -296,7 +299,7 @@ public ChatMessage( if (low >= 0 && low < high && high < Message.Length) { //Valid emote, let's parse - var id = emote.Substring(0, firstColon); + var id = emote.Slice(0, firstColon).ToString(); //Pull the emote text from the message var text = Message.Substring(low, high - low + 1); _emoteCollection.Add(new MessageEmote(id, text)); @@ -332,6 +335,9 @@ public ChatMessage( } } + /// + /// Initializes a new instance of the class. + /// public ChatMessage( string botUsername, string userId, diff --git a/TwitchLib.Client.Models/CommandInfo.cs b/TwitchLib.Client.Models/CommandInfo.cs index 3fbb4e42..d3f55a58 100644 --- a/TwitchLib.Client.Models/CommandInfo.cs +++ b/TwitchLib.Client.Models/CommandInfo.cs @@ -1,4 +1,6 @@ -namespace TwitchLib.Client.Models; +using System.Diagnostics.CodeAnalysis; + +namespace TwitchLib.Client.Models; /// Object representing a command received via Twitch chat. public class CommandInfo @@ -32,9 +34,19 @@ public CommandInfo(char identifier, string name, string argumentsAsString, List< ArgumentsAsList = argumentsAsList; } + /// + /// Tries to parse a span of characters into a value. + /// + /// The span of characters to parse. + /// When this method returns, contains the result of successfully parsing s, or an undefined value on failure. + /// true if s was successfully parsed; otherwise, false. +#if NETSTANDARD2_0 public static bool TryParse(ReadOnlySpan s, out CommandInfo result) +#else + public static bool TryParse(ReadOnlySpan s, [MaybeNullWhen(false)] out CommandInfo result) +#endif { - result = default; + result = default!; s = s.Trim(); if (s.IsEmpty) return false; diff --git a/TwitchLib.Client.Models/Common/Helpers.cs b/TwitchLib.Client.Models/Common/Helpers.cs deleted file mode 100644 index adc622c2..00000000 --- a/TwitchLib.Client.Models/Common/Helpers.cs +++ /dev/null @@ -1,70 +0,0 @@ -namespace TwitchLib.Client.Models.Common -{ - /// Static class of helper functions used around the project. - public static class Helpers - { - /// - /// Parses out strings that have quotes, ideal for commands that use quotes for parameters - /// - /// Input string to attempt to parse. - /// List of contents of quotes from the input string - public static List ParseQuotesAndNonQuotes(string message) - { - var args = new List(); - - // Return if empty string - if (message == "") - return args; - - var previousQuoted = message[0] != '"'; - // Parse quoted text as a single argument - foreach (var arg in message.Split('"')) - { - if (string.IsNullOrEmpty(arg)) - continue; - - // This arg is a quoted arg, add it right away - if (!previousQuoted) - { - args.Add(arg); - previousQuoted = true; - continue; - } - - if (!arg.Contains(" ")) - continue; - - // This arg is non-quoted, iterate through each split and add it if it's not empty/whitespace - foreach (var dynArg in arg.Split(' ')) - { - if (string.IsNullOrWhiteSpace(dynArg)) - continue; - - args.Add(dynArg); - previousQuoted = false; - } - } - return args; - } - - //not used anywhere - public static string ParseToken(string token, string message) - { - var tokenValue = string.Empty; - - for (var i = message.IndexOf(token, StringComparison.InvariantCultureIgnoreCase); - i > -1; - i = message.IndexOf(token, i + token.Length, StringComparison.InvariantCultureIgnoreCase)) - { - tokenValue = new string(message - .Substring(i) - .TakeWhile(x => x != ';' && x != ' ') - .ToArray()) - .Split('=') - .LastOrDefault(); - } - - return tokenValue; - } - } -} \ No newline at end of file diff --git a/TwitchLib.Client.Models/CommunitySubscription.cs b/TwitchLib.Client.Models/CommunitySubscription.cs index 61b7651c..cfb86f52 100644 --- a/TwitchLib.Client.Models/CommunitySubscription.cs +++ b/TwitchLib.Client.Models/CommunitySubscription.cs @@ -1,4 +1,6 @@ -using TwitchLib.Client.Enums; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using TwitchLib.Client.Enums; using TwitchLib.Client.Models.Interfaces; using TwitchLib.Client.Models.Internal; @@ -33,6 +35,11 @@ public class CommunitySubscription : IHexColorProperty public UserType UserType; public string MsgParamMultiMonthGiftDuration; + /// + /// Contains undocumented tags. + /// + public Dictionary? UndocumentedTags { get; } + public CommunitySubscription(IrcMessage ircMessage) { foreach (var tag in ircMessage.Tags) @@ -105,6 +112,9 @@ public CommunitySubscription(IrcMessage ircMessage) case Tags.MsgParamMultiMonthGiftDuration: MsgParamMultiMonthGiftDuration = tagValue; break; + default: + (UndocumentedTags = new()).Add(tag.Key, tag.Value); + break; } } } diff --git a/TwitchLib.Client.Models/ConnectionCredentials.cs b/TwitchLib.Client.Models/ConnectionCredentials.cs index ea988456..90564003 100644 --- a/TwitchLib.Client.Models/ConnectionCredentials.cs +++ b/TwitchLib.Client.Models/ConnectionCredentials.cs @@ -26,7 +26,7 @@ public ConnectionCredentials( string twitchUsername, string twitchOAuth, bool disableUsernameCheck = false, - Capabilities capabilities = null) + Capabilities? capabilities = null) { if (!disableUsernameCheck && !GetUsernameCheckRegex().Match(twitchUsername).Success) throw new Exception($"Twitch username does not appear to be valid. {twitchUsername}"); @@ -40,8 +40,7 @@ public ConnectionCredentials( TwitchOAuth = $"oauth:{twitchOAuth.Replace("oauth", "")}"; } - capabilities ??= new Capabilities(); - Capabilities = capabilities; + Capabilities = capabilities ?? new Capabilities(); } } @@ -57,6 +56,9 @@ public class Capabilities /// Enables several Twitch-specific commands. public bool Commands { get; } + /// + /// Initializes a new instance of the class. + /// public Capabilities(bool membership = true, bool tags = true, bool commands = true) { Membership = membership; diff --git a/TwitchLib.Client.Models/ContinuedGiftedSubscription.cs b/TwitchLib.Client.Models/ContinuedGiftedSubscription.cs index cd3204d8..c402684a 100644 --- a/TwitchLib.Client.Models/ContinuedGiftedSubscription.cs +++ b/TwitchLib.Client.Models/ContinuedGiftedSubscription.cs @@ -1,4 +1,6 @@ -using TwitchLib.Client.Enums; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using TwitchLib.Client.Enums; using TwitchLib.Client.Models.Interfaces; using TwitchLib.Client.Models.Internal; @@ -46,6 +48,11 @@ public class ContinuedGiftedSubscription : IHexColorProperty public UserType UserType { get; } + /// + /// Contains undocumented tags. + /// + public Dictionary? UndocumentedTags { get; } + public ContinuedGiftedSubscription(IrcMessage ircMessage) { foreach (var tag in ircMessage.Tags) @@ -107,6 +114,9 @@ public ContinuedGiftedSubscription(IrcMessage ircMessage) case Tags.UserType: UserType = TagHelper.ToUserType(tag.Value); break; + default: + (UndocumentedTags = new()).Add(tag.Key, tag.Value); + break; } } } diff --git a/TwitchLib.Client.Models/EmoteSet.cs b/TwitchLib.Client.Models/EmoteSet.cs index d8dbdb39..35d64d6d 100644 --- a/TwitchLib.Client.Models/EmoteSet.cs +++ b/TwitchLib.Client.Models/EmoteSet.cs @@ -1,7 +1,4 @@ -using System.Collections.Generic; -using System.Linq; - -using TwitchLib.Client.Models.Extractors; +using TwitchLib.Client.Models.Extractors; // TODO: Builder is missing namespace TwitchLib.Client.Models @@ -13,12 +10,12 @@ public class EmoteSet public List Emotes { get; } /// The raw emote set string obtained from Twitch, for legacy purposes. - public string RawEmoteSetString { get; } + public string? RawEmoteSetString { get; } /// Constructor for ChatEmoteSet object. /// /// - public EmoteSet(string rawEmoteSetString, string message) + public EmoteSet(string? rawEmoteSetString, string message) { // this should be removed and used outside of object RawEmoteSetString = rawEmoteSetString; diff --git a/TwitchLib.Client.Models/ErrorEvent.cs b/TwitchLib.Client.Models/ErrorEvent.cs index 085614f7..e1bcf34c 100644 --- a/TwitchLib.Client.Models/ErrorEvent.cs +++ b/TwitchLib.Client.Models/ErrorEvent.cs @@ -4,6 +4,14 @@ public class ErrorEvent { /// Message pertaining to the error. - public string Message { get; set; } + public string Message { get; } + + /// + /// Initializes a new instance of the class. + /// + public ErrorEvent(string message) + { + Message = message; + } } } diff --git a/TwitchLib.Client.Models/Extractors/EmoteExtractor.cs b/TwitchLib.Client.Models/Extractors/EmoteExtractor.cs index 507c6f78..86d60610 100644 --- a/TwitchLib.Client.Models/Extractors/EmoteExtractor.cs +++ b/TwitchLib.Client.Models/Extractors/EmoteExtractor.cs @@ -4,14 +4,16 @@ namespace TwitchLib.Client.Models.Extractors { public static class EmoteExtractor { - public static List Extract(string rawEmoteSetString, string message) + public static List Extract(string? rawEmoteSetString, string message) { var emotes = new List(); if (string.IsNullOrEmpty(rawEmoteSetString) || string.IsNullOrEmpty(message)) return emotes; // 25:5-9,28-32/28087:15-21 => 25:5-9,28-32 28087:15-21 +#pragma warning disable CS8604 // Possible null reference argument. false positiv in NS 2.0 foreach (var emoteData in new SpanSliceEnumerator(rawEmoteSetString, '/')) +#pragma warning restore CS8604 // Possible null reference argument. { var index = emoteData.IndexOf(':'); var emoteId = emoteData.Slice(0, index).ToString(); diff --git a/TwitchLib.Client.Models/GiftedSubscription.cs b/TwitchLib.Client.Models/GiftedSubscription.cs index a3ae016c..7175376e 100644 --- a/TwitchLib.Client.Models/GiftedSubscription.cs +++ b/TwitchLib.Client.Models/GiftedSubscription.cs @@ -1,4 +1,6 @@ -using TwitchLib.Client.Enums; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using TwitchLib.Client.Enums; using TwitchLib.Client.Models.Interfaces; using TwitchLib.Client.Models.Internal; @@ -59,6 +61,11 @@ public class GiftedSubscription : IHexColorProperty public string MsgParamMultiMonthGiftDuration { get; } + /// + /// Contains undocumented tags. + /// + public Dictionary? UndocumentedTags { get; } + public GiftedSubscription(IrcMessage ircMessage) { foreach (var tag in ircMessage.Tags) @@ -140,6 +147,9 @@ public GiftedSubscription(IrcMessage ircMessage) case Tags.MsgParamMultiMonthGiftDuration: MsgParamMultiMonthGiftDuration = tagValue; break; + default: + (UndocumentedTags = new()).Add(tag.Key, tag.Value); + break; } } } diff --git a/TwitchLib.Client.Models/HypeChat.cs b/TwitchLib.Client.Models/HypeChat.cs index 14a2d3d3..5fede783 100644 --- a/TwitchLib.Client.Models/HypeChat.cs +++ b/TwitchLib.Client.Models/HypeChat.cs @@ -5,7 +5,7 @@ public class HypeChat /// /// The value of the Hype Chat sent by the user. /// - public int Amount { get; set; } + public int Amount { get; internal set; } public double CalculatedAmount => Exponent == 0 ? Amount @@ -14,17 +14,17 @@ public class HypeChat /// /// The ISO 4217 alphabetic currency code the user has sent the Hype Chat in. /// - public string Currency { get; set; } + public string Currency { get; internal set; } = default!; /// /// Indicates how many decimal points this currency represents partial amounts in. Decimal points start from the right side of the value defined in pinned-chat-paid-amount. /// - public int Exponent { get; set; } + public int Exponent { get; internal set; } /// /// The level of the Hype Chat, in English.Possible values are: /// - public PaidLevel Level { get; set; } + public PaidLevel Level { get; internal set; } /// /// A Boolean value that determines if the message sent with the Hype Chat was filled in by the system. @@ -33,5 +33,5 @@ public class HypeChat /// If true (1), the user entered no message and the body message was automatically filled in by the system. /// If false (0), the user provided their own message to send with the Hype Chat. /// - public bool IsSystemMessage { get; set; } + public bool IsSystemMessage { get; internal set; } } diff --git a/TwitchLib.Client.Models/Internal/IrcMessage.cs b/TwitchLib.Client.Models/Internal/IrcMessage.cs index 72dd0fd7..a2e2a3ee 100644 --- a/TwitchLib.Client.Models/Internal/IrcMessage.cs +++ b/TwitchLib.Client.Models/Internal/IrcMessage.cs @@ -1,4 +1,4 @@ -using System.Text; +using System.Text; using TwitchLib.Client.Enums.Internal; @@ -10,7 +10,7 @@ public class IrcMessage /// The channel the message was sent in /// public string Channel => _channel ??= Params.StartsWith("#") ? Params.Remove(0, 1) : Params; - private string _channel; + private string? _channel; public string Params => _parameters?.Length > 0 ? _parameters[0] : ""; @@ -24,7 +24,7 @@ public class IrcMessage /// /// Command parameters /// - private readonly string[] _parameters; + private readonly string[]? _parameters; /// /// The user whose message it is @@ -34,7 +34,7 @@ public class IrcMessage /// /// Hostmask of the user /// - public string Hostmask { get; } + public string? Hostmask { get; } /// /// Raw Command @@ -46,7 +46,7 @@ public class IrcMessage /// public Dictionary Tags { get; } - private string _rawString; + private string? _rawString; /// /// Create an INCOMPLETE IrcMessage only carrying username @@ -72,7 +72,7 @@ public IrcMessage( IrcCommand command, string[] parameters, string hostmask, - Dictionary tags = null) + Dictionary? tags = null) { var idx = hostmask.IndexOf('!'); User = idx >= 0 ? hostmask.Substring(0, idx) : hostmask; @@ -106,7 +106,7 @@ internal IrcMessage( string[] parameters, string user, string hostmask, - Dictionary tags = null) + Dictionary? tags = null) { User = user; Hostmask = hostmask; diff --git a/TwitchLib.Client.Models/Internal/MsgIds.cs b/TwitchLib.Client.Models/Internal/MsgIds.cs index 531f4f42..0edfed7c 100644 --- a/TwitchLib.Client.Models/Internal/MsgIds.cs +++ b/TwitchLib.Client.Models/Internal/MsgIds.cs @@ -1,4 +1,6 @@ -namespace TwitchLib.Client.Models.Internal +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + +namespace TwitchLib.Client.Models.Internal { public static class MsgIds { diff --git a/TwitchLib.Client.Models/JoinedChannel.cs b/TwitchLib.Client.Models/JoinedChannel.cs index 75df2a63..ecefd752 100644 --- a/TwitchLib.Client.Models/JoinedChannel.cs +++ b/TwitchLib.Client.Models/JoinedChannel.cs @@ -9,11 +9,11 @@ public class JoinedChannel /// The current channel the TwitcChatClient is connected to. public string Channel { get; } - /// Object representing current state of channel (r9k, slow, etc). - public ChannelState ChannelState { get; protected set; } + ///// Object representing current state of channel (r9k, slow, etc). + //public ChannelState ChannelState { get; protected set; } /// The most recent message received. - public ChatMessage PreviousMessage { get; protected set; } + public ChatMessage? PreviousMessage { get; protected set; } /// JoinedChannel object constructor. public JoinedChannel(string channel) diff --git a/TwitchLib.Client.Models/MessageEmote.cs b/TwitchLib.Client.Models/MessageEmote.cs index 0090a0a0..2a1c178e 100644 --- a/TwitchLib.Client.Models/MessageEmote.cs +++ b/TwitchLib.Client.Models/MessageEmote.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +#nullable disable using System.Collections.ObjectModel; using System.Text.RegularExpressions; diff --git a/TwitchLib.Client.Models/OutboundChatMessage.cs b/TwitchLib.Client.Models/OutboundChatMessage.cs index 78afea70..3e40ec77 100644 --- a/TwitchLib.Client.Models/OutboundChatMessage.cs +++ b/TwitchLib.Client.Models/OutboundChatMessage.cs @@ -6,23 +6,24 @@ public class OutboundChatMessage public string Message { get; set; } - public string Username { get; set; } - - public string ReplyToId { get; set; } + public string? ReplyToId { get; set; } + /// + /// Initializes a new instance of the class. + /// + public OutboundChatMessage(string channel, string message) + { + Channel = channel; + Message = message; + } + + /// public override string ToString() { var channel = Channel.ToLower(); - if (ReplyToId == null) - { - var user = Username.ToLower(); - return $":{user}!{user}@{user}.tmi.twitch.tv PRIVMSG #{channel} :{Message}"; - } - else - { - return $"@reply-parent-msg-id={ReplyToId} PRIVMSG #{channel} :{Message}"; - } - + return ReplyToId is null + ? $"PRIVMSG #{channel} :{Message}" + : $"@reply-parent-msg-id={ReplyToId} PRIVMSG #{channel} :{Message}"; } } } diff --git a/TwitchLib.Client.Models/OutgoingMessage.cs b/TwitchLib.Client.Models/OutgoingMessage.cs deleted file mode 100644 index e5aa69ba..00000000 --- a/TwitchLib.Client.Models/OutgoingMessage.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace TwitchLib.Client.Models -{ - public class OutgoingMessage - { - public string Channel { get; set; } - - public string Message { get; set; } - - public int Nonce { get; set; } - - public string Sender { get; set; } - - public MessageState State { get; set; } - } - - public enum MessageState : byte - { - /// Message did not originate from this session, or was successfully sent. - Normal = 0, - - /// Message is current queued. - Queued, - - /// Message failed to be sent. - Failed - } -} - diff --git a/TwitchLib.Client.Models/RaidNotification.cs b/TwitchLib.Client.Models/RaidNotification.cs index a506a6e4..5dee4737 100644 --- a/TwitchLib.Client.Models/RaidNotification.cs +++ b/TwitchLib.Client.Models/RaidNotification.cs @@ -1,4 +1,6 @@ -using TwitchLib.Client.Enums; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using TwitchLib.Client.Enums; using TwitchLib.Client.Models.Interfaces; using TwitchLib.Client.Models.Internal; @@ -47,6 +49,11 @@ public class RaidNotification : IHexColorProperty public UserType UserType { get; } + /// + /// Contains undocumented tags. + /// + public Dictionary? UndocumentedTags { get; } + // @badges=;color=#FF0000;display-name=Heinki;emotes=;id=4fb7ab2d-aa2c-4886-a286-46e20443f3d6;login=heinki;mod=0;msg-id=raid;msg-param-displayName=Heinki;msg-param-login=heinki;msg-param-viewerCount=4;room-id=27229958;subscriber=0;system-msg=4\sraiders\sfrom\sHeinki\shave\sjoined\n!;tmi-sent-ts=1510249711023;turbo=0;user-id=44110799;user-type= :tmi.twitch.tv USERNOTICE #pandablack public RaidNotification(IrcMessage ircMessage) { @@ -110,6 +117,9 @@ public RaidNotification(IrcMessage ircMessage) case Tags.UserType: UserType = TagHelper.ToUserType(tag.Value); break; + default: + (UndocumentedTags = new()).Add(tag.Key, tag.Value); + break; } } } diff --git a/TwitchLib.Client.Models/RitualNewChatter.cs b/TwitchLib.Client.Models/RitualNewChatter.cs index 4b9021ad..aa34cdd1 100644 --- a/TwitchLib.Client.Models/RitualNewChatter.cs +++ b/TwitchLib.Client.Models/RitualNewChatter.cs @@ -1,4 +1,6 @@ -using TwitchLib.Client.Enums; +#nullable disable +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using TwitchLib.Client.Enums; using TwitchLib.Client.Models.Internal; namespace TwitchLib.Client.Models @@ -43,6 +45,11 @@ public class RitualNewChatter public UserType UserType { get; } + /// + /// Contains undocumented tags. + /// + public Dictionary? UndocumentedTags { get; } + // badges=subscriber/0;color=#0000FF;display-name=KittyJinxu;emotes=30259:0-6;id=1154b7c0-8923-464e-a66b-3ef55b1d4e50; // login=kittyjinxu;mod=0;msg-id=ritual;msg-param-ritual-name=new_chatter;room-id=35740817;subscriber=1; // system-msg=@KittyJinxu\sis\snew\shere.\sSay\shello!;tmi-sent-ts=1514387871555;turbo=0;user-id=187446639; @@ -107,6 +114,9 @@ public RitualNewChatter(IrcMessage ircMessage) case Tags.UserType: UserType = TagHelper.ToUserType(tag.Value); break; + default: + (UndocumentedTags = new()).Add(tag.Key, tag.Value); + break; } } } diff --git a/TwitchLib.Client.Models/SendOptions.cs b/TwitchLib.Client.Models/SendOptions.cs index c4933d41..d31e4e1c 100644 --- a/TwitchLib.Client.Models/SendOptions.cs +++ b/TwitchLib.Client.Models/SendOptions.cs @@ -21,6 +21,7 @@ public class SendOptions : ISendOptions public TimeSpan CacheItemTimeout { get; } /// + /// Initializes a new instance of the class. /// /// /// A of zero means: diff --git a/TwitchLib.Client.Models/SentMessage.cs b/TwitchLib.Client.Models/SentMessage.cs index 86570cb9..7b083a82 100644 --- a/TwitchLib.Client.Models/SentMessage.cs +++ b/TwitchLib.Client.Models/SentMessage.cs @@ -1,4 +1,5 @@ -using TwitchLib.Client.Models.Interfaces; +using TwitchLib.Client.Enums; +using TwitchLib.Client.Models.Interfaces; namespace TwitchLib.Client.Models { @@ -30,7 +31,7 @@ public class SentMessage : IHexColorProperty public string Message { get; } /// The type of user (admin, broadcaster, viewer, moderator) - public Enums.UserType UserType { get; } + public UserType UserType { get; } /// Model constructor. public SentMessage( @@ -48,6 +49,9 @@ public SentMessage( Message = message; } + /// + /// Initializes a new instance of the class. + /// public SentMessage( List> badges, string channel, @@ -56,7 +60,7 @@ public SentMessage( string emoteSet, bool isModerator, bool isSubscriber, - Enums.UserType userType, + UserType userType, string message) { Badges = badges; diff --git a/TwitchLib.Client.Models/SubscriberBase.cs b/TwitchLib.Client.Models/SubscriberBase.cs index eba427a8..27f7253a 100644 --- a/TwitchLib.Client.Models/SubscriberBase.cs +++ b/TwitchLib.Client.Models/SubscriberBase.cs @@ -1,3 +1,4 @@ +#nullable disable using TwitchLib.Client.Enums; using TwitchLib.Client.Models.Interfaces; using TwitchLib.Client.Models.Internal; @@ -84,6 +85,11 @@ public class SubscriberBase : IHexColorProperty protected readonly int monthsInternal; + /// + /// Contains undocumented tags. + /// + public Dictionary? UndocumentedTags { get; } + /// Subscriber object constructor. protected SubscriberBase(IrcMessage ircMessage) { @@ -165,6 +171,9 @@ protected SubscriberBase(IrcMessage ircMessage) case Tags.UserType: UserType = TagHelper.ToUserType(tag.Value); break; + default: + (UndocumentedTags = new()).Add(tag.Key, tag.Value); + break; } } } diff --git a/TwitchLib.Client.Models/TwitchLib.Client.Models.csproj b/TwitchLib.Client.Models/TwitchLib.Client.Models.csproj index 2be9b020..00d43f47 100644 --- a/TwitchLib.Client.Models/TwitchLib.Client.Models.csproj +++ b/TwitchLib.Client.Models/TwitchLib.Client.Models.csproj @@ -3,6 +3,7 @@ netstandard2.0;netstandard2.1;net6.0;net7.0 enable + enable latest TwitchLib.Client.Models 4.0.0 diff --git a/TwitchLib.Client.Models/TwitchLibMessage.cs b/TwitchLib.Client.Models/TwitchLibMessage.cs index b8a2b44b..8fd0235e 100644 --- a/TwitchLib.Client.Models/TwitchLibMessage.cs +++ b/TwitchLib.Client.Models/TwitchLibMessage.cs @@ -7,33 +7,38 @@ namespace TwitchLib.Client.Models public abstract class TwitchLibMessage : IHexColorProperty { /// List of key-value pair badges. - public List> Badges { get; protected set; } + public List> Badges { get; protected set; } = default!; /// Twitch username of the bot that received the message. - public string BotUsername { get; protected set; } + public string BotUsername { get; protected set; } = default!; /// Property representing HEX color as a System.Drawing.Color object. - public string HexColor { get; protected set; } + public string HexColor { get; protected set; } = default!; /// Case-sensitive username of sender of chat message. - public string DisplayName { get; protected set; } + public string DisplayName { get; protected set; } = default!; /// Emote Ids that exist in message. - public EmoteSet EmoteSet { get; protected set; } + public EmoteSet EmoteSet { get; protected set; } = default!; /// Twitch site-wide turbo status. public bool IsTurbo { get; protected set; } /// Twitch-unique integer assigned on per account basis. - public string UserId { get; protected set; } + public string UserId { get; protected set; } = default!; /// Username of sender of chat message. - public string Username { get; protected set; } + public string Username { get; protected set; } = default!; /// User type can be viewer, moderator, global mod, admin, or staff public UserType UserType { get; protected set; } /// Raw IRC-style text received from Twitch. - public string RawIrcMessage { get; protected set; } + public string RawIrcMessage { get; protected set; } = default!; + + /// + /// Contains undocumented tags. + /// + public Dictionary? UndocumentedTags { get; protected set; } } } diff --git a/TwitchLib.Client.Models/UserBan.cs b/TwitchLib.Client.Models/UserBan.cs index 926c5e24..1278d32e 100644 --- a/TwitchLib.Client.Models/UserBan.cs +++ b/TwitchLib.Client.Models/UserBan.cs @@ -5,17 +5,20 @@ namespace TwitchLib.Client.Models public class UserBan { /// Channel that had ban event. - public string Channel; + public string Channel { get; } /// User that was banned. - public string Username; + public string Username { get; } /// Channel that had ban event. Id. - public string RoomId; + public string RoomId { get; } = default!; /// User that was banned. Id. - public string TargetUserId; + public string TargetUserId { get; } = default!; + /// + /// Initializes a new instance of the class. + /// public UserBan(IrcMessage ircMessage) { Channel = ircMessage.Channel; @@ -32,6 +35,9 @@ public UserBan(IrcMessage ircMessage) } } + /// + /// Initializes a new instance of the class. + /// public UserBan( string channel, string username, diff --git a/TwitchLib.Client.Models/UserState.cs b/TwitchLib.Client.Models/UserState.cs index 4739def4..b4ac8f00 100644 --- a/TwitchLib.Client.Models/UserState.cs +++ b/TwitchLib.Client.Models/UserState.cs @@ -1,4 +1,3 @@ -using System.Drawing; using TwitchLib.Client.Enums; using TwitchLib.Client.Models.Interfaces; using TwitchLib.Client.Models.Internal; @@ -18,16 +17,16 @@ public class UserState : IHexColorProperty public string Channel { get; } /// Properrty representing HEX user's name. - public string HexColor { get; } + public string HexColor { get; } = default!; /// Property representing user's display name. - public string DisplayName { get; } + public string DisplayName { get; } = default!; /// Property representing emote sets available to user. - public string EmoteSet { get; } - + public string EmoteSet { get; } = default!; + /// Property representing the user's Id. - public string Id { get; } + public string Id { get; } = default!; /// Property representing Turbo status. public bool IsModerator { get; } @@ -35,9 +34,19 @@ public class UserState : IHexColorProperty /// Property representing subscriber status. public bool IsSubscriber { get; } + /// + /// A Boolean value that indicates whether the user has site-wide commercial free mode enabled. + /// + public bool Turbo { get; } + /// Property representing returned user type of user. public UserType UserType { get; } + /// + /// Contains undocumented tags. + /// + public Dictionary? UndocumentedTags { get; } + /// /// Constructor for UserState. /// @@ -75,12 +84,14 @@ public UserState(IrcMessage ircMessage) case Tags.Subscriber: IsSubscriber = TagHelper.ToBool(tagValue); break; + case Tags.Turbo: + Turbo = TagHelper.ToBool(tagValue); + break; case Tags.UserType: UserType = TagHelper.ToUserType(tag.Value); break; default: - // This should never happen, unless Twitch changes their shit - Console.WriteLine($"Unaccounted for [UserState]: {tag}"); + (UndocumentedTags = new()).Add(tag.Key, tag.Value); break; } } @@ -89,6 +100,9 @@ public UserState(IrcMessage ircMessage) UserType = UserType.Broadcaster; } + /// + /// Initializes a new instance of the class. + /// public UserState( List> badges, List> badgeInfo, diff --git a/TwitchLib.Client.Models/UserTimeout.cs b/TwitchLib.Client.Models/UserTimeout.cs index a74f24ed..98e5d388 100644 --- a/TwitchLib.Client.Models/UserTimeout.cs +++ b/TwitchLib.Client.Models/UserTimeout.cs @@ -5,27 +5,35 @@ namespace TwitchLib.Client.Models public class UserTimeout { /// Channel that had timeout event. - public string Channel; + public string Channel { get; } - /// Duration of timeout IN SECONDS. - public TimeSpan TimeoutDuration; + /// Duration of timeout + public TimeSpan TimeoutDuration { get; } /// Viewer that was timed out. - public string Username; + public string Username { get; } /// Id of Viewer that was timed out. - public string TargetUserId; + public string TargetUserId { get; } = default!; + /// + /// Contains undocumented tags. + /// + public Dictionary? UndocumentedTags { get; } + + /// + /// Initializes a new instance of the class. + /// public UserTimeout(IrcMessage ircMessage) { Channel = ircMessage.Channel; Username = ircMessage.Message; - foreach (var tag in ircMessage.Tags.Keys) + foreach (var tag in ircMessage.Tags) { - var tagValue = ircMessage.Tags[tag]; + var tagValue = tag.Value; - switch (tag) + switch (tag.Key) { case Tags.BanDuration: TimeoutDuration = TimeSpan.FromSeconds(int.Parse(tagValue)); @@ -33,10 +41,16 @@ public UserTimeout(IrcMessage ircMessage) case Tags.TargetUserId: TargetUserId = tagValue; break; + default: + (UndocumentedTags = new()).Add(tag.Key, tag.Value); + break; } } } + /// + /// Initializes a new instance of the class. + /// public UserTimeout( string channel, string username, diff --git a/TwitchLib.Client.Models/WhisperMessage.cs b/TwitchLib.Client.Models/WhisperMessage.cs index 0cb9bcbd..80fa4122 100644 --- a/TwitchLib.Client.Models/WhisperMessage.cs +++ b/TwitchLib.Client.Models/WhisperMessage.cs @@ -7,14 +7,17 @@ namespace TwitchLib.Client.Models public class WhisperMessage : TwitchLibMessage { /// Property representing message identifier. - public string MessageId { get; } + public string MessageId { get; } = default!; /// Property representing identifier of the message thread. - public string ThreadId { get; } + public string ThreadId { get; } = default!; /// Property representing identifier of the message thread. public string Message { get; } + /// + /// Initializes a new instance of the class. + /// public WhisperMessage( List> badges, string hexColor, @@ -87,6 +90,9 @@ public WhisperMessage(IrcMessage ircMessage, string botUsername) case Tags.UserType: UserType = TagHelper.ToUserType(tag.Value); break; + default: + (UndocumentedTags = new()).Add(tag.Key, tag.Value); + break; } } diff --git a/TwitchLib.Client.Test/ThrottlingServiceTests.cs b/TwitchLib.Client.Test/ThrottlingServiceTests.cs index 28ecbe87..64242f5b 100644 --- a/TwitchLib.Client.Test/ThrottlingServiceTests.cs +++ b/TwitchLib.Client.Test/ThrottlingServiceTests.cs @@ -27,7 +27,7 @@ public void EnqueueMessageTests(bool isConnected, uint queueCapacity, bool withM if (withMessage) { - message = new OutboundChatMessage(); + message = new OutboundChatMessage("channel", "message"); } var enqueued = throttlerService.Enqueue(message); diff --git a/TwitchLib.Client/TwitchClient.cs b/TwitchLib.Client/TwitchClient.cs index 350bed25..efcaabab 100644 --- a/TwitchLib.Client/TwitchClient.cs +++ b/TwitchLib.Client/TwitchClient.cs @@ -434,12 +434,7 @@ private void SendTwitchMessage(JoinedChannel channel, string message, string rep return; } - var twitchMessage = new OutboundChatMessage - { - Channel = channel.Channel, - Username = ConnectionCredentials.TwitchUsername, - Message = message - }; + var twitchMessage = new OutboundChatMessage(channel.Channel, message); if (replyToId != null) { @@ -653,7 +648,7 @@ private Task _client_OnFatality(object sender, OnFatalErrorEventArgs e) return OnConnectionError.TryInvoke(this, new() { BotUsername = TwitchUsername, - Error = new() { Message = e.Reason } + Error = new(e.Reason) }); }