diff --git a/irc/help.go b/irc/help.go index 67f74584..9208fbf2 100644 --- a/irc/help.go +++ b/irc/help.go @@ -64,6 +64,7 @@ Oragono supports the following user modes: +a | User is marked as being away. This mode is set with the /AWAY command. +i | User is marked as invisible (their channels are hidden from whois replies). +o | User is an IRC operator. + +R | User only accepts messages from other registered users. +s | Server Notice Masks (see help with /HELPOP snomasks). +Z | User is connected via TLS.` snomaskHelpText = `== Server Notice Masks == diff --git a/irc/modes.go b/irc/modes.go index 80cbdaeb..f7a23772 100644 --- a/irc/modes.go +++ b/irc/modes.go @@ -101,6 +101,7 @@ const ( LocalOperator Mode = 'O' Operator Mode = 'o' Restricted Mode = 'r' + RegisteredOnly Mode = 'R' ServerNotice Mode = 's' TLS Mode = 'Z' UserRoleplaying Mode = 'E' @@ -110,7 +111,7 @@ const ( var ( // SupportedUserModes are the user modes that we actually support (modifying). SupportedUserModes = Modes{ - Away, Invisible, Operator, ServerNotice, UserRoleplaying, + Away, Invisible, Operator, RegisteredOnly, ServerNotice, UserRoleplaying, } // supportedUserModesString acts as a cache for when we introduce users supportedUserModesString = SupportedUserModes.String() @@ -127,9 +128,9 @@ const ( Moderated Mode = 'm' // flag NoOutside Mode = 'n' // flag OpOnlyTopic Mode = 't' // flag - RegisteredOnly Mode = 'r' // flag - Secret Mode = 's' // flag - UserLimit Mode = 'l' // flag arg + // RegisteredOnly mode is reused here from umode definition + Secret Mode = 's' // flag + UserLimit Mode = 'l' // flag arg ) var ( @@ -281,7 +282,7 @@ func (client *Client) applyUserModeChanges(force bool, changes ModeChanges) Mode for _, change := range changes { switch change.mode { - case Invisible, WallOps, UserRoleplaying, Operator, LocalOperator: + case Invisible, WallOps, UserRoleplaying, Operator, LocalOperator, RegisteredOnly: switch change.op { case Add: if !force && (change.mode == Operator || change.mode == LocalOperator) { diff --git a/irc/server.go b/irc/server.go index 5be7a09e..484021c6 100644 --- a/irc/server.go +++ b/irc/server.go @@ -1133,7 +1133,11 @@ func privmsgHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool clientOnlyTags = nil } msgid := server.generateMessageID() - user.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "PRIVMSG", user.nick, splitMsg) + // restrict messages appropriately when +R is set + // intentionally make the sending user think the message went through fine + if !user.flags[RegisteredOnly] || client.registered { + user.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "PRIVMSG", user.nick, splitMsg) + } if client.capabilities[EchoMessage] { client.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "PRIVMSG", user.nick, splitMsg) } @@ -1829,7 +1833,11 @@ func noticeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { clientOnlyTags = nil } msgid := server.generateMessageID() - user.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "NOTICE", user.nick, splitMsg) + // restrict messages appropriately when +R is set + // intentionally make the sending user think the message went through fine + if !user.flags[RegisteredOnly] || client.registered { + user.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "NOTICE", user.nick, splitMsg) + } if client.capabilities[EchoMessage] { client.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "NOTICE", user.nick, splitMsg) }