mirror of
https://github.com/ergochat/ergo.git
synced 2024-12-22 18:52:41 +01:00
commit
dc322f8fd4
@ -624,12 +624,16 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
|||||||
// TODO #259 can be implemented as Flush(false) (i.e., nonblocking) while holding joinPartMutex
|
// TODO #259 can be implemented as Flush(false) (i.e., nonblocking) while holding joinPartMutex
|
||||||
rb.Flush(true)
|
rb.Flush(true)
|
||||||
|
|
||||||
|
channel.autoReplayHistory(client, rb, message.Msgid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (channel *Channel) autoReplayHistory(client *Client, rb *ResponseBuffer, skipMsgid string) {
|
||||||
// autoreplay any messages as necessary
|
// autoreplay any messages as necessary
|
||||||
config := channel.server.Config()
|
config := channel.server.Config()
|
||||||
var items []history.Item
|
var items []history.Item
|
||||||
if rb.session.zncPlaybackTimes != nil && (rb.session.zncPlaybackTimes.targets == nil || rb.session.zncPlaybackTimes.targets[chcfname]) {
|
if rb.session.zncPlaybackTimes != nil && (rb.session.zncPlaybackTimes.targets == nil || rb.session.zncPlaybackTimes.targets[channel.NameCasefolded()]) {
|
||||||
items, _ = channel.history.Between(rb.session.zncPlaybackTimes.after, rb.session.zncPlaybackTimes.before, false, config.History.ChathistoryMax)
|
items, _ = channel.history.Between(rb.session.zncPlaybackTimes.after, rb.session.zncPlaybackTimes.before, false, config.History.ChathistoryMax)
|
||||||
} else {
|
} else if !rb.session.HasHistoryCaps() {
|
||||||
var replayLimit int
|
var replayLimit int
|
||||||
customReplayLimit := client.AccountSettings().AutoreplayLines
|
customReplayLimit := client.AccountSettings().AutoreplayLines
|
||||||
if customReplayLimit != nil {
|
if customReplayLimit != nil {
|
||||||
@ -648,7 +652,7 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
|||||||
// remove the client's own JOIN line from the replay
|
// remove the client's own JOIN line from the replay
|
||||||
numItems := len(items)
|
numItems := len(items)
|
||||||
for i := len(items) - 1; 0 <= i; i-- {
|
for i := len(items) - 1; 0 <= i; i-- {
|
||||||
if items[i].Message.Msgid == message.Msgid {
|
if items[i].Message.Msgid == skipMsgid {
|
||||||
// zero'ed items will not be replayed because their `Type` field is not recognized
|
// zero'ed items will not be replayed because their `Type` field is not recognized
|
||||||
items[i] = history.Item{}
|
items[i] = history.Item{}
|
||||||
numItems--
|
numItems--
|
||||||
|
@ -162,6 +162,13 @@ func (session *Session) SetDestroyed() {
|
|||||||
atomic.StoreUint32(&session.destroyed, 1)
|
atomic.StoreUint32(&session.destroyed, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns whether the client supports a smart history replay cap,
|
||||||
|
// and therefore autoreplay-on-join and similar should be suppressed
|
||||||
|
func (session *Session) HasHistoryCaps() bool {
|
||||||
|
// TODO the chathistory cap will go here as well
|
||||||
|
return session.capabilities.Has(caps.ZNCPlayback)
|
||||||
|
}
|
||||||
|
|
||||||
// WhoWas is the subset of client details needed to answer a WHOWAS query
|
// WhoWas is the subset of client details needed to answer a WHOWAS query
|
||||||
type WhoWas struct {
|
type WhoWas struct {
|
||||||
nick string
|
nick string
|
||||||
@ -473,6 +480,13 @@ func (client *Client) playReattachMessages(session *Session) {
|
|||||||
client.server.playRegistrationBurst(session)
|
client.server.playRegistrationBurst(session)
|
||||||
for _, channel := range session.client.Channels() {
|
for _, channel := range session.client.Channels() {
|
||||||
channel.playJoinForSession(session)
|
channel.playJoinForSession(session)
|
||||||
|
// clients should receive autoreplay-on-join lines, if applicable;
|
||||||
|
// if they negotiated znc.in/playback or chathistory, they will receive nothing,
|
||||||
|
// because those caps disable autoreplay-on-join and they haven't sent the relevant
|
||||||
|
// *playback PRIVMSG or CHATHISTORY command yet
|
||||||
|
rb := NewResponseBuffer(session)
|
||||||
|
channel.autoReplayHistory(client, rb, "")
|
||||||
|
rb.Send(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
22
irc/znc.go
22
irc/znc.go
@ -73,8 +73,21 @@ func zncPlaybackHandler(client *Client, command string, params []string, rb *Res
|
|||||||
|
|
||||||
var targets map[string]bool
|
var targets map[string]bool
|
||||||
|
|
||||||
// OK: the user's PMs get played back immediately on receiving this,
|
// three cases:
|
||||||
// then we save the timestamps in the session to handle replay on future channel joins
|
// 1. the user's PMs get played back immediately upon receiving this
|
||||||
|
// 2. if this is a new connection (from the server's POV), save the information
|
||||||
|
// and use it to process subsequent joins
|
||||||
|
// 3. if this is a reattach (from the server's POV), immediately play back
|
||||||
|
// history for channels that the client is already joined to. In this scenario,
|
||||||
|
// there are three total attempts to play the history:
|
||||||
|
// 3.1. During the initial reattach (no-op because the *playback privmsg
|
||||||
|
// hasn't been received yet, but they negotiated the znc.in/playback
|
||||||
|
// cap so we know we're going to receive it later)
|
||||||
|
// 3.2 Upon receiving the *playback privmsg, i.e., now: we should play
|
||||||
|
// the relevant history lines
|
||||||
|
// 3.3 When the client sends a subsequent redundant JOIN line for those
|
||||||
|
// channels; redundant JOIN is a complete no-op so we won't replay twice
|
||||||
|
|
||||||
config := client.server.Config()
|
config := client.server.Config()
|
||||||
if params[1] == "*" {
|
if params[1] == "*" {
|
||||||
items, _ := client.history.Between(after, before, false, config.History.ChathistoryMax)
|
items, _ := client.history.Between(after, before, false, config.History.ChathistoryMax)
|
||||||
@ -95,4 +108,9 @@ func zncPlaybackHandler(client *Client, command string, params []string, rb *Res
|
|||||||
before: before,
|
before: before,
|
||||||
targets: targets,
|
targets: targets,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, channel := range client.Channels() {
|
||||||
|
channel.autoReplayHistory(client, rb, "")
|
||||||
|
rb.Flush(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user