mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-25 21:39:25 +01:00
Initial RELAYMSG implementation
This commit is contained in:
parent
2801018150
commit
4ee49f8450
@ -583,6 +583,7 @@ oper-classes:
|
|||||||
- "vhosts"
|
- "vhosts"
|
||||||
- "chanreg"
|
- "chanreg"
|
||||||
- "history"
|
- "history"
|
||||||
|
- "relaymsg-anywhere"
|
||||||
|
|
||||||
# ircd operators
|
# ircd operators
|
||||||
opers:
|
opers:
|
||||||
|
@ -93,6 +93,12 @@ CAPDEFS = [
|
|||||||
url="https://ircv3.net/specs/extensions/multi-prefix-3.1.html",
|
url="https://ircv3.net/specs/extensions/multi-prefix-3.1.html",
|
||||||
standard="IRCv3",
|
standard="IRCv3",
|
||||||
),
|
),
|
||||||
|
CapDef(
|
||||||
|
identifier="Relaymsg",
|
||||||
|
name="draft/relaymsg",
|
||||||
|
url="https://github.com/ircv3/ircv3-specifications/pull/417",
|
||||||
|
standard="proposed IRCv3",
|
||||||
|
),
|
||||||
CapDef(
|
CapDef(
|
||||||
identifier="Rename",
|
identifier="Rename",
|
||||||
name="draft/rename",
|
name="draft/rename",
|
||||||
|
@ -7,7 +7,7 @@ package caps
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// number of recognized capabilities:
|
// number of recognized capabilities:
|
||||||
numCapabs = 26
|
numCapabs = 27
|
||||||
// length of the uint64 array that represents the bitset:
|
// length of the uint64 array that represents the bitset:
|
||||||
bitsetLen = 1
|
bitsetLen = 1
|
||||||
)
|
)
|
||||||
@ -53,6 +53,10 @@ const (
|
|||||||
// https://github.com/ircv3/ircv3-specifications/pull/398
|
// https://github.com/ircv3/ircv3-specifications/pull/398
|
||||||
Multiline Capability = iota
|
Multiline Capability = iota
|
||||||
|
|
||||||
|
// Relaymsg is the proposed IRCv3 capability named "draft/relaymsg":
|
||||||
|
// https://github.com/ircv3/ircv3-specifications/pull/417
|
||||||
|
Relaymsg Capability = iota
|
||||||
|
|
||||||
// Rename is the proposed IRCv3 capability named "draft/rename":
|
// Rename is the proposed IRCv3 capability named "draft/rename":
|
||||||
// https://github.com/SaberUK/ircv3-specifications/blob/rename/extensions/rename.md
|
// https://github.com/SaberUK/ircv3-specifications/blob/rename/extensions/rename.md
|
||||||
Rename Capability = iota
|
Rename Capability = iota
|
||||||
@ -131,6 +135,7 @@ var (
|
|||||||
"draft/event-playback",
|
"draft/event-playback",
|
||||||
"draft/languages",
|
"draft/languages",
|
||||||
"draft/multiline",
|
"draft/multiline",
|
||||||
|
"draft/relaymsg",
|
||||||
"draft/rename",
|
"draft/rename",
|
||||||
"draft/resume-0.5",
|
"draft/resume-0.5",
|
||||||
"echo-message",
|
"echo-message",
|
||||||
|
@ -173,6 +173,10 @@ func (clients *ClientManager) SetNick(client *Client, session *Session, newNick
|
|||||||
return "", errNicknameInvalid, false
|
return "", errNicknameInvalid, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strings.Contains(newCfNick, "/") {
|
||||||
|
return "", errNicknameInvalid, false
|
||||||
|
}
|
||||||
|
|
||||||
if restrictedCasefoldedNicks[newCfNick] || restrictedSkeletons[newSkeleton] {
|
if restrictedCasefoldedNicks[newCfNick] || restrictedSkeletons[newSkeleton] {
|
||||||
return "", errNicknameInvalid, false
|
return "", errNicknameInvalid, false
|
||||||
}
|
}
|
||||||
|
@ -250,6 +250,10 @@ func init() {
|
|||||||
minParams: 2,
|
minParams: 2,
|
||||||
allowedInBatch: true,
|
allowedInBatch: true,
|
||||||
},
|
},
|
||||||
|
"RELAYMSG": {
|
||||||
|
handler: relaymsgHandler,
|
||||||
|
minParams: 3,
|
||||||
|
},
|
||||||
"RENAME": {
|
"RENAME": {
|
||||||
handler: renameHandler,
|
handler: renameHandler,
|
||||||
minParams: 2,
|
minParams: 2,
|
||||||
|
@ -1068,6 +1068,9 @@ func LoadConfig(filename string) (config *Config, err error) {
|
|||||||
}
|
}
|
||||||
config.Server.capValues[caps.Languages] = config.languageManager.CapValue()
|
config.Server.capValues[caps.Languages] = config.languageManager.CapValue()
|
||||||
|
|
||||||
|
// intentionally not configurable
|
||||||
|
config.Server.capValues[caps.Relaymsg] = "/"
|
||||||
|
|
||||||
config.Debug.recoverFromErrors = utils.BoolDefaultTrue(config.Debug.RecoverFromErrors)
|
config.Debug.recoverFromErrors = utils.BoolDefaultTrue(config.Debug.RecoverFromErrors)
|
||||||
|
|
||||||
// process operator definitions, store them to config.operators
|
// process operator definitions, store them to config.operators
|
||||||
|
@ -1887,6 +1887,15 @@ func messageHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *R
|
|||||||
if i == maxTargets {
|
if i == maxTargets {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strings.Contains(targetString, "/") {
|
||||||
|
if histType == history.Privmsg {
|
||||||
|
rb.Add(nil, server.name, ERR_NOSUCHNICK, client.Nick(), targetString, client.t("Relayed users cannot be sent private messages"))
|
||||||
|
}
|
||||||
|
// TAGMSG/NOTICEs are intentionally silently dropped
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// each target gets distinct msgids
|
// each target gets distinct msgids
|
||||||
splitMsg := utils.MakeMessage(message)
|
splitMsg := utils.MakeMessage(message)
|
||||||
dispatchMessageToTarget(client, clientOnlyTags, histType, msg.Command, targetString, splitMsg, rb)
|
dispatchMessageToTarget(client, clientOnlyTags, histType, msg.Command, targetString, splitMsg, rb)
|
||||||
@ -2270,6 +2279,53 @@ func rehashHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RELAYMSG <channel> <spoofed nick> :<message>
|
||||||
|
func relaymsgHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) (result bool) {
|
||||||
|
channel := server.channels.Get(msg.Params[0])
|
||||||
|
if channel == nil {
|
||||||
|
rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, client.Nick(), utils.SafeErrorParam(msg.Params[0]), client.t("No such channel"))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(channel.ClientIsAtLeast(client, modes.ChannelOperator) || client.HasRoleCapabs("relaymsg-anywhere")) {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "RELAYMSG", "NOT_PRIVED", client.t("Only channel operators or ircops with the 'relaymsg-anywhere' role can relay messages"))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
rawMessage := msg.Params[2]
|
||||||
|
if strings.TrimSpace(rawMessage) == "" {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "RELAYMSG", "BLANK_MSG", client.t("The message must not be blank"))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
message := utils.MakeMessage(rawMessage)
|
||||||
|
|
||||||
|
nick := msg.Params[1]
|
||||||
|
_, err := CasefoldName(nick)
|
||||||
|
if err != nil {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "RELAYMSG", "INVALID_NICK", client.t("Invalid nickname"))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !strings.Contains(nick, "/") {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "RELAYMSG", "INVALID_NICK", fmt.Sprintf(client.t("Relayed nicknames MUST contain the relaymsg separator %s"), "/"))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: add to history here??
|
||||||
|
|
||||||
|
// send msg
|
||||||
|
for _, member := range channel.Members() {
|
||||||
|
for _, session := range member.Sessions() {
|
||||||
|
tagsToUse := make(map[string]string)
|
||||||
|
if session.capabilities.Has(caps.Relaymsg) {
|
||||||
|
tagsToUse["relaymsg"] = client.Nick()
|
||||||
|
}
|
||||||
|
|
||||||
|
session.sendSplitMsgFromClientInternal(false, nick, "", tagsToUse, "PRIVMSG", channel.Name(), message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// RENAME <oldchan> <newchan> [<reason>]
|
// RENAME <oldchan> <newchan> [<reason>]
|
||||||
func renameHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) (result bool) {
|
func renameHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) (result bool) {
|
||||||
result = false
|
result = false
|
||||||
|
10
irc/help.go
10
irc/help.go
@ -393,6 +393,16 @@ Replies to a PING. Used to check link connectivity.`,
|
|||||||
text: `PRIVMSG <target>{,<target>} <text to be sent>
|
text: `PRIVMSG <target>{,<target>} <text to be sent>
|
||||||
|
|
||||||
Sends the text to the given targets as a PRIVMSG.`,
|
Sends the text to the given targets as a PRIVMSG.`,
|
||||||
|
},
|
||||||
|
"relaymsg": {
|
||||||
|
text: `RELAYMSG <channel> <spoofed nick> :<message>
|
||||||
|
|
||||||
|
This command lets channel operators relay messages to their
|
||||||
|
channel from other messaging systems using relay bots. The
|
||||||
|
spoofed nickname MUST contain a forwardslash.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
RELAYMSG #ircv3 Mallory/D :Welp, we linked Discord...`,
|
||||||
},
|
},
|
||||||
"rename": {
|
"rename": {
|
||||||
text: `RENAME <channel> <newname> [<reason>]
|
text: `RENAME <channel> <newname> [<reason>]
|
||||||
|
@ -609,6 +609,7 @@ oper-classes:
|
|||||||
- "vhosts"
|
- "vhosts"
|
||||||
- "chanreg"
|
- "chanreg"
|
||||||
- "history"
|
- "history"
|
||||||
|
- "relaymsg-anywhere"
|
||||||
|
|
||||||
# ircd operators
|
# ircd operators
|
||||||
opers:
|
opers:
|
||||||
|
Loading…
Reference in New Issue
Block a user