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