state: Minor Messages() fix

This commit fixes Messages() not returning the full messages list if the
state has kept track of some few messages from before.
This commit is contained in:
diamondburned 2022-04-14 11:54:16 -07:00
parent 649dd36086
commit 4d96cdd2b1
No known key found for this signature in database
GPG Key ID: D78C4471CE776659
2 changed files with 32 additions and 36 deletions

View File

@ -14,11 +14,12 @@ import (
) )
const ( const (
// the limit of max messages per request, as imposed by Discord // MaxMessageFetchLimit is the limit of max messages per request, as imposed
maxMessageFetchLimit = 100 // by Discord.
// maxMessageDeleteLimit is the limit of max message that can be deleted MaxMessageFetchLimit = 100
// MaxMessageDeleteLimit is the limit of max message that can be deleted
// per bulk delete request, as imposed by Discord. // per bulk delete request, as imposed by Discord.
maxMessageDeleteLimit = 100 MaxMessageDeleteLimit = 100
) )
// Messages returns a slice filled with the most recent messages sent in the // Messages returns a slice filled with the most recent messages sent in the
@ -62,7 +63,7 @@ func (c *Client) MessagesBefore(
msgs := make([]discord.Message, 0, limit) msgs := make([]discord.Message, 0, limit)
fetch := uint(maxMessageFetchLimit) fetch := uint(MaxMessageFetchLimit)
// Check if we are truly fetching unlimited messages to avoid confusion // Check if we are truly fetching unlimited messages to avoid confusion
// later on, if the limit reaches 0. // later on, if the limit reaches 0.
@ -72,8 +73,8 @@ func (c *Client) MessagesBefore(
if limit > 0 { if limit > 0 {
// Only fetch as much as we need. Since limit gradually decreases, // Only fetch as much as we need. Since limit gradually decreases,
// we only need to fetch intmath.Min(fetch, limit). // we only need to fetch intmath.Min(fetch, limit).
fetch = uint(intmath.Min(maxMessageFetchLimit, int(limit))) fetch = uint(intmath.Min(MaxMessageFetchLimit, int(limit)))
limit -= maxMessageFetchLimit limit -= MaxMessageFetchLimit
} }
m, err := c.messagesRange(channelID, before, 0, 0, fetch) m, err := c.messagesRange(channelID, before, 0, 0, fetch)
@ -83,7 +84,7 @@ func (c *Client) MessagesBefore(
// Append the older messages into the list of newer messages. // Append the older messages into the list of newer messages.
msgs = append(msgs, m...) msgs = append(msgs, m...)
if len(m) < maxMessageFetchLimit { if len(m) < MaxMessageFetchLimit {
break break
} }
@ -119,7 +120,7 @@ func (c *Client) MessagesAfter(
var msgs []discord.Message var msgs []discord.Message
fetch := uint(maxMessageFetchLimit) fetch := uint(MaxMessageFetchLimit)
// Check if we are truly fetching unlimited messages to avoid confusion // Check if we are truly fetching unlimited messages to avoid confusion
// later on, if the limit reaches 0. // later on, if the limit reaches 0.
@ -129,8 +130,8 @@ func (c *Client) MessagesAfter(
if limit > 0 { if limit > 0 {
// Only fetch as much as we need. Since limit gradually decreases, // Only fetch as much as we need. Since limit gradually decreases,
// we only need to fetch intmath.Min(fetch, limit). // we only need to fetch intmath.Min(fetch, limit).
fetch = uint(intmath.Min(maxMessageFetchLimit, int(limit))) fetch = uint(intmath.Min(MaxMessageFetchLimit, int(limit)))
limit -= maxMessageFetchLimit limit -= MaxMessageFetchLimit
} }
m, err := c.messagesRange(channelID, 0, after, 0, fetch) m, err := c.messagesRange(channelID, 0, after, 0, fetch)
@ -140,7 +141,7 @@ func (c *Client) MessagesAfter(
// Prepend the older messages into the newly-fetched messages list. // Prepend the older messages into the newly-fetched messages list.
msgs = append(m, msgs...) msgs = append(m, msgs...)
if len(m) < maxMessageFetchLimit { if len(m) < MaxMessageFetchLimit {
break break
} }
@ -441,14 +442,14 @@ func (c *Client) DeleteMessages(
return nil return nil
case len(messageIDs) == 1: case len(messageIDs) == 1:
return c.DeleteMessage(channelID, messageIDs[0], reason) return c.DeleteMessage(channelID, messageIDs[0], reason)
case len(messageIDs) <= maxMessageDeleteLimit: // Fast path case len(messageIDs) <= MaxMessageDeleteLimit: // Fast path
return c.deleteMessages(channelID, messageIDs, reason) return c.deleteMessages(channelID, messageIDs, reason)
} }
// If the number of messages to be deleted exceeds the amount discord is willing // If the number of messages to be deleted exceeds the amount discord is willing
// to accept at one time then batches of messages will be deleted // to accept at one time then batches of messages will be deleted
for start := 0; start < len(messageIDs); start += maxMessageDeleteLimit { for start := 0; start < len(messageIDs); start += MaxMessageDeleteLimit {
end := intmath.Min(len(messageIDs), start+maxMessageDeleteLimit) end := intmath.Min(len(messageIDs), start+MaxMessageDeleteLimit)
err := c.deleteMessages(channelID, messageIDs[start:end], reason) err := c.deleteMessages(channelID, messageIDs[start:end], reason)
if err != nil { if err != nil {
return err return err

View File

@ -606,30 +606,30 @@ func (s *State) Messages(channelID discord.ChannelID, limit uint) ([]discord.Mes
if len(storeMessages) > 0 && s.tracksMessage(&storeMessages[0]) { if len(storeMessages) > 0 && s.tracksMessage(&storeMessages[0]) {
// Is the channel tiny? // Is the channel tiny?
s.fewMutex.Lock() s.fewMutex.Lock()
if _, ok := s.fewMessages[channelID]; ok { _, isTiny := s.fewMessages[channelID]
s.fewMutex.Unlock() s.fewMutex.Unlock()
if isTiny {
return storeMessages, nil return storeMessages, nil
} }
// No, fetch from the API. // No, fetch from the API.
s.fewMutex.Unlock()
} else { } else {
// Something wrong with the cached messages, make sure they aren't // Something's wrong with the cached messages, make sure they aren't
// returned. // returned.
storeMessages = nil storeMessages = nil
} }
// Store already has enough messages. // Store already has enough messages.
if len(storeMessages) >= int(limit) && limit > 0 {
return storeMessages[:limit], nil
}
// Decrease the limit, if we aren't fetching all messages.
if limit > 0 { if limit > 0 {
if len(storeMessages) >= int(limit) {
return storeMessages[:limit], nil
}
// Decrease the limit, if we aren't fetching all messages.
limit -= uint(len(storeMessages)) limit -= uint(len(storeMessages))
} }
var before discord.MessageID = 0 var before discord.MessageID
if len(storeMessages) > 0 { if len(storeMessages) > 0 {
before = storeMessages[len(storeMessages)-1].ID before = storeMessages[len(storeMessages)-1].ID
} }
@ -639,8 +639,10 @@ func (s *State) Messages(channelID discord.ChannelID, limit uint) ([]discord.Mes
return nil, err return nil, err
} }
if len(storeMessages)+len(apiMessages) < s.MaxMessages() { if len(apiMessages) < int(limit) {
// Tiny channel, store this. // Tiny channel, store this.
// TODO: this tiny channel check isn't very perfect, but it should
// accomplish what we want.
s.fewMutex.Lock() s.fewMutex.Lock()
s.fewMessages[channelID] = struct{}{} s.fewMessages[channelID] = struct{}{}
s.fewMutex.Unlock() s.fewMutex.Unlock()
@ -668,16 +670,9 @@ func (s *State) Messages(channelID discord.ChannelID, limit uint) ([]discord.Mes
apiMessages[i].GuildID = guildID apiMessages[i].GuildID = guildID
} }
if s.tracksMessage(&apiMessages[0]) && len(storeMessages) < s.MaxMessages() { if s.tracksMessage(&apiMessages[0]) {
// Only add as many messages as the store can hold. for i := range apiMessages {
i := s.MaxMessages() - len(storeMessages) s.Cabinet.MessageSet(&apiMessages[i], false)
if i > len(apiMessages) {
i = len(apiMessages)
}
msgs := apiMessages[:i]
for i := range msgs {
s.Cabinet.MessageSet(&msgs[i], false)
} }
} }