From 7781e8e4594f45bdbc157c95311a8e5a82bde518 Mon Sep 17 00:00:00 2001 From: Fl_GUI Date: Sat, 18 May 2024 16:51:25 +0200 Subject: [PATCH] generate all messages --- twitch/core/auth.go | 11 +- twitch/core/clearchat/clearchat.go | 25 --- twitch/core/clearchat/clearchattags.go | 12 -- twitch/core/clearchat/message.go | 54 ++++++ twitch/core/clearmsg/clearmsg.go | 18 -- twitch/core/clearmsg/message.go | 54 ++++++ .../core/globaluserstate/globaluserstate.go | 12 -- .../globaluserstate/globaluserstatetags.go | 16 -- twitch/core/globaluserstate/message.go | 83 +++++++++ twitch/core/hosttarget/hosttarget.go | 36 ---- twitch/core/hosttarget/message.go | 20 +++ twitch/core/join.go | 5 +- twitch/core/messages.go | 23 +++ twitch/core/messages/join.go | 4 +- .../{messages/notice.go => notice/errors.go} | 17 +- twitch/core/notice/message.go | 36 ++++ twitch/core/notice/notice.go | 25 --- twitch/core/notice/noticetags.go | 10 -- twitch/core/privmsg/message.go | 146 ++++++++++++++++ twitch/core/privmsg/privmsg.go | 29 ---- twitch/core/privmsg/privmsgtags.go | 32 ---- twitch/core/reconnect/message.go | 11 ++ twitch/core/roomstate/message.go | 76 ++++++++ twitch/core/roomstate/roomstate.go | 21 --- twitch/core/roomstate/roomstatetags.go | 15 -- twitch/core/usernotice/message.go | 162 ++++++++++++++++++ twitch/core/usernotice/usernotice.go | 20 --- twitch/core/usernotice/usernoticetags.go | 24 --- twitch/core/userstate/message.go | 103 +++++++++++ twitch/core/userstate/userstate.go | 21 --- twitch/core/userstate/userstatetags.go | 17 -- twitch/core/whisper/message.go | 101 +++++++++++ twitch/core/whisper/whisper.go | 31 ---- twitch/core/whisper/whispertags.go | 17 -- x/corechatclient/main.go | 4 +- x/generate/message/clearchat/message.go | 54 ++++++ x/generate/message/convert.go | 86 ++++++++++ x/generate/message/convert_test.go | 21 +++ x/generate/message/generateMessage.go | 87 ++++++++++ x/generate/message/main.go | 55 ++++++ 40 files changed, 1188 insertions(+), 406 deletions(-) delete mode 100644 twitch/core/clearchat/clearchat.go delete mode 100755 twitch/core/clearchat/clearchattags.go create mode 100644 twitch/core/clearchat/message.go delete mode 100644 twitch/core/clearmsg/clearmsg.go create mode 100644 twitch/core/clearmsg/message.go delete mode 100644 twitch/core/globaluserstate/globaluserstate.go delete mode 100755 twitch/core/globaluserstate/globaluserstatetags.go create mode 100644 twitch/core/globaluserstate/message.go delete mode 100644 twitch/core/hosttarget/hosttarget.go create mode 100644 twitch/core/hosttarget/message.go create mode 100644 twitch/core/messages.go rename twitch/core/{messages/notice.go => notice/errors.go} (61%) create mode 100644 twitch/core/notice/message.go delete mode 100644 twitch/core/notice/notice.go delete mode 100755 twitch/core/notice/noticetags.go create mode 100644 twitch/core/privmsg/message.go delete mode 100644 twitch/core/privmsg/privmsg.go delete mode 100755 twitch/core/privmsg/privmsgtags.go create mode 100644 twitch/core/reconnect/message.go create mode 100644 twitch/core/roomstate/message.go delete mode 100644 twitch/core/roomstate/roomstate.go delete mode 100755 twitch/core/roomstate/roomstatetags.go create mode 100644 twitch/core/usernotice/message.go delete mode 100644 twitch/core/usernotice/usernotice.go delete mode 100755 twitch/core/usernotice/usernoticetags.go create mode 100644 twitch/core/userstate/message.go delete mode 100644 twitch/core/userstate/userstate.go delete mode 100755 twitch/core/userstate/userstatetags.go create mode 100644 twitch/core/whisper/message.go delete mode 100644 twitch/core/whisper/whisper.go delete mode 100755 twitch/core/whisper/whispertags.go create mode 100644 x/generate/message/clearchat/message.go create mode 100644 x/generate/message/convert.go create mode 100644 x/generate/message/convert_test.go create mode 100644 x/generate/message/generateMessage.go create mode 100644 x/generate/message/main.go diff --git a/twitch/core/auth.go b/twitch/core/auth.go index 452f531..edde3ff 100644 --- a/twitch/core/auth.go +++ b/twitch/core/auth.go @@ -4,6 +4,7 @@ import ( "errors" "twitchchat/twitch/core/commands" "twitchchat/twitch/core/messages" + "twitchchat/twitch/core/notice" ) // see https://dev.twitch.tv/docs/irc/authenticate-bot/#sending-the-pass-and-nick-messages. @@ -31,9 +32,9 @@ func (c *Conn) Authenticate(nickname, access_token string, msgs <-chan messages. authResp <- msg close(authResp) case commands.Notice: - err := msg.ToNoticeError() - if errors.Is(err, messages.LoginFailedError) || - errors.Is(err, messages.InvalidAuthError) { + err := notice.Notice{msg}.ToNoticeError() + if errors.Is(err, notice.LoginFailedError) || + errors.Is(err, notice.InvalidAuthError) { authResp <- msg close(authResp) } else { @@ -49,8 +50,8 @@ func (c *Conn) Authenticate(nickname, access_token string, msgs <-chan messages. c.WriteMessage(messages.Nick(nickname)) for m := range authResp { - if messages.IsNotice(m) { - return res, m.ToNoticeError() + if notice.IsNotice(m) { + return res, notice.Notice{m}.ToNoticeError() } } diff --git a/twitch/core/clearchat/clearchat.go b/twitch/core/clearchat/clearchat.go deleted file mode 100644 index f1dc74f..0000000 --- a/twitch/core/clearchat/clearchat.go +++ /dev/null @@ -1,25 +0,0 @@ -package clearchat - -import ( - "twitchchat/irc" - "twitchchat/twitch/core/commands" - "twitchchat/twitch/core/messages" -) - -//go:generate tagprototype -out clearchattags.go -package clearchat -prototype @ban-duration=;room-id=;target-user-id=;tmi-sent-ts= -type ClearChatTag - -type ClearChat struct { - messages.Message -} - -func IsClearChat(m messages.Message) bool { - return string(m.Command) == commands.ClearChat -} - -func (c ClearChat) GetTag(key ClearChatTag) *irc.Tag { - return c.Message.GetTag(string(key)) -} - -func (c ClearChat) User() string { - return c.Params.Trailing -} diff --git a/twitch/core/clearchat/clearchattags.go b/twitch/core/clearchat/clearchattags.go deleted file mode 100755 index 6d1e9ae..0000000 --- a/twitch/core/clearchat/clearchattags.go +++ /dev/null @@ -1,12 +0,0 @@ -//Generated by twitch-chat/x/generate/tagprototype - -package clearchat - -type ClearChatTag string - -const ( - BanDuration ClearChatTag = "ban-duration" - RoomId ClearChatTag = "room-id" - TargetUserId ClearChatTag = "target-user-id" - TmiSentTs ClearChatTag = "tmi-sent-ts" -) diff --git a/twitch/core/clearchat/message.go b/twitch/core/clearchat/message.go new file mode 100644 index 0000000..1aac42c --- /dev/null +++ b/twitch/core/clearchat/message.go @@ -0,0 +1,54 @@ +// generated by message + +package clearchat + +import ( + "strings" + "twitchchat/twitch/core/messages" +) + +type Clearchat struct { + messages.Message +} + +func IsClearchat(m messages.Message) bool { return string(m.Command) == "CLEARCHAT" } + +func (m Clearchat) Channel() string { return m.Params.Params[0][1:] } + +func (m Clearchat) User() string { return strings.Split(m.Params.Trailing, " ")[0][0:] } + +func (m Clearchat) Duration() string { + for _, t := range m.Tags { + if t.Key == "ban-duration" { + return t.Value + } + } + return "" +} + +func (m Clearchat) RoomId() string { + for _, t := range m.Tags { + if t.Key == "room-id" { + return t.Value + } + } + return "" +} + +func (m Clearchat) UserId() string { + for _, t := range m.Tags { + if t.Key == "target-user-id" { + return t.Value + } + } + return "" +} + +func (m Clearchat) Timestamp() string { + for _, t := range m.Tags { + if t.Key == "tmi-sent-ts" { + return t.Value + } + } + return "" +} diff --git a/twitch/core/clearmsg/clearmsg.go b/twitch/core/clearmsg/clearmsg.go deleted file mode 100644 index ae64d6f..0000000 --- a/twitch/core/clearmsg/clearmsg.go +++ /dev/null @@ -1,18 +0,0 @@ -package clearmsg - -import ( - "twitchchat/twitch/core/commands" - "twitchchat/twitch/core/messages" -) - -type ClearMsg struct { - messages.Message -} - -func IsClearMsg(m messages.Message) bool { - return string(m.Command) == commands.ClearMsg -} - -func (c ClearMsg) ChatMessage() string { - return c.Params.Trailing -} diff --git a/twitch/core/clearmsg/message.go b/twitch/core/clearmsg/message.go new file mode 100644 index 0000000..2962967 --- /dev/null +++ b/twitch/core/clearmsg/message.go @@ -0,0 +1,54 @@ +// generated by message + +package clearmsg + +import ( + "strings" + "twitchchat/twitch/core/messages" +) + +type Clearmsg struct { + messages.Message +} + +func IsClearmsg(m messages.Message) bool { return string(m.Command) == "CLEARMSG" } + +func (m Clearmsg) Channel() string { return m.Params.Params[0][1:] } + +func (m Clearmsg) UserMessage() string { return strings.Split(m.Params.Trailing, " ")[0][0:] } + +func (m Clearmsg) Login() string { + for _, t := range m.Tags { + if t.Key == "login" { + return t.Value + } + } + return "" +} + +func (m Clearmsg) RoomId() string { + for _, t := range m.Tags { + if t.Key == "room-id" { + return t.Value + } + } + return "" +} + +func (m Clearmsg) TargetMsgId() string { + for _, t := range m.Tags { + if t.Key == "target-msg-id" { + return t.Value + } + } + return "" +} + +func (m Clearmsg) Timestamp() string { + for _, t := range m.Tags { + if t.Key == "tmi-sent-ts" { + return t.Value + } + } + return "" +} diff --git a/twitch/core/globaluserstate/globaluserstate.go b/twitch/core/globaluserstate/globaluserstate.go deleted file mode 100644 index 8c64a35..0000000 --- a/twitch/core/globaluserstate/globaluserstate.go +++ /dev/null @@ -1,12 +0,0 @@ -package globaluserstate - -import ( - "twitchchat/twitch/core/commands" - "twitchchat/twitch/core/messages" -) - -//go:generate tagprototype -out globaluserstatetags.go -package globaluserstate -type GlobalUserStateTag -prototype @badge-info=;badges=;color=;display-name=;emote-sets=;turbo=;user-id=;user-type= - -func IsGlobalUserState(m messages.Message) bool { - return m.Command == commands.GlobalUserState -} diff --git a/twitch/core/globaluserstate/globaluserstatetags.go b/twitch/core/globaluserstate/globaluserstatetags.go deleted file mode 100755 index e8861de..0000000 --- a/twitch/core/globaluserstate/globaluserstatetags.go +++ /dev/null @@ -1,16 +0,0 @@ -//Generated by twitch-chat/x/generate/tagprototype - -package globaluserstate - -type GlobalUserStateTag string - -const ( - BadgeInfo GlobalUserStateTag = "badge-info" - Badges GlobalUserStateTag = "badges" - Color GlobalUserStateTag = "color" - DisplayName GlobalUserStateTag = "display-name" - EmoteSets GlobalUserStateTag = "emote-sets" - Turbo GlobalUserStateTag = "turbo" - UserId GlobalUserStateTag = "user-id" - UserType GlobalUserStateTag = "user-type" -) diff --git a/twitch/core/globaluserstate/message.go b/twitch/core/globaluserstate/message.go new file mode 100644 index 0000000..8c985e4 --- /dev/null +++ b/twitch/core/globaluserstate/message.go @@ -0,0 +1,83 @@ +// generated by message + +package globaluserstate + +import "twitchchat/twitch/core/messages" + +type Globaluserstate struct { + messages.Message +} + +func IsGlobaluserstate(m messages.Message) bool { return string(m.Command) == "GLOBALUSERSTATE" } + +func (m Globaluserstate) BadgeInfo() string { + for _, t := range m.Tags { + if t.Key == "badge-info" { + return t.Value + } + } + return "" +} + +func (m Globaluserstate) Badges() string { + for _, t := range m.Tags { + if t.Key == "badges" { + return t.Value + } + } + return "" +} + +func (m Globaluserstate) Color() string { + for _, t := range m.Tags { + if t.Key == "color" { + return t.Value + } + } + return "" +} + +func (m Globaluserstate) DisplayName() string { + for _, t := range m.Tags { + if t.Key == "display-name" { + return t.Value + } + } + return "" +} + +func (m Globaluserstate) EmoteSets() string { + for _, t := range m.Tags { + if t.Key == "emote-sets" { + return t.Value + } + } + return "" +} + +func (m Globaluserstate) Turbo() string { + for _, t := range m.Tags { + if t.Key == "turbo" { + return t.Value + } + } + return "" +} + +func (m Globaluserstate) UserId() string { + for _, t := range m.Tags { + if t.Key == "user-id" { + return t.Value + } + } + return "" +} + +func (m Globaluserstate) UserType() string { + for _, t := range m.Tags { + if t.Key == "user-type" { + return t.Value + } + } + return "" +} diff --git a/twitch/core/hosttarget/hosttarget.go b/twitch/core/hosttarget/hosttarget.go deleted file mode 100644 index b174960..0000000 --- a/twitch/core/hosttarget/hosttarget.go +++ /dev/null @@ -1,36 +0,0 @@ -package hosttarget - -import ( - "strconv" - "strings" - "twitchchat/twitch/core/commands" - "twitchchat/twitch/core/messages" -) - -type HostTarget struct { - messages.Message -} - -func IsHostTarget(m messages.Message) bool { - return m.Command == commands.HostTarget -} - -func (h HostTarget) ChannelTarget() string { - parts := strings.Split(h.Params.Trailing, " ") - if len(parts) != 2 { - return "" - } - return parts[0] -} - -func (h HostTarget) NumberOfViewers() int { - parts := strings.Split(h.Params.Trailing, " ") - if len(parts) != 2 { - return 0 - } - if i, err := strconv.Atoi(parts[1]); err != nil { - return 0 - } else { - return i - } -} diff --git a/twitch/core/hosttarget/message.go b/twitch/core/hosttarget/message.go new file mode 100644 index 0000000..a020ba7 --- /dev/null +++ b/twitch/core/hosttarget/message.go @@ -0,0 +1,20 @@ +// generated by message + +package hosttarget + +import ( + "strings" + "twitchchat/twitch/core/messages" +) + +type Hosttarget struct { + messages.Message +} + +func IsHosttarget(m messages.Message) bool { return string(m.Command) == "HOSTTARGET" } + +func (m Hosttarget) HostingChannel() string { return m.Params.Params[0][1:] } + +func (m Hosttarget) Channel() string { return strings.Split(m.Params.Trailing, " ")[0][0:] } + +func (m Hosttarget) NumberOfViewers() string { return strings.Split(m.Params.Trailing, " ")[1][0:] } diff --git a/twitch/core/join.go b/twitch/core/join.go index a82baa4..1edc257 100644 --- a/twitch/core/join.go +++ b/twitch/core/join.go @@ -3,6 +3,7 @@ package core import ( "fmt" "twitchchat/twitch/core/messages" + "twitchchat/twitch/core/notice" ) type ChannelMembers map[string][]string @@ -16,8 +17,8 @@ func (w *Conn) Join(msgs <-chan messages.Message, channels ...string) (<-chan me resp := <-msgs fmt.Fprintf(DebugLogger, "Reading channel members for %s\n", resp) - if messages.IsNotice(resp) { - return msgs, channelMembers, resp.ToNoticeError() + if notice.IsNotice(resp) { + return msgs, channelMembers, notice.Notice{resp}.ToNoticeError() } else if !messages.IsJoin(resp) { return msgs, channelMembers, UnexpectedAnswerError } diff --git a/twitch/core/messages.go b/twitch/core/messages.go new file mode 100644 index 0000000..423fc3c --- /dev/null +++ b/twitch/core/messages.go @@ -0,0 +1,23 @@ +package core + +//go:generate message -proto "@badge-info=;badges=;client-nonce=;color=;display-name=;emote-only=;emotes=;first-msg=;flags=;id=;mod=;room-id=;subscriber=;tmi-sent-ts=;turbo=;user-id=;user-type= :!@.tmi.twitch.tv PRIVMSG # :" + +//go:generate message -proto "@ban-duration=;room-id=;target-user-id=;tmi-sent-ts= :tmi.twitch.tv CLEARCHAT # :" + +//go:generate message -proto "@login=;room-id=;target-msg-id=;tmi-sent-ts= :tmi.twitch.tv CLEARMSG # :" + +//go:generate message -proto "@badge-info=;badges=;color=;display-name=;emote-sets=;turbo=;user-id=;user-type= :tmi.twitch.tv GLOBALUSERSTATE" + +//go:generate message -proto ":tmi.twitch.tv HOSTTARGET # :[-|] " + +//go:generate message -proto "@msg-id=;target-user-id= :tmi.twitch.tv NOTICE # :" + +//go:generate message -proto ":tmi.twitch.tv RECONNECT" + +//go:generate message -proto "@emote-only=;followers-only=;r9k=;rituals=;room-id=;slow=;subs-only= :tmi.twitch.tv ROOMSTATE #" + +//go:generate message -proto "@badge-info=;badges=;color=;display-name=;emotes=;id=;login=;mod=;msg-id=;room-id=;subscriber=;system-msg=;tmi-sent-ts=;turbo=;user-id=;user-type= :tmi.twitch.tv USERNOTICE # :[]" + +//go:generate message -proto "@badge-info=;badges=;color=;display-name=;emote-sets=;id=;mod=;subscriber=;turbo=;user-type= :tmi.twitch.tv USERSTATE #" + +//go:generate message -proto "@badges=;color=;display-name=;emotes=;message-id=;thread-id=;turbo=;user-id=;user-type= :!@.tmi.twitch.tv WHISPER :" diff --git a/twitch/core/messages/join.go b/twitch/core/messages/join.go index a5c6439..bbc8165 100644 --- a/twitch/core/messages/join.go +++ b/twitch/core/messages/join.go @@ -10,9 +10,9 @@ func Join(channels ...string) Message { b := strings.Builder{} for n, c := range channels { if n != 0 { - b.WriteString(",") + b.WriteByte(',') } - b.WriteString("#") + b.WriteByte('#') b.WriteString(c) } return Message{ diff --git a/twitch/core/messages/notice.go b/twitch/core/notice/errors.go similarity index 61% rename from twitch/core/messages/notice.go rename to twitch/core/notice/errors.go index 650a4e9..dc46453 100644 --- a/twitch/core/messages/notice.go +++ b/twitch/core/notice/errors.go @@ -1,22 +1,11 @@ -package messages +package notice -import ( - "errors" - "twitchchat/twitch/core/commands" -) +import "errors" var LoginFailedError = errors.New("login authentication failed") var InvalidAuthError = errors.New("improperly formatted auth") -func IsNotice(m Message) bool { - return m.Command == commands.Notice -} - -func (m Message) ToNoticeError() error { - if !IsNotice(m) { - return nil - } - +func (m Notice) ToNoticeError() error { // known errors by string value switch m.Params.Trailing { case "Login authentication failed": diff --git a/twitch/core/notice/message.go b/twitch/core/notice/message.go new file mode 100644 index 0000000..7ae9435 --- /dev/null +++ b/twitch/core/notice/message.go @@ -0,0 +1,36 @@ +// generated by message + +package notice + +import ( + "strings" + "twitchchat/twitch/core/messages" +) + +type Notice struct { + messages.Message +} + +func IsNotice(m messages.Message) bool { return string(m.Command) == "NOTICE" } + +func (m Notice) Channel() string { return m.Params.Params[0][1:] } + +func (m Notice) NoticeMessage() string { return strings.Split(m.Params.Trailing, " ")[0][0:] } + +func (m Notice) MsgId() string { + for _, t := range m.Tags { + if t.Key == "msg-id" { + return t.Value + } + } + return "" +} + +func (m Notice) UserId() string { + for _, t := range m.Tags { + if t.Key == "target-user-id" { + return t.Value + } + } + return "" +} diff --git a/twitch/core/notice/notice.go b/twitch/core/notice/notice.go deleted file mode 100644 index 49afc93..0000000 --- a/twitch/core/notice/notice.go +++ /dev/null @@ -1,25 +0,0 @@ -package notice - -import ( - "twitchchat/irc" - "twitchchat/twitch/core/commands" - "twitchchat/twitch/core/messages" -) - -//go:generate tagprototype -out noticetags.go -package notice -type NoticeTag -prototype @msg-id=;target-user-id= - -type Notice struct { - messages.Message -} - -func IsNotice(m messages.Message) bool { - return m.Command == commands.Notice -} - -func (n Notice) GetTag(tag NoticeTag) *irc.Tag { - return n.Message.GetTag(string(tag)) -} - -func (n Notice) NoticeMessage() string { - return n.Params.Trailing -} diff --git a/twitch/core/notice/noticetags.go b/twitch/core/notice/noticetags.go deleted file mode 100755 index c1de781..0000000 --- a/twitch/core/notice/noticetags.go +++ /dev/null @@ -1,10 +0,0 @@ -//Generated by twitch-chat/x/generate/tagprototype - -package notice - -type NoticeTag string - -const ( - MsgId NoticeTag = "msg-id" - TargetUserId NoticeTag = "target-user-id" -) diff --git a/twitch/core/privmsg/message.go b/twitch/core/privmsg/message.go new file mode 100644 index 0000000..03d84c2 --- /dev/null +++ b/twitch/core/privmsg/message.go @@ -0,0 +1,146 @@ +// generated by message + +package privmsg + +import ( + "strings" + "twitchchat/twitch/core/messages" +) + +type Privmsg struct { + messages.Message +} + +func IsPrivmsg(m messages.Message) bool { return string(m.Command) == "PRIVMSG" } + +func (m Privmsg) User() string { return m.Prefix.User } + +func (m Privmsg) Channel() string { return m.Params.Params[0][1:] } + +func (m Privmsg) UserMessage() string { return strings.Split(m.Params.Trailing, " ")[0][0:] } + +func (m Privmsg) Badges() string { + for _, t := range m.Tags { + if t.Key == "badges" { + return t.Value + } + } + return "" +} + +func (m Privmsg) ClientNonce() string { + for _, t := range m.Tags { + if t.Key == "client-nonce" { + return t.Value + } + } + return "" +} + +func (m Privmsg) Color() string { + for _, t := range m.Tags { + if t.Key == "color" { + return t.Value + } + } + return "" +} + +func (m Privmsg) DisplayName() string { + for _, t := range m.Tags { + if t.Key == "display-name" { + return t.Value + } + } + return "" +} + +func (m Privmsg) EmoteOnly() string { + for _, t := range m.Tags { + if t.Key == "emote-only" { + return t.Value + } + } + return "" +} + +func (m Privmsg) Emotes() string { + for _, t := range m.Tags { + if t.Key == "emotes" { + return t.Value + } + } + return "" +} + +func (m Privmsg) FirstMsg() string { + for _, t := range m.Tags { + if t.Key == "first-msg" { + return t.Value + } + } + return "" +} + +func (m Privmsg) Id() string { + for _, t := range m.Tags { + if t.Key == "id" { + return t.Value + } + } + return "" +} + +func (m Privmsg) Mod() string { + for _, t := range m.Tags { + if t.Key == "mod" { + return t.Value + } + } + return "" +} + +func (m Privmsg) RoomId() string { + for _, t := range m.Tags { + if t.Key == "room-id" { + return t.Value + } + } + return "" +} + +func (m Privmsg) Subscriber() string { + for _, t := range m.Tags { + if t.Key == "subscriber" { + return t.Value + } + } + return "" +} + +func (m Privmsg) TmiSentTs() string { + for _, t := range m.Tags { + if t.Key == "tmi-sent-ts" { + return t.Value + } + } + return "" +} + +func (m Privmsg) Turbo() string { + for _, t := range m.Tags { + if t.Key == "turbo" { + return t.Value + } + } + return "" +} + +func (m Privmsg) UserId() string { + for _, t := range m.Tags { + if t.Key == "user-id" { + return t.Value + } + } + return "" +} diff --git a/twitch/core/privmsg/privmsg.go b/twitch/core/privmsg/privmsg.go deleted file mode 100644 index 496c30e..0000000 --- a/twitch/core/privmsg/privmsg.go +++ /dev/null @@ -1,29 +0,0 @@ -package privmsg - -import ( - "twitchchat/irc" - "twitchchat/twitch/core/commands" - "twitchchat/twitch/core/messages" -) - -//go:generate tagprototype -out "privmsgtags.go" -type PrivMsgTag -prototype "@badge-info=;badges=;bits=client-nonce=;color=;display-name=;emotes=;first-msg=;flags=;id=;mod=;room-id=;subscriber=;tmi-sent-ts=;turbo=;user-id=;user-type=;reply-parent-msg-id=;reply-parent-user-id=;reply-parent-user-login=;reply-parent-display-name=;reply-parent-msg-body=;reply-thread-parent-msg-id=;reply-thread-parent-user-login=;vip=" -package privmsg - -type PrivMsg struct { - messages.Message -} - -func IsPrivateMessage(m messages.Message) bool { - return string(m.Command) == commands.PrivMsg -} - -func (p PrivMsg) User() string { - return p.Prefix.Name -} - -func (p PrivMsg) Text() string { - return p.Params.Trailing -} - -func (p PrivMsg) GetTag(key PrivMsgTag) *irc.Tag { - return p.Message.GetTag(string(key)) -} diff --git a/twitch/core/privmsg/privmsgtags.go b/twitch/core/privmsg/privmsgtags.go deleted file mode 100755 index f9e3571..0000000 --- a/twitch/core/privmsg/privmsgtags.go +++ /dev/null @@ -1,32 +0,0 @@ -//Generated by twitch-chat/x/generate/tagprototype - -package privmsg - -type PrivMsgTag string - -const ( - BadgeInfo PrivMsgTag = "badge-info" - Badges PrivMsgTag = "badges" - Bits PrivMsgTag = "bits" - Color PrivMsgTag = "color" - DisplayName PrivMsgTag = "display-name" - Emotes PrivMsgTag = "emotes" - FirstMsg PrivMsgTag = "first-msg" - Flags PrivMsgTag = "flags" - Id PrivMsgTag = "id" - Mod PrivMsgTag = "mod" - RoomId PrivMsgTag = "room-id" - Subscriber PrivMsgTag = "subscriber" - TmiSentTs PrivMsgTag = "tmi-sent-ts" - Turbo PrivMsgTag = "turbo" - UserId PrivMsgTag = "user-id" - UserType PrivMsgTag = "user-type" - ReplyParentMsgId PrivMsgTag = "reply-parent-msg-id" - ReplyParentUserId PrivMsgTag = "reply-parent-user-id" - ReplyParentUserLogin PrivMsgTag = "reply-parent-user-login" - ReplyParentDisplayName PrivMsgTag = "reply-parent-display-name" - ReplyParentMsgBody PrivMsgTag = "reply-parent-msg-body" - ReplyThreadParentMsgId PrivMsgTag = "reply-thread-parent-msg-id" - ReplyThreadParentUserLogin PrivMsgTag = "reply-thread-parent-user-login" - Vip PrivMsgTag = "vip" -) diff --git a/twitch/core/reconnect/message.go b/twitch/core/reconnect/message.go new file mode 100644 index 0000000..632c90b --- /dev/null +++ b/twitch/core/reconnect/message.go @@ -0,0 +1,11 @@ +// generated by message + +package reconnect + +import "twitchchat/twitch/core/messages" + +type Reconnect struct { + messages.Message +} + +func IsReconnect(m messages.Message) bool { return string(m.Command) == "RECONNECT" } diff --git a/twitch/core/roomstate/message.go b/twitch/core/roomstate/message.go new file mode 100644 index 0000000..61997b4 --- /dev/null +++ b/twitch/core/roomstate/message.go @@ -0,0 +1,76 @@ +// generated by message + +package roomstate + +import "twitchchat/twitch/core/messages" + +type Roomstate struct { + messages.Message +} + +func IsRoomstate(m messages.Message) bool { return string(m.Command) == "ROOMSTATE" } + +func (m Roomstate) Channel() string { return m.Params.Params[0][1:] } + +func (m Roomstate) EmoteOnly() string { + for _, t := range m.Tags { + if t.Key == "emote-only" { + return t.Value + } + } + return "" +} + +func (m Roomstate) FollowersOnly() string { + for _, t := range m.Tags { + if t.Key == "followers-only" { + return t.Value + } + } + return "" +} + +func (m Roomstate) R9k() string { + for _, t := range m.Tags { + if t.Key == "r9k" { + return t.Value + } + } + return "" +} + +func (m Roomstate) Rituals() string { + for _, t := range m.Tags { + if t.Key == "rituals" { + return t.Value + } + } + return "" +} + +func (m Roomstate) RoomId() string { + for _, t := range m.Tags { + if t.Key == "room-id" { + return t.Value + } + } + return "" +} + +func (m Roomstate) Slow() string { + for _, t := range m.Tags { + if t.Key == "slow" { + return t.Value + } + } + return "" +} + +func (m Roomstate) SubsOnly() string { + for _, t := range m.Tags { + if t.Key == "subs-only" { + return t.Value + } + } + return "" +} diff --git a/twitch/core/roomstate/roomstate.go b/twitch/core/roomstate/roomstate.go deleted file mode 100644 index 6817a70..0000000 --- a/twitch/core/roomstate/roomstate.go +++ /dev/null @@ -1,21 +0,0 @@ -package roomstate - -import ( - "twitchchat/irc" - "twitchchat/twitch/core/commands" - "twitchchat/twitch/core/messages" -) - -//go:generate tagprototype -out roomstatetags.go -package roomstate -type RoomStateTag -prototype @emote-only=;followers-only=;r9k=;rituals=;room-id=;slow=;subs-only= - -type RoomState struct { - messages.Message -} - -func IsRoomState(m messages.Message) bool { - return m.Command == commands.RoomState -} - -func (r RoomState) GetTag(tag RoomStateTag) *irc.Tag { - return r.Message.GetTag(string(tag)) -} diff --git a/twitch/core/roomstate/roomstatetags.go b/twitch/core/roomstate/roomstatetags.go deleted file mode 100755 index 8e5e16d..0000000 --- a/twitch/core/roomstate/roomstatetags.go +++ /dev/null @@ -1,15 +0,0 @@ -//Generated by twitch-chat/x/generate/tagprototype - -package roomstate - -type RoomStateTag string - -const ( - EmoteOnly RoomStateTag = "emote-only" - FollowersOnly RoomStateTag = "followers-only" - R9k RoomStateTag = "r9k" - Rituals RoomStateTag = "rituals" - RoomId RoomStateTag = "room-id" - Slow RoomStateTag = "slow" - SubsOnly RoomStateTag = "subs-only" -) diff --git a/twitch/core/usernotice/message.go b/twitch/core/usernotice/message.go new file mode 100644 index 0000000..0a981cb --- /dev/null +++ b/twitch/core/usernotice/message.go @@ -0,0 +1,162 @@ +// generated by message + +package usernotice + +import ( + "strings" + "twitchchat/twitch/core/messages" +) + +type Usernotice struct { + messages.Message +} + +func IsUsernotice(m messages.Message) bool { return string(m.Command) == "USERNOTICE" } + +func (m Usernotice) Channel() string { return m.Params.Params[0][1:] } + +func (m Usernotice) UserMessage() string { return strings.Split(m.Params.Trailing, " ")[0][0:] } + +func (m Usernotice) BadgeInfo() string { + for _, t := range m.Tags { + if t.Key == "badge-info" { + return t.Value + } + } + return "" +} + +func (m Usernotice) Badges() string { + for _, t := range m.Tags { + if t.Key == "badges" { + return t.Value + } + } + return "" +} + +func (m Usernotice) Color() string { + for _, t := range m.Tags { + if t.Key == "color" { + return t.Value + } + } + return "" +} + +func (m Usernotice) DisplayName() string { + for _, t := range m.Tags { + if t.Key == "display-name" { + return t.Value + } + } + return "" +} + +func (m Usernotice) Emotes() string { + for _, t := range m.Tags { + if t.Key == "emotes" { + return t.Value + } + } + return "" +} + +func (m Usernotice) IdOfMsg() string { + for _, t := range m.Tags { + if t.Key == "id" { + return t.Value + } + } + return "" +} + +func (m Usernotice) User() string { + for _, t := range m.Tags { + if t.Key == "login" { + return t.Value + } + } + return "" +} + +func (m Usernotice) Mod() string { + for _, t := range m.Tags { + if t.Key == "mod" { + return t.Value + } + } + return "" +} + +func (m Usernotice) MsgId() string { + for _, t := range m.Tags { + if t.Key == "msg-id" { + return t.Value + } + } + return "" +} + +func (m Usernotice) RoomId() string { + for _, t := range m.Tags { + if t.Key == "room-id" { + return t.Value + } + } + return "" +} + +func (m Usernotice) Subscriber() string { + for _, t := range m.Tags { + if t.Key == "subscriber" { + return t.Value + } + } + return "" +} + +func (m Usernotice) SystemMsg() string { + for _, t := range m.Tags { + if t.Key == "system-msg" { + return t.Value + } + } + return "" +} + +func (m Usernotice) Timestamp() string { + for _, t := range m.Tags { + if t.Key == "tmi-sent-ts" { + return t.Value + } + } + return "" +} + +func (m Usernotice) Turbo() string { + for _, t := range m.Tags { + if t.Key == "turbo" { + return t.Value + } + } + return "" +} + +func (m Usernotice) UserId() string { + for _, t := range m.Tags { + if t.Key == "user-id" { + return t.Value + } + } + return "" +} + +func (m Usernotice) UserType() string { + for _, t := range m.Tags { + if t.Key == "user-type" { + return t.Value + } + } + return "" +} diff --git a/twitch/core/usernotice/usernotice.go b/twitch/core/usernotice/usernotice.go deleted file mode 100644 index e6cc1b8..0000000 --- a/twitch/core/usernotice/usernotice.go +++ /dev/null @@ -1,20 +0,0 @@ -package usernotice - -import ( - "twitchchat/twitch/core/commands" - "twitchchat/twitch/core/messages" -) - -//go:generate tagprototype -out usernoticetags.go -package usernotice -type UserNoticeTag -prototype @badge-info=;badges=;color=;display-name=;emotes=;id=;login=;mod=;msg-id=;room-id=;subscriber=;system-msg=;tmi-sent-ts=;turbo=;user-id=;user-type= - -type UserNotice struct { - messages.Message -} - -func IsUserNotice(m messages.Message) bool { - return m.Command == commands.UserNotice -} - -func (u UserNotice) UserMessage() string { - return u.Params.Trailing -} diff --git a/twitch/core/usernotice/usernoticetags.go b/twitch/core/usernotice/usernoticetags.go deleted file mode 100755 index 94b5380..0000000 --- a/twitch/core/usernotice/usernoticetags.go +++ /dev/null @@ -1,24 +0,0 @@ -//Generated by twitch-chat/x/generate/tagprototype - -package usernotice - -type UserNoticeTag string - -const ( - BadgeInfo UserNoticeTag = "badge-info" - Badges UserNoticeTag = "badges" - Color UserNoticeTag = "color" - DisplayName UserNoticeTag = "display-name" - Emotes UserNoticeTag = "emotes" - Id UserNoticeTag = "id" - Login UserNoticeTag = "login" - Mod UserNoticeTag = "mod" - MsgId UserNoticeTag = "msg-id" - RoomId UserNoticeTag = "room-id" - Subscriber UserNoticeTag = "subscriber" - SystemMsg UserNoticeTag = "system-msg" - TmiSentTs UserNoticeTag = "tmi-sent-ts" - Turbo UserNoticeTag = "turbo" - UserId UserNoticeTag = "user-id" - UserType UserNoticeTag = "user-type" -) diff --git a/twitch/core/userstate/message.go b/twitch/core/userstate/message.go new file mode 100644 index 0000000..975ecab --- /dev/null +++ b/twitch/core/userstate/message.go @@ -0,0 +1,103 @@ +// generated by message + +package userstate + +import "twitchchat/twitch/core/messages" + +type Userstate struct { + messages.Message +} + +func IsUserstate(m messages.Message) bool { return string(m.Command) == "USERSTATE" } + +func (m Userstate) Channel() string { return m.Params.Params[0][1:] } + +func (m Userstate) BadgeInfo() string { + for _, t := range m.Tags { + if t.Key == "badge-info" { + return t.Value + } + } + return "" +} + +func (m Userstate) Badges() string { + for _, t := range m.Tags { + if t.Key == "badges" { + return t.Value + } + } + return "" +} + +func (m Userstate) Color() string { + for _, t := range m.Tags { + if t.Key == "color" { + return t.Value + } + } + return "" +} + +func (m Userstate) DisplayName() string { + for _, t := range m.Tags { + if t.Key == "display-name" { + return t.Value + } + } + return "" +} + +func (m Userstate) EmoteSets() string { + for _, t := range m.Tags { + if t.Key == "emote-sets" { + return t.Value + } + } + return "" +} + +func (m Userstate) Id() string { + for _, t := range m.Tags { + if t.Key == "id" { + return t.Value + } + } + return "" +} + +func (m Userstate) Mod() string { + for _, t := range m.Tags { + if t.Key == "mod" { + return t.Value + } + } + return "" +} + +func (m Userstate) Subscriber() string { + for _, t := range m.Tags { + if t.Key == "subscriber" { + return t.Value + } + } + return "" +} + +func (m Userstate) Turbo() string { + for _, t := range m.Tags { + if t.Key == "turbo" { + return t.Value + } + } + return "" +} + +func (m Userstate) UserType() string { + for _, t := range m.Tags { + if t.Key == "user-type" { + return t.Value + } + } + return "" +} diff --git a/twitch/core/userstate/userstate.go b/twitch/core/userstate/userstate.go deleted file mode 100644 index 32160c8..0000000 --- a/twitch/core/userstate/userstate.go +++ /dev/null @@ -1,21 +0,0 @@ -package userstate - -import ( - "twitchchat/irc" - "twitchchat/twitch/core/commands" - "twitchchat/twitch/core/messages" -) - -//go:generate tagprototype -out userstatetags.go -package userstate -type UserStateTag -prototype @badge-info=;badges=staff/1;color=#0D4200;display-name=ronni;emote-sets=0,33,50,237,793,2126,3517,4578,5569,9400,10337,12239;mod=1;subscriber=1;turbo=1;user-type=staff :tmi.twitch.tv USERSTATE #dallas - -type UserState struct { - messages.Message -} - -func IsUserState(m messages.Message) bool { - return m.Command == commands.UserState -} - -func (u UserState) GetTag(tag UserStateTag) *irc.Tag { - return u.Message.GetTag(string(tag)) -} diff --git a/twitch/core/userstate/userstatetags.go b/twitch/core/userstate/userstatetags.go deleted file mode 100755 index 2dec248..0000000 --- a/twitch/core/userstate/userstatetags.go +++ /dev/null @@ -1,17 +0,0 @@ -//Generated by twitch-chat/x/generate/tagprototype - -package userstate - -type UserStateTag string - -const ( - BadgeInfo UserStateTag = "badge-info" - Badges UserStateTag = "badges" - Color UserStateTag = "color" - DisplayName UserStateTag = "display-name" - EmoteSets UserStateTag = "emote-sets" - Mod UserStateTag = "mod" - Subscriber UserStateTag = "subscriber" - Turbo UserStateTag = "turbo" - UserType UserStateTag = "user-type" -) diff --git a/twitch/core/whisper/message.go b/twitch/core/whisper/message.go new file mode 100644 index 0000000..9ed16a5 --- /dev/null +++ b/twitch/core/whisper/message.go @@ -0,0 +1,101 @@ +// generated by message + +package whisper + +import ( + "strings" + "twitchchat/twitch/core/messages" +) + +type Whisper struct { + messages.Message +} + +func IsWhisper(m messages.Message) bool { return string(m.Command) == "WHISPER" } + +func (m Whisper) ToUser() string { return m.Prefix.User } + +func (m Whisper) FromUser() string { return m.Params.Params[0][0:] } + +func (m Whisper) UserMessage() string { return strings.Split(m.Params.Trailing, " ")[0][0:] } + +func (m Whisper) Badges() string { + for _, t := range m.Tags { + if t.Key == "badges" { + return t.Value + } + } + return "" +} + +func (m Whisper) Color() string { + for _, t := range m.Tags { + if t.Key == "color" { + return t.Value + } + } + return "" +} + +func (m Whisper) DisplayName() string { + for _, t := range m.Tags { + if t.Key == "display-name" { + return t.Value + } + } + return "" +} + +func (m Whisper) Emotes() string { + for _, t := range m.Tags { + if t.Key == "emotes" { + return t.Value + } + } + return "" +} + +func (m Whisper) MsgId() string { + for _, t := range m.Tags { + if t.Key == "message-id" { + return t.Value + } + } + return "" +} + +func (m Whisper) ThreadId() string { + for _, t := range m.Tags { + if t.Key == "thread-id" { + return t.Value + } + } + return "" +} + +func (m Whisper) Turbo() string { + for _, t := range m.Tags { + if t.Key == "turbo" { + return t.Value + } + } + return "" +} + +func (m Whisper) UserId() string { + for _, t := range m.Tags { + if t.Key == "user-id" { + return t.Value + } + } + return "" +} + +func (m Whisper) UserType() string { + for _, t := range m.Tags { + if t.Key == "user-type" { + return t.Value + } + } + return "" +} diff --git a/twitch/core/whisper/whisper.go b/twitch/core/whisper/whisper.go deleted file mode 100644 index 3fd0197..0000000 --- a/twitch/core/whisper/whisper.go +++ /dev/null @@ -1,31 +0,0 @@ -package whisper - -import ( - "twitchchat/twitch/core/commands" - "twitchchat/twitch/core/messages" -) - -//go:generate tagprototype -out whispertags.go -package whisper -type WhisperTag -prototype @badges=;color=;display-name=;emotes=;message-id=;thread-id=;turbo=;user-id=;user-type= - -type Whisper struct { - messages.Message -} - -func IsWhisper(m messages.Message) bool { - return m.Command == commands.Whisper -} - -func (w Whisper) ToUser() string { - return w.Prefix.User -} - -func (w Whisper) FromUser() string { - if len(w.Params.Params) != 1 { - return "" - } - return w.Params.Params[0] -} - -func (w Whisper) WhisperMessage() string { - return w.Params.Trailing -} diff --git a/twitch/core/whisper/whispertags.go b/twitch/core/whisper/whispertags.go deleted file mode 100755 index 159018e..0000000 --- a/twitch/core/whisper/whispertags.go +++ /dev/null @@ -1,17 +0,0 @@ -//Generated by twitch-chat/x/generate/tagprototype - -package whisper - -type WhisperTag string - -const ( - Badges WhisperTag = "badges" - Color WhisperTag = "color" - DisplayName WhisperTag = "display-name" - Emotes WhisperTag = "emotes" - MessageId WhisperTag = "message-id" - ThreadId WhisperTag = "thread-id" - Turbo WhisperTag = "turbo" - UserId WhisperTag = "user-id" - UserType WhisperTag = "user-type" -) diff --git a/x/corechatclient/main.go b/x/corechatclient/main.go index 8112318..56055e9 100644 --- a/x/corechatclient/main.go +++ b/x/corechatclient/main.go @@ -51,8 +51,8 @@ func main() { var format string rmax := NewRunningMax(50) for m := range msgs { - if privmsg.IsPrivateMessage(m) { - priv := privmsg.PrivMsg{m} + if privmsg.IsPrivmsg(m) { + priv := privmsg.Privmsg{m} u := priv.User() mx := rmax.Push(len(u)) format = fmt.Sprintf("%%%ds: %%s\n", mx) diff --git a/x/generate/message/clearchat/message.go b/x/generate/message/clearchat/message.go new file mode 100644 index 0000000..1856896 --- /dev/null +++ b/x/generate/message/clearchat/message.go @@ -0,0 +1,54 @@ +// generated by /tmp/go-build2868507172/b001/exe/message + +package clearchat + +import ( + "strings" + "twitchchat/irc" +) + +type Clearchat struct { + irc.Message +} + +func IsClearchat(m irc.Message) bool { return string(m.Command) == "CLEARCHAT" } + +func (m Clearchat) Channel() string { return m.Params.Params[0][1:] } + +func (m Clearchat) User() string { return strings.Split(m.Params.Trailing, " ")[0][0:] } + +func (m Clearchat) Duration() string { + for _, t := range m.Tags { + if t.Key == "ban-duration" { + return t.Value + } + } + return "" +} + +func (m Clearchat) RoomId() string { + for _, t := range m.Tags { + if t.Key == "room-id" { + return t.Value + } + } + return "" +} + +func (m Clearchat) UserId() string { + for _, t := range m.Tags { + if t.Key == "target-user-id" { + return t.Value + } + } + return "" +} + +func (m Clearchat) Timestamp() string { + for _, t := range m.Tags { + if t.Key == "tmi-sent-ts" { + return t.Value + } + } + return "" +} diff --git a/x/generate/message/convert.go b/x/generate/message/convert.go new file mode 100644 index 0000000..dcf17ad --- /dev/null +++ b/x/generate/message/convert.go @@ -0,0 +1,86 @@ +package main + +import ( + "strings" + "unicode" +) + +func convertCommandToName(command string) string { + b := strings.Builder{} + upper := true + for _, c := range command { + if upper { + b.WriteRune(unicode.ToUpper(c)) + upper = false + } else { + b.WriteRune(unicode.ToLower(c)) + } + } + return b.String() +} + +func convertCommandToDir(command string) string { + return strings.ToLower(command) +} + +func convertCommandToPackage(command string) string { + return strings.ToLower(command) +} + +func isParam(word string) bool { + left := strings.Index(word, "<") + right := strings.Index(word, ">") + return left != -1 && right != -1 +} + +func convertWordToName(word string) (prefix, name string) { + prefB := strings.Builder{} + nameB := strings.Builder{} + + if !isParam(word) { + return word, "" + } + + const ( + s_init int = iota + s_optional + s_param + ) + + part := true + state := s_init + for _, c := range word { + switch state { + + case s_init: + switch c { + case '[': + state = s_optional + case '<': + state = s_param + default: + prefB.WriteRune(c) + } + + case s_optional: + switch c { + case '<': + state = s_param + } + + case s_param: + if c == '>' || c == ']' { + continue + } else if part { + nameB.WriteRune(unicode.ToUpper(c)) + part = false + } else if c == '-' { + part = true + } else { + nameB.WriteRune(c) + } + + } + } + return prefB.String(), nameB.String() +} diff --git a/x/generate/message/convert_test.go b/x/generate/message/convert_test.go new file mode 100644 index 0000000..1e22026 --- /dev/null +++ b/x/generate/message/convert_test.go @@ -0,0 +1,21 @@ +package main + +import "testing" + +func TestConvertWordToName(t *testing.T) { + data := []struct { + in, prefix, name string + }{ + {"", "", "ToUser"}, + {"#", "#", "Channel"}, + {"#", "#", "HostingChannel"}, + {"[-|]", "", "Channel"}, + {"[]", "", "Message"}, + } + for _, d := range data { + prefix, name := convertWordToName(d.in) + if prefix != d.prefix || name != d.name { + t.Errorf("convertWordToName(%#v) = %#v, %#v but expected %#v, %#v.\n", d.in, prefix, name, d.prefix, d.name) + } + } +} diff --git a/x/generate/message/generateMessage.go b/x/generate/message/generateMessage.go new file mode 100644 index 0000000..46500f8 --- /dev/null +++ b/x/generate/message/generateMessage.go @@ -0,0 +1,87 @@ +package main + +import ( + "fmt" + "io" + "os" + "strings" + "twitchchat/irc" +) + +func generateMessage(msg irc.Message, w io.Writer) (n int, err error) { + write := func(s string) { + if err == nil { + var m int + m, err = io.WriteString(w, s) + n += m + } + } + + // header + write(fmt.Sprintf("// generated by %s\n", os.Args[0])) + write("\n") + write(fmt.Sprintf("package %s\n", convertCommandToPackage(string(msg.Command)))) + write("\n") + + // imports + if msg.Params.Trailing != "" { + write("import \"strings\"\n") + write("\n") + } + + // Potential optimization is to have all properties from the message as strings + // in the type and lazy load them + + var typeDef = convertCommandToName(string(msg.Command)) + // type definition + write(fmt.Sprintf("type %s struct {\n", typeDef)) + write(fmt.Sprintf("\tmessages.Message\n")) + write(fmt.Sprintf("}\n")) + write("\n") + + // command checking + + write(fmt.Sprintf("func Is%s(m messages.Message) bool { return string(m.Command) == %#v }\n", typeDef, msg.Command)) + write("\n") + + // from the user value + if isParam(msg.Prefix.User) { + // there shouldn't be a prefix here + _, n := convertWordToName(msg.Prefix.User) + write(fmt.Sprintf("func (m %s) %s() string { return m.Prefix.User }\n", typeDef, n)) + write("\n") + } + + // all params + for d, p := range msg.Params.Params { + p, n := convertWordToName(p) + write(fmt.Sprintf("func (m %s) %s() string { return m.Params.Params[%d][%d:] }\n", typeDef, n, d, len(p))) + write("\n") + } + + // words in trailing + if msg.Params.Trailing != "" { + for d, p := range strings.Split(msg.Params.Trailing, " ") { + p, n := convertWordToName(p) + write(fmt.Sprintf("func (m %s) %s() string { return strings.Split(m.Params.Trailing, \" \")[%d][%d:] }\n", typeDef, n, d, len(p))) + write("\n") + } + } + + // tags + for _, t := range msg.Tags { + // shouldn't have a prefx + if isParam(t.Value) { + _, n := convertWordToName(t.Value) + write(fmt.Sprintf("func (m %s) %s() string {\n", typeDef, n)) + write(fmt.Sprintf("\tfor _, t := range m.Tags {\n")) + write(fmt.Sprintf("\t\tif t.Key == %#v { return t.Value }\n", t.Key)) + write(fmt.Sprintf("\t}\n")) + write(fmt.Sprintf("\treturn \"\"\n")) + write(fmt.Sprintf("}\n")) + write("\n") + } + } + + return n, err +} diff --git a/x/generate/message/main.go b/x/generate/message/main.go new file mode 100644 index 0000000..6c76020 --- /dev/null +++ b/x/generate/message/main.go @@ -0,0 +1,55 @@ +package main + +import ( + "errors" + "flag" + "fmt" + "io/fs" + "os" + "path" + "twitchchat/irc" +) + +var prototype = flag.String("proto", "", "The prototype of the tags + message as a valid IRC message") + +func flags() { + flag.Usage = func() { + fmt.Fprintf(flag.CommandLine.Output(), "%s: generate code from a twitch message prototype\n", os.Args[0]) + fmt.Fprintln(flag.CommandLine.Output(), "Usage:") + flag.PrintDefaults() + } + + flag.Parse() + if *prototype == "" { + flag.Usage() + os.Exit(-1) + } +} + +func main() { + flags() + + msg, err := irc.ParseBytes([]byte(*prototype)) + if err != nil { + fmt.Printf("Invalid prototype message: %s\n", err) + os.Exit(-1) + } + + dir := convertCommandToDir(string(msg.Command)) + + if err := os.Mkdir(dir, fs.ModeDir|0755); err != nil { + if !errors.Is(err, fs.ErrExist) { + fmt.Printf("Could now create a directory: %s\n", err) + os.Exit(-1) + } + } + + file, err := os.Create(path.Join(dir, "message.go")) + if err != nil { + fmt.Printf("Could not write out: %s\n", err) + os.Exit(-1) + } + + generateMessage(msg, file) + fmt.Printf("Generated %s\n", msg) +} -- 2.47.1