forked from External/ergo
improvements to message replay code
This commit is contained in:
parent
939729a7c0
commit
b11bf503e7
10 changed files with 338 additions and 165 deletions
|
|
@ -487,7 +487,7 @@ func (client *Client) tryResume() (success bool) {
|
|||
}
|
||||
}
|
||||
privmsgMatcher := func(item history.Item) bool {
|
||||
return item.Type == history.Privmsg || item.Type == history.Notice
|
||||
return item.Type == history.Privmsg || item.Type == history.Notice || item.Type == history.Tagmsg
|
||||
}
|
||||
privmsgHistory := oldClient.history.Match(privmsgMatcher, false, 0)
|
||||
lastDiscarded := oldClient.history.LastDiscarded()
|
||||
|
|
@ -495,8 +495,7 @@ func (client *Client) tryResume() (success bool) {
|
|||
oldestLostMessage = lastDiscarded
|
||||
}
|
||||
for _, item := range privmsgHistory {
|
||||
// TODO this is the nickmask, fix that
|
||||
sender := server.clients.Get(item.Nick)
|
||||
sender := server.clients.Get(stripMaskFromNick(item.Nick))
|
||||
if sender != nil {
|
||||
friends.Add(sender)
|
||||
}
|
||||
|
|
@ -561,8 +560,13 @@ func (client *Client) tryResumeChannels() {
|
|||
}
|
||||
|
||||
func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.Item, complete bool) {
|
||||
var batchID string
|
||||
nick := client.Nick()
|
||||
serverTime := rb.session.capabilities.Has(caps.ServerTime)
|
||||
if 0 < len(items) {
|
||||
batchID = rb.StartNestedHistoryBatch(nick)
|
||||
}
|
||||
|
||||
allowTags := rb.session.capabilities.Has(caps.MessageTags)
|
||||
for _, item := range items {
|
||||
var command string
|
||||
switch item.Type {
|
||||
|
|
@ -570,15 +574,23 @@ func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.I
|
|||
command = "PRIVMSG"
|
||||
case history.Notice:
|
||||
command = "NOTICE"
|
||||
case history.Tagmsg:
|
||||
if allowTags {
|
||||
command = "TAGMSG"
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
var tags map[string]string
|
||||
if serverTime {
|
||||
tags = map[string]string{"time": item.Time.Format(IRCv3TimestampFormat)}
|
||||
if allowTags {
|
||||
tags = item.Tags
|
||||
}
|
||||
rb.AddSplitMessageFromClient(item.Nick, item.AccountName, tags, command, nick, item.Message)
|
||||
}
|
||||
|
||||
rb.EndNestedBatch(batchID)
|
||||
if !complete {
|
||||
rb.Add(nil, "HistServ", "NOTICE", nick, client.t("Some additional message history may have been lost"))
|
||||
}
|
||||
|
|
@ -934,19 +946,21 @@ func (client *Client) destroy(beingResumed bool, session *Session) {
|
|||
return
|
||||
}
|
||||
|
||||
details := client.Details()
|
||||
|
||||
// see #235: deduplicating the list of PART recipients uses (comparatively speaking)
|
||||
// a lot of RAM, so limit concurrency to avoid thrashing
|
||||
client.server.semaphores.ClientDestroy.Acquire()
|
||||
defer client.server.semaphores.ClientDestroy.Release()
|
||||
|
||||
if beingResumed {
|
||||
client.server.logger.Debug("quit", fmt.Sprintf("%s is being resumed", client.nick))
|
||||
client.server.logger.Debug("quit", fmt.Sprintf("%s is being resumed", details.nick))
|
||||
} else {
|
||||
client.server.logger.Debug("quit", fmt.Sprintf("%s is no longer on the server", client.nick))
|
||||
client.server.logger.Debug("quit", fmt.Sprintf("%s is no longer on the server", details.nick))
|
||||
}
|
||||
|
||||
if !beingResumed {
|
||||
client.server.whoWas.Append(client.WhoWas())
|
||||
client.server.whoWas.Append(details.WhoWas)
|
||||
}
|
||||
|
||||
// remove from connection limits
|
||||
|
|
@ -963,6 +977,7 @@ func (client *Client) destroy(beingResumed bool, session *Session) {
|
|||
// clean up monitor state
|
||||
client.server.monitorManager.RemoveAll(client)
|
||||
|
||||
splitQuitMessage := utils.MakeSplitMessage(quitMessage, true)
|
||||
// clean up channels
|
||||
friends := make(ClientSet)
|
||||
for _, channel := range client.Channels() {
|
||||
|
|
@ -972,7 +987,7 @@ func (client *Client) destroy(beingResumed bool, session *Session) {
|
|||
Type: history.Quit,
|
||||
Nick: nickMaskString,
|
||||
AccountName: accountName,
|
||||
Message: utils.MakeSplitMessage(quitMessage, true),
|
||||
Message: splitQuitMessage,
|
||||
})
|
||||
}
|
||||
for _, member := range channel.Members() {
|
||||
|
|
@ -1007,14 +1022,14 @@ func (client *Client) destroy(beingResumed bool, session *Session) {
|
|||
if quitMessage == "" {
|
||||
quitMessage = "Exited"
|
||||
}
|
||||
friend.Send(nil, client.nickMaskString, "QUIT", quitMessage)
|
||||
friend.sendFromClientInternal(false, splitQuitMessage.Time, splitQuitMessage.Msgid, details.nickMask, details.accountName, nil, "QUIT", quitMessage)
|
||||
}
|
||||
}
|
||||
if !client.exitedSnomaskSent {
|
||||
if beingResumed {
|
||||
client.server.snomasks.Send(sno.LocalQuits, fmt.Sprintf(ircfmt.Unescape("%s$r is resuming their connection, old client has been destroyed"), client.nick))
|
||||
} else {
|
||||
client.server.snomasks.Send(sno.LocalQuits, fmt.Sprintf(ircfmt.Unescape("%s$r exited the network"), client.nick))
|
||||
client.server.snomasks.Send(sno.LocalQuits, fmt.Sprintf(ircfmt.Unescape("%s$r exited the network"), details.nick))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1031,15 +1046,7 @@ func (session *Session) sendSplitMsgFromClientInternal(blocking bool, serverTime
|
|||
}
|
||||
}
|
||||
|
||||
// SendFromClient sends an IRC line coming from a specific client.
|
||||
// Adds account-tag to the line as well.
|
||||
func (client *Client) SendFromClient(msgid string, from *Client, tags map[string]string, command string, params ...string) error {
|
||||
return client.sendFromClientInternal(false, time.Time{}, msgid, from.NickMaskString(), from.AccountName(), tags, command, params...)
|
||||
}
|
||||
|
||||
// this is SendFromClient, but directly exposing nickmask and accountName,
|
||||
// for things like history replay and CHGHOST where they no longer (necessarily)
|
||||
// correspond to the current state of a client
|
||||
// Sends a line with `nickmask` as the prefix, adding `time` and `account` tags if supported
|
||||
func (client *Client) sendFromClientInternal(blocking bool, serverTime time.Time, msgid string, nickmask, accountName string, tags map[string]string, command string, params ...string) (err error) {
|
||||
for _, session := range client.Sessions() {
|
||||
err_ := session.sendFromClientInternal(blocking, serverTime, msgid, nickmask, accountName, tags, command, params...)
|
||||
|
|
@ -1062,7 +1069,10 @@ func (session *Session) sendFromClientInternal(blocking bool, serverTime time.Ti
|
|||
}
|
||||
// attach server-time
|
||||
if session.capabilities.Has(caps.ServerTime) {
|
||||
msg.SetTag("time", time.Now().UTC().Format(IRCv3TimestampFormat))
|
||||
if serverTime.IsZero() {
|
||||
serverTime = time.Now().UTC()
|
||||
}
|
||||
msg.SetTag("time", serverTime.Format(IRCv3TimestampFormat))
|
||||
}
|
||||
|
||||
return session.SendRawMessage(msg, blocking)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue