From 5a348fe6f5dcb3d43697c97a0c3c9ad17fc2a3f4 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 11 Mar 2024 02:44:17 -0400 Subject: [PATCH 1/2] fix #2133 Don't record NICK and QUIT in history for invisible auditorium members --- irc/channel.go | 16 ++++++++++++++++ irc/client.go | 9 ++++++--- irc/nickname.go | 4 +++- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/irc/channel.go b/irc/channel.go index 586d80d1..fd3916d5 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -1622,6 +1622,22 @@ func (channel *Channel) auditoriumFriends(client *Client) (friends []*Client) { return } +// returns whether the client is visible to unprivileged users in the channel +// (i.e., respecting auditorium mode) +func (channel *Channel) clientIsVisible(client *Client) bool { + channel.stateMutex.RLock() + defer channel.stateMutex.RUnlock() + + clientData, found := channel.members[client] + if !found { + return false + } + if !channel.flags.HasMode(modes.Auditorium) { + return true + } + return clientData.modes.HighestChannelUserMode() != modes.Mode(0) +} + // data for RPL_LIST func (channel *Channel) listData() (memberCount int, name, topic string) { channel.stateMutex.RLock() diff --git a/irc/client.go b/irc/client.go index cc303e71..419955f2 100644 --- a/irc/client.go +++ b/irc/client.go @@ -1297,10 +1297,10 @@ func (client *Client) destroy(session *Session) { } var quitItem history.Item - var channels []*Channel + var quitHistoryChannels []*Channel // use a defer here to avoid writing to mysql while holding the destroy semaphore: defer func() { - for _, channel := range channels { + for _, channel := range quitHistoryChannels { channel.AddHistoryItem(quitItem, details.account) } }() @@ -1322,8 +1322,11 @@ func (client *Client) destroy(session *Session) { // clean up channels // (note that if this is a reattach, client has no channels and therefore no friends) friends := make(ClientSet) - channels = client.Channels() + channels := client.Channels() for _, channel := range channels { + if channel.clientIsVisible(client) { + quitHistoryChannels = append(quitHistoryChannels, channel) + } for _, member := range channel.auditoriumFriends(client) { friends.Add(member) } diff --git a/irc/nickname.go b/irc/nickname.go index b180c005..698a8869 100644 --- a/irc/nickname.go +++ b/irc/nickname.go @@ -120,7 +120,9 @@ func performNickChange(server *Server, client *Client, target *Client, session * } for _, channel := range target.Channels() { - channel.AddHistoryItem(histItem, details.account) + if channel.clientIsVisible(client) { + channel.AddHistoryItem(histItem, details.account) + } } newCfnick := target.NickCasefolded() From d1485d63456f24a7279d4217713b937a5b943d4b Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 11 Mar 2024 23:49:45 -0400 Subject: [PATCH 2/2] pointless optimization --- irc/channel.go | 14 +++++++++----- irc/client.go | 2 +- irc/nickname.go | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/irc/channel.go b/irc/channel.go index fd3916d5..c6807a5c 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -1623,8 +1623,15 @@ func (channel *Channel) auditoriumFriends(client *Client) (friends []*Client) { } // returns whether the client is visible to unprivileged users in the channel -// (i.e., respecting auditorium mode) -func (channel *Channel) clientIsVisible(client *Client) bool { +// (i.e., respecting auditorium mode). note that this assumes that the client +// is a member; if the client is not, it may return true anyway +func (channel *Channel) memberIsVisible(client *Client) bool { + // fast path, we assume they're a member so if this isn't an auditorium, + // they're visible: + if !channel.flags.HasMode(modes.Auditorium) { + return true + } + channel.stateMutex.RLock() defer channel.stateMutex.RUnlock() @@ -1632,9 +1639,6 @@ func (channel *Channel) clientIsVisible(client *Client) bool { if !found { return false } - if !channel.flags.HasMode(modes.Auditorium) { - return true - } return clientData.modes.HighestChannelUserMode() != modes.Mode(0) } diff --git a/irc/client.go b/irc/client.go index 419955f2..47aca273 100644 --- a/irc/client.go +++ b/irc/client.go @@ -1324,7 +1324,7 @@ func (client *Client) destroy(session *Session) { friends := make(ClientSet) channels := client.Channels() for _, channel := range channels { - if channel.clientIsVisible(client) { + if channel.memberIsVisible(client) { quitHistoryChannels = append(quitHistoryChannels, channel) } for _, member := range channel.auditoriumFriends(client) { diff --git a/irc/nickname.go b/irc/nickname.go index 698a8869..9373871d 100644 --- a/irc/nickname.go +++ b/irc/nickname.go @@ -120,7 +120,7 @@ func performNickChange(server *Server, client *Client, target *Client, session * } for _, channel := range target.Channels() { - if channel.clientIsVisible(client) { + if channel.memberIsVisible(client) { channel.AddHistoryItem(histItem, details.account) } }