chore: document and add RFC1459, RFC2812 and IRCv3 commands

* also rename ChannelIndex to ActiveChannelIndex
This commit is contained in:
2022-01-21 03:23:02 +02:00
parent 2edc007022
commit 26deca05d9
5 changed files with 280 additions and 126 deletions
+2 -2
View File
@@ -68,7 +68,7 @@ type Client struct {
ActiveChannel string ActiveChannel string
// Active channel index // Active channel index
ChannelIndex int ActiveChannelIndex int
// Reference to the bubbletea program // Reference to the bubbletea program
Tea *tea.Program Tea *tea.Program
@@ -136,7 +136,7 @@ func (c *Client) Register(nick string, password string, channel string) {
Name: c.ActiveChannel, Name: c.ActiveChannel,
Users: make(map[string]User), Users: make(map[string]User),
}) })
c.ChannelIndex = 1 c.ActiveChannelIndex = 1
} }
} }
+248 -102
View File
@@ -116,114 +116,260 @@ var UserPrefixes = map[string]bool{
/* --- Numeric Replies --- */ /* --- Numeric Replies --- */
const ( const (
RPL_WELCOME = "001" RPL_WELCOME = "001" // RFC2812 - Implemented
RPL_YOURHOST = "002" RPL_YOURHOST = "002" // RFC2812 - Implemented
RPL_CREATED = "003" RPL_CREATED = "003" // RFC2812 - Implemented
RPL_MYINFO = "004" RPL_MYINFO = "004" // RFC2812 - Implemented
RPL_ISUPPORT = "005" RPL_ISUPPORT = "005" // ??????? - Not Implemented (TODO:)
RPL_BOUNCE = "010" RPL_BOUNCE = "010" // ??????? - Not Implemented (TODO:)
RPL_UMODEIS = "221" RPL_TRACELINK = "200" // RFC1459 - Not Implemented (TODO:)
RPL_LUSERCLIENT = "251" RPL_TRACECONNECTING = "201" // RFC1459 - Not Implemented (TODO:)
RPL_LUSEROP = "252" RPL_TRACEHANDSHAKE = "202" // RFC1459 - Not Implemented (TODO:)
RPL_LUSERUNKNOWN = "253" RPL_TRACEUNKNOWN = "203" // RFC1459 - Not Implemented (TODO:)
RPL_LUSERCHANNELS = "254" RPL_TRACEOPERATOR = "204" // RFC1459 - Not Implemented (TODO:)
RPL_LUSERME = "255" RPL_TRACEUSER = "205" // RFC1459 - Not Implemented (TODO:)
RPL_ADMINME = "256" RPL_TRACESERVER = "206" // RFC1459 - Not Implemented (TODO:)
RPL_ADMINLOC1 = "257" RPL_TRACESERVICE = "207" // RFC2812 - Not Implemented (TODO:)
RPL_ADMINLOC2 = "258" RPL_TRACENEWTYPE = "208" // RFC1459 - Not Implemented (TODO:)
RPL_ADMINEMAIL = "259" RPL_TRACECLASS = "209" // RFC2812 - Not Implemented (TODO:)
RPL_TRYAGAIN = "263" RPL_TRACERECONNECT = "210" // RFC2812 - Not Implemented - Deprecated - Has Conflicts (TODO:)
RPL_LOCALUSERS = "265" RPL_STATSLINKINFO = "211" // RFC1459 - Not Implemented (TODO:)
RPL_GLOBALUSERS = "266" RPL_STATSCOMMANDS = "212" // RFC1459 - Not Implemented (TODO:)
RPL_WHOISCERTFP = "276" RPL_STATSCLINE = "213" // RFC1459 - Not Implemented (TODO:)
RPL_NONE = "300" RPL_STATSNLINE = "214" // RFC1459 - Not Implemented - Has Conflicts (TODO:)
RPL_AWAY = "301" RPL_STATSILINE = "215" // RFC1459 - Not Implemented (TODO:)
RPL_USERHOST = "302" RPL_STATSKLINE = "216" // RFC1459 - Not Implemented (TODO:)
RPL_ISON = "303" RPL_STATSQLINE = "217" // RFC1459 - Not Implemented - Has Conflicts (TODO:)
RPL_UNAWAY = "305" RPL_STATSYLINE = "218" // RFC1459 - Not Implemented (TODO:)
RPL_NOWAWAY = "306" RPL_ENDOFSTATS = "219" // RFC1459 - Not Implemented (TODO:)
RPL_WHOISUSER = "311" RPL_UMODEIS = "221" // RFC1459 - Not Implemented (TODO:)
RPL_WHOISSERVER = "312" RPL_SERVICEINFO = "231" // RFC1459 - Not Implemented - Deprecated (TODO:)
RPL_WHOISOPERATOR = "313" RPL_ENDOFSERVICES = "232" // RFC1459 - Not Implemented - Deprecated (TODO:)
RPL_WHOWASUSER = "314" RPL_SERVICE = "233" // RFC1459 - Not Implemented - Deprecated (TODO:)
RPL_WHOISIDLE = "317" RPL_SERVLIST = "234" // RFC2812 - Not Implemented (TODO:) replaces 231 and 233
RPL_ENDOFWHOIS = "318" RPL_SERVLISTEND = "235" // RFC2812 - Not Implemented (TODO:) replaces 232
RPL_WHOISCHANNELS = "319" RPL_STATSVLINE = "240" // RFC2812 - Not Implemented - Has Conflicts (TODO:)
RPL_LISTSTART = "321" RPL_STATSLLINE = "241" // RFC1459 - Not Implemented (TODO:)
RPL_LIST = "322" RPL_STATSUPTIME = "242" // RFC1459 - Not Implemented (TODO:)
RPL_LISTEND = "323" RPL_STATSOLINE = "243" // RFC1459 - Not Implemented (TODO:)
RPL_CHANNELMODEIS = "324" RPL_STATSHLINE = "244" // RFC1459 - Not Implemented (TODO:)
RPL_CREATIONTIME = "329" RPL_STATSPING = "246" // RFC2812 - Not Implemented - Deprecated (TODO:)
RPL_NOTOPIC = "331" RPL_STATSBLINE = "247" // RFC2812 - Not Implemented - Has Conflicts (TODO:)
RPL_TOPIC = "332" RPL_STATSDLINE = "250" // RFC2812 - Not Implemented - Has Conflicts (TODO:)
RPL_TOPICWHOTIME = "333" RPL_LUSERCLIENT = "251" // RFC1459 - Implemented
RPL_INVITING = "341" RPL_LUSEROP = "252" // RFC1459 - Implemented
RPL_INVITELIST = "346" RPL_LUSERUNKNOWN = "253" // RFC1459 - Implemented
RPL_ENDOFINVITELIST = "347" RPL_LUSERCHANNELS = "254" // RFC1459 - Implemented
RPL_EXCEPTLIST = "348" RPL_LUSERME = "255" // RFC1459 - Implemented
RPL_ENDOFEXCEPTLIST = "349" RPL_ADMINME = "256" // RFC1459 - Not Implemented (TODO:)
RPL_VERSION = "351" RPL_ADMINLOC1 = "257" // RFC1459 - Not Implemented (TODO:)
RPL_NAMREPLY = "353" RPL_ADMINLOC2 = "258" // RFC1459 - Not Implemented (TODO:)
RPL_ENDOFNAMES = "366" RPL_ADMINEMAIL = "259" // RFC1459 - Not Implemented (TODO:)
RPL_BANLIST = "367" RPL_TRACELOG = "261" // RFC1459 - Not Implemented (TODO:)
RPL_ENDOFBANLIST = "368" RPL_TRACEEND = "262" // RFC2812 - Not Implemented - Has Conflicts (TODO:)
RPL_ENDOFWHOWAS = "369" RPL_TRYAGAIN = "263" // RFC2812 - Not Implemented (TODO:)
RPL_MOTDSTART = "375" RPL_LOCALUSERS = "265" // aircd, Hybrid, Bahamut - Implemented
RPL_MOTD = "372" RPL_GLOBALUSERS = "266" // aircd, Hybird, Bahamut - Implemented
RPL_ENDOFMOTD = "376" RPL_WHOISCERTFP = "276" // oftc-hybrid - Not Implemented - Has Conflicts (TODO:)
RPL_YOUREOPER = "381" RPL_NONE = "300" // RFC1459 - Not Implemented (TODO:)
RPL_REHASHING = "382" RPL_AWAY = "301" // RFC1459 - Not Implemented (TODO:)
RPL_USERHOST = "302" // RFC1459 - Not Implemented (TODO:)
RPL_ISON = "303" // RFC1459 - Not Implemented (TODO:)
RPL_TEXT = "304" // irc2 - Not Implemented (TODO:)
RPL_UNAWAY = "305" // RFC1459 - Not Implemented (TODO:)
RPL_NOWAWAY = "306" // RFC1459 - Not Implemented (TODO:)
RPL_WHOISUSER = "311" // RFC1459 - Not Implemented (TODO:)
RPL_WHOISSERVER = "312" // RFC1459 - Not Implemented (TODO:)
RPL_WHOISOPERATOR = "313" // RFC1459 - Not Implemented (TODO:)
RPL_WHOWASUSER = "314" // RFC1459 - Not Implemented (TODO:)
RPL_ENDOFWHO = "315" // RFC1459 - Not Implemented (TODO:)
RPL_WHOISIDLE = "317" // RFC1459 - Not Implemented (TODO:)
RPL_ENDOFWHOIS = "318" // RFC1459 - Not Implemented (TODO:)
RPL_WHOISCHANNELS = "319" // RFC1459 - Not Implemented (TODO:)
RPL_LISTSTART = "321" // RFC1459 - Not Implemented - Deprecated (TODO:)
RPL_LIST = "322" // RFC1459 - Not Implemented (TODO:)
RPL_LISTEND = "323" // RFC1459 - Not Implemented (TODO:)
RPL_CHANNELMODEIS = "324" // RFC1459 - Not Implemented (TODO:)
RPL_UNIQOPIS = "325" // RFC2812 - Not Implemented - Has Conflicts (TODO:)
RPL_CREATIONTIME = "329" // Bahamut,InspIRCd - Not Implemented (TODO:)
RPL_NOTOPIC = "331" // RFC1459 - Not Implemented (TODO:)
RPL_TOPIC = "332" // RFC1459 - Not Implemented (TODO:)
RPL_TOPICWHOTIME = "333" // ircu,InspIRCd - Not Implemented (TODO:)
RPL_INVITING = "341" // RFC1459 - Not Implemented (TODO:)
RPL_SUMMONING = "342" // RFC1459 - Not Implemented - Deprecated (TODO:)
RPL_INVITELIST = "346" // RFC2812 - Not Implemented (TODO:)
RPL_ENDOFINVITELIST = "347" // RFC2812 - Not Implemented (TODO:)
RPL_EXCEPTLIST = "348" // RFC2812 - Not Implemented (TODO:)
RPL_ENDOFEXCEPTLIST = "349" // RFC2812 - Not Implemented (TODO:)
RPL_WHOISGATEWAY = "350" // InspIRCd - Not Implemented (TODO:)
RPL_VERSION = "351" // RFC1459 - Not Implemented (TODO:)
RPL_WHOREPLY = "352" // RFC1459 - Not Implemented (TODO:)
RPL_NAMREPLY = "353" // RFC1459 - Implemented
RPL_KILLDONE = "361" // RFC1459 - Not Implemented - Deprecated (TODO:)
RPL_CLOSING = "362" // RFC1459 - Not Implemented - Deprecated (TODO:)
RPL_CLOSEEND = "363" // RFC1459 - Not Implemented - Deprecated (TODO:)
RPL_LINKS = "364" // RFC1459 - Not Implemented (TODO:)
RPL_ENDOFLINKS = "365" // RFC1459 - Not Implemented (TODO:)
RPL_ENDOFNAMES = "366" // RFC1459 - Not Implemented (TODO:)
RPL_BANLIST = "367" // RFC1459 - Not Implemented (TODO:)
RPL_ENDOFBANLIST = "368" // RFC1459 - Not Implemented (TODO:)
RPL_ENDOFWHOWAS = "369" // RFC1459 - Not Implemented (TODO:)
RPL_INFO = "371" // RFC1459 - Not Implemented (TODO:)
RPL_MOTD = "372" // RFC1459 - Implemented
RPL_INFOSTART = "373" // RFC1459 - Not Implemented - Deprecated (TODO:)
RPL_ENDOFINFO = "374" // RFC1459 - Not Implemented (TODO:)
RPL_MOTDSTART = "375" // RFC1459 - Implemented
RPL_ENDOFMOTD = "376" // RFC1459 - Not Implemented (TODO:)
RPL_YOUREOPER = "381" // RFC1459 - Not Implemented (TODO:)
RPL_REHASHING = "382" // RFC1459 - Not Implemented (TODO:)
RPL_YOURSERVICE = "383" // RFC2812 - Not Implemented (TODO:)
RPL_MYPORTIS = "384" // RFC1459 - Not Implemented - Deprecated (TODO:)
RPL_TIME = "391" // RFC1459 - Not Implemented - Has Conflicts (TODO:)
RPL_USERSSTART = "392" // RFC1459 - Not Implemented (TODO:)
RPL_USERS = "393" // RFC1459 - Not Implemented (TODO:)
RPL_ENDOFUSERS = "394" // RFC1459 - Not Implemented (TODO:)
RPL_NOUSERS = "395" // RFC1459 - Not Implemented (TODO:)
ERR_UNKNOWNERROR = "400" ERR_UNKNOWNERROR = "400" // ??????? - Not Implemented (TODO:)
ERR_NOSUCHNICK = "401" ERR_NOSUCHNICK = "401" // RFC1459 - Not Implemented (TODO:)
ERR_NOSUCHSERVER = "402" ERR_NOSUCHSERVER = "402" // RFC1459 - Not Implemented (TODO:)
ERR_NOSUCHCHANNEL = "403" ERR_NOSUCHCHANNEL = "403" // RFC1459 - Not Implemented (TODO:)
ERR_CANNOTSENDTOCHAN = "404" ERR_CANNOTSENDTOCHAN = "404" // RFC1459 - Not Implemented (TODO:)
ERR_TOOMANYCHANNELS = "405" ERR_TOOMANYCHANNELS = "405" // RFC1459 - Not Implemented (TODO:)
ERR_UNKNOWNCOMMAND = "421" ERR_WASNOSUCHNICK = "406" // RFC1459 - Not Implemented (TODO:)
ERR_NOMOTD = "422" ERR_NOSUCHSERVICE = "408" // RFC2812 - Not Implemented - Has Conflicts (TODO:)
ERR_ERRONUSNICKNAME = "432" ERR_NOORIGIN = "409" // RFC1459 - Not Implemented (TODO:)
ERR_NICKNAMEINUSE = "433" ERR_NORECIPIENT = "411" // RFC1459 - Not Implemented (TODO:)
ERR_USERNOTINCHANNEL = "441" ERR_NOTEXTTOSEND = "412" // RFC1459 - Not Implemented (TODO:)
ERR_NOTONCHANNEL = "442" ERR_NOTOPLEVEL = "413" // RFC1459 - Not Implemented (TODO:)
ERR_USERONCHANNEL = "443" ERR_WILDTOPLEVEL = "414" // RFC1459 - Not Implemented (TODO:)
ERR_NOTREGISTERED = "451" ERR_BADMASK = "415" // RFC2812 - Not Implemented (TODO:)
ERR_NEEDMOREPARAMS = "461" ERR_UNKNOWNCOMMAND = "421" // RFC1459 - Not Implemented (TODO:)
ERR_ALREADYREGISTERED = "462" ERR_NOMOTD = "422" // RFC1459 - Not Implemented (TODO:)
ERR_PASSWDMISMATCH = "464" ERR_NOADMININFO = "423" // RFC1459 - Not Implemented (TODO:)
ERR_YOUREBANNEDCREEP = "465" ERR_FILEERROR = "424" // RFC1459 - Not Implemented (TODO:)
ERR_CHANNELISFULL = "471" ERR_NONICKNAMEGIVEN = "431" // RFC1459 - Not Implemented (TODO:)
ERR_UNKNOWNMODE = "472" ERR_ERRONEUSNICKNAME = "432" // RFC1459 - Not Implemented (TODO:)
ERR_INVITEONLYCHAN = "473" ERR_NICKNAMEINUSE = "433" // RFC1459 - Not Implemented (TODO:)
ERR_BANNEDFROMCHAN = "474" ERR_NICKCOLLISION = "436" // RFC1459 - Not Implemented (TODO:)
ERR_BADCHANNELKEY = "475" ERR_UNAVAILRESOURCE = "437" // RFC2812 - Not Implemented - Has Conflicts (TODO:)
ERR_BADCHANMASK = "476" ERR_USERNOTINCHANNEL = "441" // RFC1459 - Not Implemented (TODO:)
ERR_NOPRIVILEGES = "481" ERR_NOTONCHANNEL = "442" // RFC1459 - Not Implemented (TODO:)
ERR_CHANOPRIVSNEEDED = "482" ERR_USERONCHANNEL = "443" // RFC1459 - Not Implemented (TODO:)
ERR_CANTKILLSERVER = "483" ERR_NOLOGIN = "444" // RFC1459 - Not Implemented (TODO:)
ERR_NOOPERHOST = "491" ERR_SUMMONDISABLED = "445" // RFC1459 - Not Implemented (TODO:)
ERR_UMODEUNKNOWNFLAG = "501" ERR_USERSDISABLED = "446" // RFC1459 - Not Implemented (TODO:)
ERR_USERSDONTMATCH = "502" ERR_NOTREGISTERED = "451" // RFC1459 - Not Implemented (TODO:)
RPL_STARTTLS = "670" ERR_NEEDMOREPARAMS = "461" // RFC1459 - Not Implemented (TODO:)
ERR_STARTTLS = "691" ERR_ALREADYREGISTERED = "462" // RFC1459 - Not Implemented (TODO:)
ERR_NOPRIVS = "723" ERR_NOPERMFORHOST = "463" // RFC1459 - Not Implemented (TODO:)
RPL_LOGGEDIN = "900" ERR_PASSWDMISMATCH = "464" // RFC1459 - Not Implemented (TODO:)
RPL_LOGGEDOUT = "901" ERR_YOUREBANNEDCREEP = "465" // RFC1459 - Not Implemented (TODO:)
ERR_NICKLOCKED = "902" ERR_YOUWILLBEBANNED = "466" // RFC1459 - Not Implemented - Deprecated (TODO:)
RPL_SASLSUCCESS = "903" ERR_KEYSET = "467" // RFC1459 - Not Implemented (TODO:)
ERR_SASLFAIL = "904" ERR_CHANNELISFULL = "471" // RFC1459 - Not Implemented (TODO:)
ERR_SASLTOOLONG = "905" ERR_UNKNOWNMODE = "472" // RFC1459 - Not Implemented (TODO:)
ERR_SASLABORTED = "906" ERR_INVITEONLYCHAN = "473" // RFC1459 - Not Implemented (TODO:)
ERR_SASLALREADY = "907" ERR_BANNEDFROMCHAN = "474" // RFC1459 - Not Implemented (TODO:)
RPL_SASLMECHS = "908" ERR_BADCHANNELKEY = "475" // RFC1459 - Not Implemented (TODO:)
ERR_BADCHANMASK = "476" // RFC2812 - Not Implemented (TODO:)
ERR_BANLISTFULL = "478" // RFC2812 - Not Implemented (TODO:)
ERR_NOPRIVILEGES = "481" // RFC1459 - Not Implemented (TODO:)
ERR_CHANOPRIVSNEEDED = "482" // RFC1459 - Not Implemented (TODO:)
ERR_CANTKILLSERVER = "483" // RFC1459 - Not Implemented (TODO:)
ERR_RESTRICTED = "484" // RFC2812 - Not Implemented - Has Conflicts (TODO:)
ERR_UNIQOPRIVSNEEDED = "485" // RFC2812 - Not Implemented (TODO:)
ERR_NOOPERHOST = "491" // RFC1459 - Not Implemented (TODO:)
ERR_NOSERVICEHOST = "492" // RFC1459 - Not Implemented - Deprecated - Has Conflicts (TODO:)
ERR_UMODEUNKNOWNFLAG = "501" // RFC1459 - Not Implemented - Has Conflicts (TODO:)
ERR_USERSDONTMATCH = "502" // RFC1459 - Not Implemented (TODO:)
RPL_STARTTLS = "670" // IRCv3 - Not Implemented (TODO:)
ERR_STARTTLS = "691" // IRCv3 - Not Implemented (TODO:)
ERR_NOPRIVS = "723" // RatBox - Not Implemented (TODO:)
RPL_WHOISKEYVALUE = "760" // IRCv3 - Not Implemented (TODO:)
RPL_KEYVALUE = "761" // IRCv3 - Not Implemented (TODO:)
RPL_METADATAEND = "762" // IRCv3 - Not Implemented (TODO:)
ERR_METADATALIMIT = "764" // IRCv3 - Not Implemented (TODO:)
ERR_TARGETINVALID = "765" // IRCv3 - Not Implemented (TODO:)
ERR_NOMATCHINGKEY = "766" // IRCv3 - Not Implemented (TODO:)
ERR_KEYINVALID = "767" // IRCv3 - Not Implemented (TODO:)
ERR_KEYNOTSET = "768" // IRCv3 - Not Implemented (TODO:)
ERR_KEYNOPERMISSION = "769" // IRCv3 - Not Implemented (TODO:)
RPL_LOGGEDIN = "900" // Charybdis/Atheme,IRCv3 - Not Implemented (TODO:)
RPL_LOGGEDOUT = "901" // Charybdis/Atheme,IRCv3 - Not Implemented (TODO:)
ERR_NICKLOCKED = "902" // Charybdis/Atheme,IRCv3 - Not Implemented (TODO:)
RPL_SASLSUCCESS = "903" // Charybdis/Atheme,IRCv3 - Not Implemented (TODO:)
ERR_SASLFAIL = "904" // Charybdis/Atheme,IRCv3 - Not Implemented (TODO:)
ERR_SASLTOOLONG = "905" // Charybdis/Atheme,IRCv3 - Not Implemented (TODO:)
ERR_SASLABORTED = "906" // Charybdis/Atheme,IRCv3 - Not Implemented (TODO:)
ERR_SASLALREADY = "907" // Charybdis/Atheme,IRCv3 - Not Implemented (TODO:)
RPL_SASLMECHS = "908" // Charybdis/Atheme,IRCv3 - Not Implemented (TODO:)
) )
/* --- RPL_ISUPPORT Parameters --- */ /* --- RPL_ISUPPORT Parameters --- */
// TODO:
var Features = map[string]bool{
"ACCEPT": true,
"AWAYLEN": true,
"BOT": true,
"CALLERID": true,
"CASEMAPPING": true,
"CHANLIMIT": true,
"CHANMODES": true,
"CHANNELLEN": true,
"CHANTYPES": true,
"CHARSET": true, // Deprecated but might still be used
"CLIENTVER": true, // Deprecated but might still be used
"CNOTICE": true,
"CPRIVMSG": true,
"DEAF": true,
"ELIST": true,
"ESILENCE": true,
"ETRACE": true,
"EXCEPTS": true,
"EXTBAN": true,
"FNC": true, // Deprecated but might still be used
"INVEX": true,
"KEYLEN": true,
"KICKLEN": true,
"KNOCK": true,
"LINELEN": true, // Proposed
"MAP": true, // Deprecated but might still be used
"MAXBANS": true, // Deprecated but might still be used
"MAXCHANNELS": true, // Deprecated but might still be used
"MAXLIST": true,
"MAXNICKLEN": true,
"MAXPARA": true, // Deprecated but might still be used
"MAXTARGETS": true,
"METADATA": true,
"MODES": true,
"MONITOR": true,
"NAMESX": true, // Deprecated but might still be used
"NETWORK": true,
"NICKLEN": true,
"OVERRIDE": true,
"PREFIX": true,
"SAFELIST": true,
"SECURELIST": true,
"SILENCE": true,
"SSL": true, // Deprecated but might still be used
"STARTTLS": true, // Deprecated but might still be used
"STATUSMSG": true,
"STD": true, // Deprecated but might still be used
"TARGMAX": true,
"TOPICLEN": true,
"UHNAMES": true, // Deprecated but might still be used
"USERIP": true,
"USERLEN": true, // Proposed
"VBANLIST": true, // Deprecared but might still be used
"VLIST": true,
"WALLCHOPS": true, // Deprecated but might still be used
"WALLVOICES": true, // Deprecated but might still be used
"WATCH": true,
"WHOX": true,
}
// Messages MUST end in CRLF and SHOULD be encoded and decoded using UTF-8 (with fallbacks such as Latin-1). // Messages MUST end in CRLF and SHOULD be encoded and decoded using UTF-8 (with fallbacks such as Latin-1).
// Names are casemapped, read the casemapping from the RPL_ISUPPORT the server sends when registration is completed. // Names are casemapped, read the casemapping from the RPL_ISUPPORT the server sends when registration is completed.
// Silently ignore empty messages and only parse messages when you encounter a CRLF.
// Client SHOULD NOT include a source when sending a message, but if included it MUST be the nickname of the client.
// When receiving a numeric reply, client MUST be able to handle any number of parameters on a numeric reply. // When receiving a numeric reply, client MUST be able to handle any number of parameters on a numeric reply.
+10 -2
View File
@@ -245,13 +245,21 @@ func (s *State) HandleCommand(msg parser.IRCMessage) {
case commands.RPL_NAMREPLY: case commands.RPL_NAMREPLY:
s.handleNAMREPLY(msg) s.handleNAMREPLY(msg)
case commands.RPL_ENDOFNAMES: case commands.RPL_ENDOFNAMES:
// TODO: what do i do here lol // TODO: toggle a flag on the channel to indicate
// it received all the names correctly.
// start a timeout and update said timeout on every RPL_NAMREPLY
// and log an error if timeout ends without receiving this command.
case commands.RPL_MOTDSTART: case commands.RPL_MOTDSTART:
s.handleMOTDStart(msg) s.handleMOTDStart(msg)
case commands.RPL_MOTD: case commands.RPL_MOTD:
s.handleMOTD(msg) s.handleMOTD(msg)
case commands.RPL_ENDOFMOTD: case commands.RPL_ENDOFMOTD:
// TODO: what do i do here lol // TODO: toggle a flag on the client/server to indicate
// it received all the MOTD correctly
// start a timeout and update said timeout on every RPL_MOTD
// and log an error if timeout ends without receiving this command.
default: default:
fullMsg := fmt.Sprintf("%s %s %s %s", msg.Tags, msg.Source, msg.Command, strings.Join(msg.Parameters, " ")) fullMsg := fmt.Sprintf("%s %s %s %s", msg.Tags, msg.Source, msg.Command, strings.Join(msg.Parameters, " "))
+18 -18
View File
@@ -82,7 +82,7 @@ func (s State) Update(msg tea.Msg) (State, tea.Cmd) {
switch msg := msg.(type) { switch msg := msg.(type) {
case ReceivedIRCMsgMsg: case ReceivedIRCMsgMsg:
wasAtBottom := s.Viewport.AtBottom() wasAtBottom := s.Viewport.AtBottom()
s.Viewport.SetContent(s.Client.Channels[s.Client.ChannelIndex].History) s.Viewport.SetContent(s.Client.Channels[s.Client.ActiveChannelIndex].History)
if wasAtBottom { if wasAtBottom {
s.Viewport.GotoBottom() s.Viewport.GotoBottom()
@@ -105,14 +105,14 @@ func (s State) Update(msg tea.Msg) (State, tea.Cmd) {
s.Client.ActiveChannel = channel s.Client.ActiveChannel = channel
for i, c := range s.Client.Channels { for i, c := range s.Client.Channels {
if c.Name == channel { if c.Name == channel {
s.Client.ChannelIndex = i s.Client.ActiveChannelIndex = i
break break
} else if i == len(s.Client.Channels)-1 { } else if i == len(s.Client.Channels)-1 {
s.Client.Channels = append(s.Client.Channels, client.Channel{ s.Client.Channels = append(s.Client.Channels, client.Channel{
Name: channel, Name: channel,
Users: make(map[string]client.User), Users: make(map[string]client.User),
}) })
s.Client.ChannelIndex = len(s.Client.Channels) - 1 s.Client.ActiveChannelIndex = len(s.Client.Channels) - 1
LastTabIndexInTabBar = len(s.Client.Channels) - 1 LastTabIndexInTabBar = len(s.Client.Channels) - 1
s.TabRenderingDirection = Left s.TabRenderingDirection = Left
} }
@@ -124,17 +124,17 @@ func (s State) Update(msg tea.Msg) (State, tea.Cmd) {
} else { } else {
if s.Client.ActiveChannel != s.Client.Host { if s.Client.ActiveChannel != s.Client.Host {
fullMsg := s.Client.Nickname + ": " + msg.Msg fullMsg := s.Client.Nickname + ": " + msg.Msg
s.Client.Channels[s.Client.ChannelIndex].History += fullMsg + client.CRLF s.Client.Channels[s.Client.ActiveChannelIndex].History += fullMsg + client.CRLF
// TODO: make sure to only append the message to the history if server sends back no errors // TODO: make sure to only append the message to the history if server sends back no errors
s.Client.SendCommand(commands.PRIVMSG, s.Client.ActiveChannel, msg.Msg) s.Client.SendCommand(commands.PRIVMSG, s.Client.ActiveChannel, msg.Msg)
s.Viewport.SetContent(s.Client.Channels[s.Client.ChannelIndex].History) s.Viewport.SetContent(s.Client.Channels[s.Client.ActiveChannelIndex].History)
s.Viewport.GotoBottom() s.Viewport.GotoBottom()
} }
} }
return s, nil return s, nil
case SwitchChannelsMsg: case SwitchChannelsMsg:
s.Viewport.SetContent(s.Client.Channels[s.Client.ChannelIndex].History) s.Viewport.SetContent(s.Client.Channels[s.Client.ActiveChannelIndex].History)
s.Viewport.GotoBottom() s.Viewport.GotoBottom()
*s.SidePanel, cmd = s.SidePanel.Update(msg) *s.SidePanel, cmd = s.SidePanel.Update(msg)
@@ -181,26 +181,26 @@ func (s State) Update(msg tea.Msg) (State, tea.Cmd) {
} }
if key == "right" { if key == "right" {
s.Client.ChannelIndex++ s.Client.ActiveChannelIndex++
} else { } else {
s.Client.ChannelIndex-- s.Client.ActiveChannelIndex--
} }
if s.Client.ChannelIndex >= len(s.Client.Channels) { if s.Client.ActiveChannelIndex >= len(s.Client.Channels) {
s.Client.ChannelIndex = 0 s.Client.ActiveChannelIndex = 0
} else if s.Client.ChannelIndex < 0 { } else if s.Client.ActiveChannelIndex < 0 {
s.Client.ChannelIndex = len(s.Client.Channels) - 1 s.Client.ActiveChannelIndex = len(s.Client.Channels) - 1
} }
if s.Client.ChannelIndex > LastTabIndexInTabBar { if s.Client.ActiveChannelIndex > LastTabIndexInTabBar {
s.TabRenderingDirection = Left s.TabRenderingDirection = Left
LastTabIndexInTabBar = s.Client.ChannelIndex LastTabIndexInTabBar = s.Client.ActiveChannelIndex
} else if s.Client.ChannelIndex < FirstTabIndexInTabBar { } else if s.Client.ActiveChannelIndex < FirstTabIndexInTabBar {
FirstTabIndexInTabBar = s.Client.ChannelIndex FirstTabIndexInTabBar = s.Client.ActiveChannelIndex
s.TabRenderingDirection = Right s.TabRenderingDirection = Right
} }
s.Client.ActiveChannel = s.Client.Channels[s.Client.ChannelIndex].Name s.Client.ActiveChannel = s.Client.Channels[s.Client.ActiveChannelIndex].Name
return s, SwitchChannels return s, SwitchChannels
case "g": case "g":
if s.FocusIndex == Viewport { if s.FocusIndex == Viewport {
@@ -268,7 +268,7 @@ func (s *State) SetSize(width, height int) {
// we need this to render an empty viewport // we need this to render an empty viewport
history := "" history := ""
if len(s.Client.Channels) != 0 { if len(s.Client.Channels) != 0 {
history = s.Client.Channels[s.Client.ChannelIndex].History history = s.Client.Channels[s.Client.ActiveChannelIndex].History
} }
// we need to re-set the content because words wrap differently on different sizes // we need to re-set the content because words wrap differently on different sizes
+2 -2
View File
@@ -36,7 +36,7 @@ type SidePanelState struct {
func (s *SidePanelState) getHeader() string { func (s *SidePanelState) getHeader() string {
usersCount := 0 usersCount := 0
if len(s.Client.Channels) != 0 { if len(s.Client.Channels) != 0 {
usersCount = len(s.Client.Channels[s.Client.ChannelIndex].Users) usersCount = len(s.Client.Channels[s.Client.ActiveChannelIndex].Users)
} }
separator := strings.Repeat("—", s.Viewport.Width) + "\n" separator := strings.Repeat("—", s.Viewport.Width) + "\n"
header := fmt.Sprintf("Users in this channel (%d)\n", usersCount) + separator header := fmt.Sprintf("Users in this channel (%d)\n", usersCount) + separator
@@ -48,7 +48,7 @@ func (s *SidePanelState) getLatestNicks() []string {
nicks := make([]string, 0) nicks := make([]string, 0)
if len(s.Client.Channels) != 0 { if len(s.Client.Channels) != 0 {
for nick, user := range s.Client.Channels[s.Client.ChannelIndex].Users { for nick, user := range s.Client.Channels[s.Client.ActiveChannelIndex].Users {
_nick := user.Prefix + nick _nick := user.Prefix + nick
nicks = append(nicks, _nick) nicks = append(nicks, _nick)
} }