diff --git a/gencapdefs.py b/gencapdefs.py index a0dcd0f4..9c3fe2e3 100644 --- a/gencapdefs.py +++ b/gencapdefs.py @@ -123,6 +123,12 @@ CAPDEFS = [ url="https://ircv3.net/specs/extensions/server-time-3.2.html", standard="IRCv3", ), + CapDef( + identifier="SetName", + name="draft/setname", + url="https://github.com/ircv3/ircv3-specifications/pull/361", + standard="proposed IRCv3", + ), CapDef( identifier="STS", name="sts", diff --git a/irc/caps/defs.go b/irc/caps/defs.go index 74ff1de6..adfbbb7d 100644 --- a/irc/caps/defs.go +++ b/irc/caps/defs.go @@ -7,7 +7,7 @@ package caps const ( // number of recognized capabilities: - numCapabs = 20 + numCapabs = 21 // length of the uint64 array that represents the bitset: bitsetLen = 1 ) @@ -85,6 +85,10 @@ const ( // https://ircv3.net/specs/extensions/server-time-3.2.html ServerTime Capability = iota + // SetName is the proposed IRCv3 capability named "draft/setname": + // https://github.com/ircv3/ircv3-specifications/pull/361 + SetName Capability = iota + // STS is the IRCv3 capability named "sts": // https://ircv3.net/specs/extensions/sts.html STS Capability = iota @@ -115,6 +119,7 @@ var ( "draft/resume-0.3", "sasl", "server-time", + "draft/setname", "sts", "userhost-in-names", } diff --git a/irc/commands.go b/irc/commands.go index fce1b5df..92e1bfb2 100644 --- a/irc/commands.go +++ b/irc/commands.go @@ -252,6 +252,10 @@ func init() { handler: sceneHandler, minParams: 2, }, + "SETNAME": { + handler: setnameHandler, + minParams: 1, + }, "TAGMSG": { handler: tagmsgHandler, minParams: 1, diff --git a/irc/handlers.go b/irc/handlers.go index e6210d03..64534610 100644 --- a/irc/handlers.go +++ b/irc/handlers.go @@ -2310,6 +2310,22 @@ func sceneHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res return false } +// SETNAME +func setnameHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool { + realname := msg.Params[0] + + client.stateMutex.Lock() + client.realname = realname + client.stateMutex.Unlock() + + // alert friends + for friend := range client.Friends(caps.SetName) { + friend.SendFromClient("", client, nil, "SETNAME", realname) + } + + return false +} + // TAGMSG {,} func tagmsgHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool { clientOnlyTags := utils.GetClientOnlyTags(msg.Tags) diff --git a/irc/help.go b/irc/help.go index cef0f1d0..e2a94e0f 100644 --- a/irc/help.go +++ b/irc/help.go @@ -434,6 +434,11 @@ opers. For more specific information on mode characters, see the help for text: `SCENE The SCENE command is used to send a scene notification to the given target.`, + }, + "setname": { + text: `SETNAME + +The SETNAME command updates the realname to be the newly-given one.`, }, "tagmsg": { text: `@+client-only-tags TAGMSG {,} diff --git a/irc/server.go b/irc/server.go index c478afdb..fdf4f01e 100644 --- a/irc/server.go +++ b/irc/server.go @@ -47,7 +47,7 @@ var ( // SupportedCapabilities are the caps we advertise. // MaxLine, SASL and STS are set during server startup. - SupportedCapabilities = caps.NewSet(caps.AccountTag, caps.AccountNotify, caps.AwayNotify, caps.Batch, caps.CapNotify, caps.ChgHost, caps.EchoMessage, caps.ExtendedJoin, caps.InviteNotify, caps.LabeledResponse, caps.Languages, caps.MessageTags, caps.MultiPrefix, caps.Rename, caps.Resume, caps.ServerTime, caps.UserhostInNames) + SupportedCapabilities = caps.NewSet(caps.AccountTag, caps.AccountNotify, caps.AwayNotify, caps.Batch, caps.CapNotify, caps.ChgHost, caps.EchoMessage, caps.ExtendedJoin, caps.InviteNotify, caps.LabeledResponse, caps.Languages, caps.MessageTags, caps.MultiPrefix, caps.Rename, caps.Resume, caps.ServerTime, caps.SetName, caps.UserhostInNames) // CapValues are the actual values we advertise to v3.2 clients. // actual values are set during server startup.