3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-15 08:29:31 +01:00

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

View File

@ -177,6 +177,12 @@ CAPDEFS = [
url="https://github.com/ircv3/ircv3-specifications/pull/435", url="https://github.com/ircv3/ircv3-specifications/pull/435",
standard="draft IRCv3", 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(): def validate_defs():

View File

@ -7,7 +7,7 @@ package caps
const ( const (
// number of recognized capabilities: // number of recognized capabilities:
numCapabs = 27 numCapabs = 28
// 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/362 // https://github.com/ircv3/ircv3-specifications/pull/362
EventPlayback Capability = iota 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": // Languages is the proposed IRCv3 capability named "draft/languages":
// https://gist.github.com/DanielOaks/8126122f74b26012a3de37db80e4e0c6 // https://gist.github.com/DanielOaks/8126122f74b26012a3de37db80e4e0c6
Languages Capability = iota Languages Capability = iota
@ -135,6 +139,7 @@ var (
"draft/channel-rename", "draft/channel-rename",
"draft/chathistory", "draft/chathistory",
"draft/event-playback", "draft/event-playback",
"draft/extended-monitor",
"draft/languages", "draft/languages",
"draft/multiline", "draft/multiline",
"draft/relaymsg", "draft/relaymsg",

View File

@ -1025,6 +1025,13 @@ func (client *Client) Friends(capabs ...caps.Capability) (result map[*Session]em
return 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 // helper for Friends
func addFriendsToSet(set map[*Session]empty, client *Client, capabs ...caps.Capability) { func addFriendsToSet(set map[*Session]empty, client *Client, capabs ...caps.Capability) {
client.stateMutex.RLock() client.stateMutex.RLock()
@ -1049,7 +1056,7 @@ func (client *Client) SetOper(oper *Oper) {
func (client *Client) sendChghost(oldNickMask string, vhost string) { func (client *Client) sendChghost(oldNickMask string, vhost string) {
details := client.Details() details := client.Details()
isBot := client.HasMode(modes.Bot) 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) fClient.sendFromClientInternal(false, time.Time{}, "", oldNickMask, details.accountName, isBot, nil, "CHGHOST", details.username, vhost)
} }
} }

View File

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

View File

@ -6,6 +6,8 @@ package irc
import ( import (
"sync" "sync"
"github.com/ergochat/ergo/irc/caps"
"github.com/ergochat/irc-go/ircmsg" "github.com/ergochat/irc-go/ircmsg"
) )
@ -23,6 +25,17 @@ func (mm *MonitorManager) Initialize() {
mm.watchedby = make(map[string]map[*Session]empty) 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. // AlertAbout alerts everyone monitoring `client`'s nick that `client` is now {on,off}line.
func (manager *MonitorManager) AlertAbout(nick, cfnick string, online bool) { func (manager *MonitorManager) AlertAbout(nick, cfnick string, online bool) {
var watchers []*Session var watchers []*Session