Add support for extended-monitor

See: https://github.com/ircv3/ircv3-specifications/pull/466
This commit is contained in:
delthas 2021-07-24 20:52:03 +02:00
parent ad61f9f213
commit 7fde04ea94
5 changed files with 36 additions and 5 deletions

@ -177,6 +177,12 @@ CAPDEFS = [
url="https://github.com/ircv3/ircv3-specifications/pull/435",
standard="draft IRCv3",
),
CapDef(
identifier="ExtendedMonitor",
name="draft/extended-monitor",
url="https://github.com/ircv3/ircv3-specifications/pull/466",
standard="draft IRCv3",
),
]
def validate_defs():

@ -7,7 +7,7 @@ package caps
const (
// number of recognized capabilities:
numCapabs = 27
numCapabs = 28
// length of the uint64 array that represents the bitset:
bitsetLen = 1
)
@ -53,6 +53,10 @@ const (
// https://github.com/ircv3/ircv3-specifications/pull/362
EventPlayback Capability = iota
// ExtendedMonitor is the draft IRCv3 capability named "draft/extended-monitor":
// https://github.com/ircv3/ircv3-specifications/pull/466
ExtendedMonitor Capability = iota
// Languages is the proposed IRCv3 capability named "draft/languages":
// https://gist.github.com/DanielOaks/8126122f74b26012a3de37db80e4e0c6
Languages Capability = iota
@ -135,6 +139,7 @@ var (
"draft/channel-rename",
"draft/chathistory",
"draft/event-playback",
"draft/extended-monitor",
"draft/languages",
"draft/multiline",
"draft/relaymsg",

@ -1025,6 +1025,13 @@ func (client *Client) Friends(capabs ...caps.Capability) (result map[*Session]em
return
}
// Friends refers to clients that share a channel or extended-monitor this client.
func (client *Client) FriendsMonitors(capabs ...caps.Capability) (result map[*Session]empty) {
result = client.Friends(capabs...)
client.server.monitorManager.AddMonitors(result, client.nickCasefolded, capabs...)
return
}
// helper for Friends
func addFriendsToSet(set map[*Session]empty, client *Client, capabs ...caps.Capability) {
client.stateMutex.RLock()
@ -1049,7 +1056,7 @@ func (client *Client) SetOper(oper *Oper) {
func (client *Client) sendChghost(oldNickMask string, vhost string) {
details := client.Details()
isBot := client.HasMode(modes.Bot)
for fClient := range client.Friends(caps.ChgHost) {
for fClient := range client.FriendsMonitors(caps.ChgHost) {
fClient.sendFromClientInternal(false, time.Time{}, "", oldNickMask, details.accountName, isBot, nil, "CHGHOST", details.username, vhost)
}
}

@ -109,7 +109,7 @@ func sendSuccessfulAccountAuth(service *ircService, client *Client, rb *Response
if client.Registered() {
// dispatch account-notify
for friend := range client.Friends(caps.AccountNotify) {
for friend := range client.FriendsMonitors(caps.AccountNotify) {
if friend != rb.session {
friend.Send(nil, details.nickMask, "ACCOUNT", details.accountName)
}
@ -369,7 +369,7 @@ func dispatchAwayNotify(client *Client, isAway bool, awayMessage string) {
// dispatch away-notify
details := client.Details()
isBot := client.HasMode(modes.Bot)
for session := range client.Friends(caps.AwayNotify) {
for session := range client.FriendsMonitors(caps.AwayNotify) {
if isAway {
session.sendFromClientInternal(false, time.Time{}, "", details.nickMask, details.accountName, isBot, nil, "AWAY", awayMessage)
} else {
@ -2875,7 +2875,7 @@ func setnameHandler(server *Server, client *Client, msg ircmsg.Message, rb *Resp
// alert friends
now := time.Now().UTC()
friends := client.Friends(caps.SetName)
friends := client.FriendsMonitors(caps.SetName)
delete(friends, rb.session)
isBot := client.HasMode(modes.Bot)
for session := range friends {

@ -6,6 +6,8 @@ package irc
import (
"sync"
"github.com/ergochat/ergo/irc/caps"
"github.com/ergochat/irc-go/ircmsg"
)
@ -23,6 +25,17 @@ func (mm *MonitorManager) Initialize() {
mm.watchedby = make(map[string]map[*Session]empty)
}
// AddMonitors adds clients using extended-monitor monitoring `client`'s nick to the passed user set.
func (manager *MonitorManager) AddMonitors(users map[*Session]empty, cfnick string, capabs ...caps.Capability) {
manager.RLock()
defer manager.RUnlock()
for session := range manager.watchedby[cfnick] {
if session.capabilities.Has(caps.ExtendedMonitor) && session.capabilities.HasAll(capabs...) {
users[session] = empty{}
}
}
}
// AlertAbout alerts everyone monitoring `client`'s nick that `client` is now {on,off}line.
func (manager *MonitorManager) AlertAbout(nick, cfnick string, online bool) {
var watchers []*Session