diff --git a/libgm/client.go b/libgm/client.go index bfe9153..03808b6 100644 --- a/libgm/client.go +++ b/libgm/client.go @@ -41,6 +41,11 @@ const RefreshTachyonBuffer = 1 * time.Hour type Proxy func(*http.Request) (*url.URL, error) type EventHandler func(evt any) +type updateDedupItem struct { + id string + hash [32]byte +} + type Client struct { Logger zerolog.Logger evHandler EventHandler @@ -51,7 +56,7 @@ type Client struct { skipCount int disconnecting bool - recentUpdates [8][32]byte + recentUpdates [8]updateDedupItem recentUpdatesPtr int conversationsFetchedOnce bool diff --git a/libgm/event_handler.go b/libgm/event_handler.go index 0eab351..a1558dc 100644 --- a/libgm/event_handler.go +++ b/libgm/event_handler.go @@ -77,19 +77,23 @@ func (c *Client) decryptInternalMessage(data *gmproto.IncomingRPCMessage) (*Inco return msg, nil } -func (c *Client) deduplicateHash(hash [32]byte) bool { +func (c *Client) deduplicateHash(id string, hash [32]byte) bool { const recentUpdatesLen = len(c.recentUpdates) for i := c.recentUpdatesPtr + recentUpdatesLen - 1; i >= c.recentUpdatesPtr; i-- { - if c.recentUpdates[i%recentUpdatesLen] == hash { - return true + if c.recentUpdates[i%recentUpdatesLen].id == id { + if c.recentUpdates[i%recentUpdatesLen].hash == hash { + return true + } else { + break + } } } - c.recentUpdates[c.recentUpdatesPtr] = hash + c.recentUpdates[c.recentUpdatesPtr] = updateDedupItem{id: id, hash: hash} c.recentUpdatesPtr = (c.recentUpdatesPtr + 1) % recentUpdatesLen return false } -func (c *Client) logContent(res *IncomingRPCMessage) { +func (c *Client) logContent(res *IncomingRPCMessage, thingID string, contentHash []byte) { if c.Logger.Trace().Enabled() && (res.DecryptedData != nil || res.DecryptedMessage != nil) { evt := c.Logger.Trace() if res.DecryptedMessage != nil { @@ -97,6 +101,10 @@ func (c *Client) logContent(res *IncomingRPCMessage) { } if res.DecryptedData != nil { evt.Str("data", base64.StdEncoding.EncodeToString(res.DecryptedData)) + if contentHash != nil { + evt.Str("thing_id", thingID) + evt.Hex("data_hash", contentHash) + } } else { evt.Str("data", "") } @@ -104,14 +112,14 @@ func (c *Client) logContent(res *IncomingRPCMessage) { } } -func (c *Client) deduplicateUpdate(msg *IncomingRPCMessage) bool { +func (c *Client) deduplicateUpdate(id string, msg *IncomingRPCMessage) bool { if msg.DecryptedData != nil { contentHash := sha256.Sum256(msg.DecryptedData) - if c.deduplicateHash(contentHash) { - c.Logger.Trace().Hex("data_hash", contentHash[:]).Msg("Ignoring duplicate update") + if c.deduplicateHash(id, contentHash) { + c.Logger.Trace().Str("thing_id", id).Hex("data_hash", contentHash[:]).Msg("Ignoring duplicate update") return true } - c.logContent(msg) + c.logContent(msg, id, contentHash[:]) } return false } diff --git a/libgm/updates_handler.go b/libgm/updates_handler.go index d26de22..48ba3d4 100644 --- a/libgm/updates_handler.go +++ b/libgm/updates_handler.go @@ -16,27 +16,27 @@ func (c *Client) handleUpdatesEvent(msg *IncomingRPCMessage) { switch evt := data.Event.(type) { case *gmproto.UpdateEvents_UserAlertEvent: - c.logContent(msg) + c.logContent(msg, "", nil) c.handleUserAlertEvent(msg, evt.UserAlertEvent) case *gmproto.UpdateEvents_SettingsEvent: - c.logContent(msg) + c.logContent(msg, "", nil) c.triggerEvent(evt.SettingsEvent) case *gmproto.UpdateEvents_ConversationEvent: - if c.deduplicateUpdate(msg) { + if c.deduplicateUpdate(evt.ConversationEvent.GetData().GetConversationID(), msg) { return } c.triggerEvent(evt.ConversationEvent.GetData()) case *gmproto.UpdateEvents_MessageEvent: - if c.deduplicateUpdate(msg) { + if c.deduplicateUpdate(evt.MessageEvent.GetData().GetMessageID(), msg) { return } c.triggerEvent(evt.MessageEvent.GetData()) case *gmproto.UpdateEvents_TypingEvent: - c.logContent(msg) + c.logContent(msg, "", nil) c.triggerEvent(evt.TypingEvent.GetData()) default: