mirror of
https://github.com/ergochat/ergo.git
synced 2025-01-05 09:32:32 +01:00
Send fake channel joins on RESUME
This commit is contained in:
parent
d13b2ee095
commit
f8b39cfe61
@ -145,29 +145,33 @@ func (channel *Channel) IsRegistered() bool {
|
|||||||
return channel.registeredFounder != ""
|
return channel.registeredFounder != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) regenerateMembersCache() {
|
func (channel *Channel) regenerateMembersCache(noLocksNeeded bool) {
|
||||||
// this is eventually consistent even without holding stateMutex.Lock()
|
// this is eventually consistent even without holding stateMutex.Lock()
|
||||||
// throughout the update; all updates to `members` while holding Lock()
|
// throughout the update; all updates to `members` while holding Lock()
|
||||||
// have a serial order, so the call to `regenerateMembersCache` that
|
// have a serial order, so the call to `regenerateMembersCache` that
|
||||||
// happens-after the last one will see *all* the updates. then,
|
// happens-after the last one will see *all* the updates. then,
|
||||||
// `membersCacheMutex` ensures that this final read is correctly paired
|
// `membersCacheMutex` ensures that this final read is correctly paired
|
||||||
// with the final write to `membersCache`.
|
// with the final write to `membersCache`.
|
||||||
channel.membersCacheMutex.Lock()
|
if !noLocksNeeded {
|
||||||
defer channel.membersCacheMutex.Unlock()
|
channel.membersCacheMutex.Lock()
|
||||||
|
defer channel.membersCacheMutex.Unlock()
|
||||||
|
channel.stateMutex.RLock()
|
||||||
|
}
|
||||||
|
|
||||||
channel.stateMutex.RLock()
|
|
||||||
result := make([]*Client, len(channel.members))
|
result := make([]*Client, len(channel.members))
|
||||||
i := 0
|
i := 0
|
||||||
for client := range channel.members {
|
for client := range channel.members {
|
||||||
result[i] = client
|
result[i] = client
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
channel.stateMutex.RUnlock()
|
if !noLocksNeeded {
|
||||||
channel.stateMutex.Lock()
|
channel.stateMutex.RUnlock()
|
||||||
|
channel.stateMutex.Lock()
|
||||||
|
}
|
||||||
channel.membersCache = result
|
channel.membersCache = result
|
||||||
channel.stateMutex.Unlock()
|
if !noLocksNeeded {
|
||||||
return
|
channel.stateMutex.Unlock()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Names sends the list of users joined to the channel to the given client.
|
// Names sends the list of users joined to the channel to the given client.
|
||||||
@ -413,7 +417,7 @@ func (channel *Channel) Join(client *Client, key string) {
|
|||||||
channel.members.Add(client)
|
channel.members.Add(client)
|
||||||
firstJoin := len(channel.members) == 1
|
firstJoin := len(channel.members) == 1
|
||||||
channel.stateMutex.Unlock()
|
channel.stateMutex.Unlock()
|
||||||
channel.regenerateMembersCache()
|
channel.regenerateMembersCache(false)
|
||||||
|
|
||||||
client.addChannel(channel)
|
client.addChannel(channel)
|
||||||
|
|
||||||
@ -722,7 +726,7 @@ func (channel *Channel) Quit(client *Client) {
|
|||||||
channel.stateMutex.Lock()
|
channel.stateMutex.Lock()
|
||||||
channel.members.Remove(client)
|
channel.members.Remove(client)
|
||||||
channel.stateMutex.Unlock()
|
channel.stateMutex.Unlock()
|
||||||
channel.regenerateMembersCache()
|
channel.regenerateMembersCache(false)
|
||||||
|
|
||||||
client.removeChannel(channel)
|
client.removeChannel(channel)
|
||||||
}
|
}
|
||||||
|
@ -380,10 +380,12 @@ func (client *Client) TryResume() {
|
|||||||
for channel := range oldClient.channels {
|
for channel := range oldClient.channels {
|
||||||
channel.stateMutex.Lock()
|
channel.stateMutex.Lock()
|
||||||
|
|
||||||
|
client.resumeDetails.SendFakeJoinsFor = append(client.resumeDetails.SendFakeJoinsFor, channel.name)
|
||||||
|
|
||||||
oldModeSet := channel.members[oldClient]
|
oldModeSet := channel.members[oldClient]
|
||||||
channel.members.Remove(oldClient)
|
channel.members.Remove(oldClient)
|
||||||
channel.members[client] = oldModeSet
|
channel.members[client] = oldModeSet
|
||||||
channel.regenerateMembersCache()
|
channel.regenerateMembersCache(true)
|
||||||
|
|
||||||
// send join for old clients
|
// send join for old clients
|
||||||
for member := range channel.members {
|
for member := range channel.members {
|
||||||
@ -397,7 +399,7 @@ func (client *Client) TryResume() {
|
|||||||
member.Send(nil, client.nickMaskString, "JOIN", channel.name)
|
member.Send(nil, client.nickMaskString, "JOIN", channel.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO(dan): send priv modes
|
//TODO(dan): send priv modes for fake new join
|
||||||
}
|
}
|
||||||
|
|
||||||
channel.stateMutex.Unlock()
|
channel.stateMutex.Unlock()
|
||||||
@ -652,26 +654,18 @@ func (client *Client) destroy(beingResumed bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("2")
|
|
||||||
|
|
||||||
// clean up server
|
// clean up server
|
||||||
if !beingResumed {
|
if !beingResumed {
|
||||||
client.server.clients.Remove(client)
|
client.server.clients.Remove(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("3")
|
|
||||||
|
|
||||||
// clean up self
|
// clean up self
|
||||||
if client.idletimer != nil {
|
if client.idletimer != nil {
|
||||||
client.idletimer.Stop()
|
client.idletimer.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("4")
|
|
||||||
|
|
||||||
client.socket.Close()
|
client.socket.Close()
|
||||||
|
|
||||||
fmt.Println("5")
|
|
||||||
|
|
||||||
// send quit messages to friends
|
// send quit messages to friends
|
||||||
if !beingResumed {
|
if !beingResumed {
|
||||||
for friend := range friends {
|
for friend := range friends {
|
||||||
|
@ -447,6 +447,24 @@ func (server *Server) tryRegister(c *Client) {
|
|||||||
if server.logger.IsLoggingRawIO() {
|
if server.logger.IsLoggingRawIO() {
|
||||||
c.Notice(rawIONotice)
|
c.Notice(rawIONotice)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if resumed, send fake channel joins
|
||||||
|
if c.resumeDetails != nil {
|
||||||
|
for _, name := range c.resumeDetails.SendFakeJoinsFor {
|
||||||
|
channel := server.channels.Get(name)
|
||||||
|
if channel == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.capabilities.Has(caps.ExtendedJoin) {
|
||||||
|
c.Send(nil, c.nickMaskString, "JOIN", channel.name, c.account.Name, c.realname)
|
||||||
|
} else {
|
||||||
|
c.Send(nil, c.nickMaskString, "JOIN", channel.name)
|
||||||
|
}
|
||||||
|
channel.SendTopic(c)
|
||||||
|
channel.Names(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// t returns the translated version of the given string, based on the languages configured by the client.
|
// t returns the translated version of the given string, based on the languages configured by the client.
|
||||||
@ -2077,8 +2095,9 @@ func lusersHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
|||||||
|
|
||||||
// ResumeDetails are the details that we use to resume connections.
|
// ResumeDetails are the details that we use to resume connections.
|
||||||
type ResumeDetails struct {
|
type ResumeDetails struct {
|
||||||
OldNick string
|
OldNick string
|
||||||
Timestamp *time.Time
|
Timestamp *time.Time
|
||||||
|
SendFakeJoinsFor []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// RESUME <oldnick> [timestamp]
|
// RESUME <oldnick> [timestamp]
|
||||||
|
Loading…
Reference in New Issue
Block a user