mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-29 23:49:25 +01:00
commit
7ee7b1aab5
@ -1316,6 +1316,9 @@ func (client *Client) destroy(session *Session) {
|
|||||||
session.SetDestroyed()
|
session.SetDestroyed()
|
||||||
session.socket.Close()
|
session.socket.Close()
|
||||||
|
|
||||||
|
// clean up monitor state
|
||||||
|
client.server.monitorManager.RemoveAll(session)
|
||||||
|
|
||||||
// remove from connection limits
|
// remove from connection limits
|
||||||
var source string
|
var source string
|
||||||
if session.isTor {
|
if session.isTor {
|
||||||
@ -1381,8 +1384,6 @@ func (client *Client) destroy(session *Session) {
|
|||||||
if registered {
|
if registered {
|
||||||
client.server.monitorManager.AlertAbout(details.nick, details.nickCasefolded, false)
|
client.server.monitorManager.AlertAbout(details.nick, details.nickCasefolded, false)
|
||||||
}
|
}
|
||||||
// clean up monitor state
|
|
||||||
client.server.monitorManager.RemoveAll(client)
|
|
||||||
|
|
||||||
// clean up channels
|
// clean up channels
|
||||||
// (note that if this is a reattach, client has no channels and therefore no friends)
|
// (note that if this is a reattach, client has no channels and therefore no friends)
|
||||||
|
@ -1722,11 +1722,7 @@ func monitorRemoveHandler(server *Server, client *Client, msg ircmsg.IrcMessage,
|
|||||||
|
|
||||||
targets := strings.Split(msg.Params[1], ",")
|
targets := strings.Split(msg.Params[1], ",")
|
||||||
for _, target := range targets {
|
for _, target := range targets {
|
||||||
cfnick, err := CasefoldName(target)
|
server.monitorManager.Remove(rb.session, target)
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
server.monitorManager.Remove(client, cfnick)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
@ -1752,12 +1748,7 @@ func monitorAddHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add target
|
// add target
|
||||||
casefoldedTarget, err := CasefoldName(target)
|
err := server.monitorManager.Add(rb.session, target, limits.MonitorEntries)
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
err = server.monitorManager.Add(client, casefoldedTarget, limits.MonitorEntries)
|
|
||||||
if err == errMonitorLimitExceeded {
|
if err == errMonitorLimitExceeded {
|
||||||
rb.Add(nil, server.name, ERR_MONLISTFULL, client.Nick(), strconv.Itoa(limits.MonitorEntries), strings.Join(targets, ","))
|
rb.Add(nil, server.name, ERR_MONLISTFULL, client.Nick(), strconv.Itoa(limits.MonitorEntries), strings.Join(targets, ","))
|
||||||
break
|
break
|
||||||
@ -1786,14 +1777,14 @@ func monitorAddHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb
|
|||||||
|
|
||||||
// MONITOR C
|
// MONITOR C
|
||||||
func monitorClearHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
|
func monitorClearHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
|
||||||
server.monitorManager.RemoveAll(client)
|
server.monitorManager.RemoveAll(rb.session)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// MONITOR L
|
// MONITOR L
|
||||||
func monitorListHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
|
func monitorListHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
|
||||||
nick := client.Nick()
|
nick := client.Nick()
|
||||||
monitorList := server.monitorManager.List(client)
|
monitorList := server.monitorManager.List(rb.session)
|
||||||
|
|
||||||
var nickList []string
|
var nickList []string
|
||||||
for _, cfnick := range monitorList {
|
for _, cfnick := range monitorList {
|
||||||
@ -1820,7 +1811,7 @@ func monitorStatusHandler(server *Server, client *Client, msg ircmsg.IrcMessage,
|
|||||||
var online []string
|
var online []string
|
||||||
var offline []string
|
var offline []string
|
||||||
|
|
||||||
monitorList := server.monitorManager.List(client)
|
monitorList := server.monitorManager.List(rb.session)
|
||||||
|
|
||||||
for _, name := range monitorList {
|
for _, name := range monitorList {
|
||||||
currentNick := server.getCurrentNick(name)
|
currentNick := server.getCurrentNick(name)
|
||||||
|
@ -12,25 +12,24 @@ import (
|
|||||||
// MonitorManager keeps track of who's monitoring which nicks.
|
// MonitorManager keeps track of who's monitoring which nicks.
|
||||||
type MonitorManager struct {
|
type MonitorManager struct {
|
||||||
sync.RWMutex // tier 2
|
sync.RWMutex // tier 2
|
||||||
// client -> nicks it's watching
|
// client -> (casefolded nick it's watching -> uncasefolded nick)
|
||||||
watching map[*Client]map[string]bool
|
watching map[*Session]map[string]string
|
||||||
// nick -> clients watching it
|
// casefolded nick -> clients watching it
|
||||||
watchedby map[string]map[*Client]bool
|
watchedby map[string]map[*Session]empty
|
||||||
// (all nicks must be normalized externally by casefolding)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mm *MonitorManager) Initialize() {
|
func (mm *MonitorManager) Initialize() {
|
||||||
mm.watching = make(map[*Client]map[string]bool)
|
mm.watching = make(map[*Session]map[string]string)
|
||||||
mm.watchedby = make(map[string]map[*Client]bool)
|
mm.watchedby = make(map[string]map[*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 []*Client
|
var watchers []*Session
|
||||||
// safely copy the list of clients watching our nick
|
// safely copy the list of clients watching our nick
|
||||||
manager.RLock()
|
manager.RLock()
|
||||||
for client := range manager.watchedby[cfnick] {
|
for session := range manager.watchedby[cfnick] {
|
||||||
watchers = append(watchers, client)
|
watchers = append(watchers, session)
|
||||||
}
|
}
|
||||||
manager.RUnlock()
|
manager.RUnlock()
|
||||||
|
|
||||||
@ -39,58 +38,67 @@ func (manager *MonitorManager) AlertAbout(nick, cfnick string, online bool) {
|
|||||||
command = RPL_MONONLINE
|
command = RPL_MONONLINE
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, mClient := range watchers {
|
for _, session := range watchers {
|
||||||
mClient.Send(nil, mClient.server.name, command, mClient.Nick(), nick)
|
session.Send(nil, session.client.server.name, command, session.client.Nick(), nick)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add registers `client` to receive notifications about `nick`.
|
// Add registers `client` to receive notifications about `nick`.
|
||||||
func (manager *MonitorManager) Add(client *Client, nick string, limit int) error {
|
func (manager *MonitorManager) Add(session *Session, nick string, limit int) error {
|
||||||
|
cfnick, err := CasefoldName(nick)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
manager.Lock()
|
manager.Lock()
|
||||||
defer manager.Unlock()
|
defer manager.Unlock()
|
||||||
|
|
||||||
if manager.watching[client] == nil {
|
if manager.watching[session] == nil {
|
||||||
manager.watching[client] = make(map[string]bool)
|
manager.watching[session] = make(map[string]string)
|
||||||
}
|
}
|
||||||
if manager.watchedby[nick] == nil {
|
if manager.watchedby[cfnick] == nil {
|
||||||
manager.watchedby[nick] = make(map[*Client]bool)
|
manager.watchedby[cfnick] = make(map[*Session]empty)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(manager.watching[client]) >= limit {
|
if len(manager.watching[session]) >= limit {
|
||||||
return errMonitorLimitExceeded
|
return errMonitorLimitExceeded
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.watching[client][nick] = true
|
manager.watching[session][cfnick] = nick
|
||||||
manager.watchedby[nick][client] = true
|
manager.watchedby[cfnick][session] = empty{}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove unregisters `client` from receiving notifications about `nick`.
|
// Remove unregisters `client` from receiving notifications about `nick`.
|
||||||
func (manager *MonitorManager) Remove(client *Client, nick string) error {
|
func (manager *MonitorManager) Remove(session *Session, nick string) (err error) {
|
||||||
|
cfnick, err := CasefoldName(nick)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
manager.Lock()
|
manager.Lock()
|
||||||
defer manager.Unlock()
|
defer manager.Unlock()
|
||||||
// deleting from nil maps is fine
|
delete(manager.watching[session], cfnick)
|
||||||
delete(manager.watching[client], nick)
|
delete(manager.watchedby[cfnick], session)
|
||||||
delete(manager.watchedby[nick], client)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveAll unregisters `client` from receiving notifications about *all* nicks.
|
// RemoveAll unregisters `client` from receiving notifications about *all* nicks.
|
||||||
func (manager *MonitorManager) RemoveAll(client *Client) {
|
func (manager *MonitorManager) RemoveAll(session *Session) {
|
||||||
manager.Lock()
|
manager.Lock()
|
||||||
defer manager.Unlock()
|
defer manager.Unlock()
|
||||||
|
|
||||||
for nick := range manager.watching[client] {
|
for cfnick := range manager.watching[session] {
|
||||||
delete(manager.watchedby[nick], client)
|
delete(manager.watchedby[cfnick], session)
|
||||||
}
|
}
|
||||||
delete(manager.watching, client)
|
delete(manager.watching, session)
|
||||||
}
|
}
|
||||||
|
|
||||||
// List lists all nicks that `client` is registered to receive notifications about.
|
// List lists all nicks that `client` is registered to receive notifications about.
|
||||||
func (manager *MonitorManager) List(client *Client) (nicks []string) {
|
func (manager *MonitorManager) List(session *Session) (nicks []string) {
|
||||||
manager.RLock()
|
manager.RLock()
|
||||||
defer manager.RUnlock()
|
defer manager.RUnlock()
|
||||||
for nick := range manager.watching[client] {
|
for _, nick := range manager.watching[session] {
|
||||||
nicks = append(nicks, nick)
|
nicks = append(nicks, nick)
|
||||||
}
|
}
|
||||||
return nicks
|
return nicks
|
||||||
|
Loading…
Reference in New Issue
Block a user