summaryrefslogtreecommitdiffstats
path: root/bridge/irc/irc.go
diff options
context:
space:
mode:
Diffstat (limited to 'bridge/irc/irc.go')
-rw-r--r--bridge/irc/irc.go73
1 files changed, 57 insertions, 16 deletions
diff --git a/bridge/irc/irc.go b/bridge/irc/irc.go
index 2352fcd7..4ccdee95 100644
--- a/bridge/irc/irc.go
+++ b/bridge/irc/irc.go
@@ -205,27 +205,58 @@ func (b *Birc) doConnect() {
}
}
+// Sanitize nicks for RELAYMSG: replace IRC characters with special meanings with "-"
+func sanitizeNick(nick string) string {
+ sanitize := func(r rune) rune {
+ if strings.ContainsRune("!+%@&#$:'\"?*,. ", r) {
+ return '-'
+ }
+ return r
+ }
+ return strings.Map(sanitize, nick)
+}
+
func (b *Birc) doSend() {
rate := time.Millisecond * time.Duration(b.MessageDelay)
throttle := time.NewTicker(rate)
for msg := range b.Local {
<-throttle.C
username := msg.Username
- if b.GetBool("Colornicks") && len(username) > 1 {
- checksum := crc32.ChecksumIEEE([]byte(msg.Username))
- colorCode := checksum%14 + 2 // quick fix - prevent white or black color codes
- username = fmt.Sprintf("\x03%02d%s\x0F", colorCode, msg.Username)
- }
+ // Optional support for the proposed RELAYMSG extension, described at
+ // https://github.com/jlu5/ircv3-specifications/blob/master/extensions/relaymsg.md
+ // nolint:nestif
+ if (b.i.HasCapability("overdrivenetworks.com/relaymsg") || b.i.HasCapability("draft/relaymsg")) &&
+ b.GetBool("UseRelayMsg") {
+ username = sanitizeNick(username)
+ text := msg.Text
+
+ // Work around girc chomping leading commas on single word messages?
+ if strings.HasPrefix(text, ":") && !strings.ContainsRune(text, ' ') {
+ text = ":" + text
+ }
- switch msg.Event {
- case config.EventUserAction:
- b.i.Cmd.Action(msg.Channel, username+msg.Text)
- case config.EventNoticeIRC:
- b.Log.Debugf("Sending notice to channel %s", msg.Channel)
- b.i.Cmd.Notice(msg.Channel, username+msg.Text)
- default:
- b.Log.Debugf("Sending to channel %s", msg.Channel)
- b.i.Cmd.Message(msg.Channel, username+msg.Text)
+ if msg.Event == config.EventUserAction {
+ b.i.Cmd.SendRawf("RELAYMSG %s %s :\x01ACTION %s\x01", msg.Channel, username, text) //nolint:errcheck
+ } else {
+ b.Log.Debugf("Sending RELAYMSG to channel %s: nick=%s", msg.Channel, username)
+ b.i.Cmd.SendRawf("RELAYMSG %s %s :%s", msg.Channel, username, text) //nolint:errcheck
+ }
+ } else {
+ if b.GetBool("Colornicks") {
+ checksum := crc32.ChecksumIEEE([]byte(msg.Username))
+ colorCode := checksum%14 + 2 // quick fix - prevent white or black color codes
+ username = fmt.Sprintf("\x03%02d%s\x0F", colorCode, msg.Username)
+ }
+ switch msg.Event {
+ case config.EventUserAction:
+ b.i.Cmd.Action(msg.Channel, username+msg.Text)
+ case config.EventNoticeIRC:
+ b.Log.Debugf("Sending notice to channel %s", msg.Channel)
+ b.i.Cmd.Notice(msg.Channel, username+msg.Text)
+ default:
+ b.Log.Debugf("Sending to channel %s", msg.Channel)
+ b.i.Cmd.Message(msg.Channel, username+msg.Text)
+ }
}
}
}
@@ -273,8 +304,9 @@ func (b *Birc) getClient() (*girc.Client, error) {
TLSConfig: &tls.Config{InsecureSkipVerify: b.GetBool("SkipTLSVerify"), ServerName: server}, //nolint:gosec
PingDelay: pingDelay,
// skip gIRC internal rate limiting, since we have our own throttling
- AllowFlood: true,
- Debug: debug,
+ AllowFlood: true,
+ Debug: debug,
+ SupportedCaps: map[string][]string{"overdrivenetworks.com/relaymsg": nil, "draft/relaymsg": nil},
})
return i, nil
}
@@ -311,6 +343,15 @@ func (b *Birc) skipPrivMsg(event girc.Event) bool {
if event.Source.Name == b.Nick {
return true
}
+ // don't forward messages we sent via RELAYMSG
+ if relayedNick, ok := event.Tags.Get("draft/relaymsg"); ok && relayedNick == b.Nick {
+ return true
+ }
+ // This is the old name of the cap sent in spoofed messages; I've kept this in
+ // for compatibility reasons
+ if relayedNick, ok := event.Tags.Get("relaymsg"); ok && relayedNick == b.Nick {
+ return true
+ }
return false
}