Merge branch 'master' into muc

This commit is contained in:
Bohdan Horbeshko 2025-06-07 03:28:40 -04:00
commit 47da22ed7d
3 changed files with 18 additions and 80 deletions

View file

@ -2,7 +2,6 @@ package telegram
import ( import (
"github.com/pkg/errors" "github.com/pkg/errors"
"hash/maphash"
"path/filepath" "path/filepath"
"strconv" "strconv"
"sync" "sync"
@ -82,7 +81,6 @@ type Client struct {
lastMsgHashes map[int64]uint64 lastMsgHashes map[int64]uint64
lastMsgIds map[int64]string lastMsgIds map[int64]string
msgHashSeed maphash.Seed
mucCache map[int64]*MUCState mucCache map[int64]*MUCState
@ -181,7 +179,6 @@ func NewClient(conf config.TelegramConfig, jid string, component *xmpp.Component
DelayedStatuses: make(map[int64]*DelayedStatus), DelayedStatuses: make(map[int64]*DelayedStatus),
lastMsgHashes: make(map[int64]uint64), lastMsgHashes: make(map[int64]uint64),
lastMsgIds: make(map[int64]string), lastMsgIds: make(map[int64]string),
msgHashSeed: maphash.MakeSeed(),
XmppClientFeatures: make(map[string]*[]string), XmppClientFeatures: make(map[string]*[]string),
AvatarHashes: make(map[int64]*HashedAvatar), AvatarHashes: make(map[int64]*HashedAvatar),
locks: clientLocks{ locks: clientLocks{

View file

@ -253,8 +253,6 @@ func (c *Client) updateNewMessage(update *client.UpdateNewMessage) {
lock.Lock() lock.Lock()
defer lock.Unlock() defer lock.Unlock()
c.updateLastMessageHash(update.Message.ChatId, update.Message.Id, update.Message.Content)
var forceCmd bool var forceCmd bool
if c.LastBotCmdString != "" && update.Message.IsOutgoing { if c.LastBotCmdString != "" && update.Message.IsOutgoing {
if update.Message.Content.MessageContentType() == client.TypeMessageText { if update.Message.Content.MessageContentType() == client.TypeMessageText {
@ -291,8 +289,6 @@ func (c *Client) updateMessageContent(update *client.UpdateMessageContent) {
markupFunction := c.getFormatter() markupFunction := c.getFormatter()
defer c.updateLastMessageHash(update.ChatId, update.MessageId, update.NewContent)
log.Debugf("newContent: %#v", update.NewContent) log.Debugf("newContent: %#v", update.NewContent)
lock := c.getChatMessageLock(update.ChatId) lock := c.getChatMessageLock(update.ChatId)
@ -324,7 +320,7 @@ func (c *Client) updateMessageContent(update *client.UpdateMessageContent) {
return return
} }
if update.NewContent.MessageContentType() == client.TypeMessageText && c.hasLastMessageHashChanged(update.ChatId, update.MessageId, update.NewContent) { if update.NewContent.MessageContentType() == client.TypeMessageText {
textContent := update.NewContent.(*client.MessageText) textContent := update.NewContent.(*client.MessageText)
log.Debugf("textContent: %#v", textContent.Text) log.Debugf("textContent: %#v", textContent.Text)
@ -332,6 +328,23 @@ func (c *Client) updateMessageContent(update *client.UpdateMessageContent) {
sId := strconv.FormatInt(update.MessageId, 10) sId := strconv.FormatInt(update.MessageId, 10)
var isCarbon bool var isCarbon bool
message, messageErr := c.client.GetMessage(&client.GetMessageRequest{
ChatId: update.ChatId,
MessageId: update.MessageId,
})
var prefix string
if messageErr == nil {
if message.EditDate == 0 {
return
}
isCarbon = c.isCarbonsEnabled() && message.IsOutgoing && !isMUC
// reply correction support in clients is suboptimal yet, so cut them out for now
prefix, _ = c.messageToPrefix(message, "", "", true)
} else {
log.Errorf("No message %v/%v found, cannot reliably determine if it is a carbon and if it is edited", update.ChatId, update.MessageId)
}
// use XEP-0308 edits only if the last message is edited for sure, fallback otherwise // use XEP-0308 edits only if the last message is edited for sure, fallback otherwise
if c.Session.NativeEdits { if c.Session.NativeEdits {
lastXmppId, ok := c.getLastChatMessageId(update.ChatId) lastXmppId, ok := c.getLastChatMessageId(update.ChatId)
@ -345,19 +358,6 @@ func (c *Client) updateMessageContent(update *client.UpdateMessageContent) {
} }
} }
message, messageErr := c.client.GetMessage(&client.GetMessageRequest{
ChatId: update.ChatId,
MessageId: update.MessageId,
})
var prefix string
if messageErr == nil {
isCarbon = c.isCarbonsEnabled() && message.IsOutgoing && !isMUC
// reply correction support in clients is suboptimal yet, so cut them out for now
prefix, _ = c.messageToPrefix(message, "", "", true)
} else {
log.Errorf("No message %v/%v found, cannot reliably determine if it's a carbon", update.ChatId, update.MessageId)
}
var text strings.Builder var text strings.Builder
if replaceId == "" { if replaceId == "" {
@ -474,8 +474,6 @@ func (c *Client) updateMessageSendSucceeded(update *client.UpdateMessageSendSucc
log.Errorf("failed to replace %v with %v: %v", update.OldMessageId, update.Message.Id, err.Error()) log.Errorf("failed to replace %v with %v: %v", update.OldMessageId, update.Message.Id, err.Error())
} }
c.updateLastMessageHash(update.Message.ChatId, update.Message.Id, update.Message.Content)
c.sendMarker(update.Message.ChatId, update.Message.Id, gateway.MarkerTypeReceived) c.sendMarker(update.Message.ChatId, update.Message.Id, gateway.MarkerTypeReceived)
// clean uploaded files // clean uploaded files

View file

@ -4,10 +4,8 @@ import (
"bytes" "bytes"
"crypto/sha1" "crypto/sha1"
"encoding/base64" "encoding/base64"
"encoding/binary"
"fmt" "fmt"
"github.com/pkg/errors" "github.com/pkg/errors"
"hash/maphash"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
@ -2407,61 +2405,6 @@ func (c *Client) getCarbonFullJids(isOutgoing bool, ignoredResource string) []st
return jids return jids
} }
func (c *Client) calculateMessageHash(messageId int64, content client.MessageContent) uint64 {
var h maphash.Hash
h.SetSeed(c.msgHashSeed)
buf8 := make([]byte, 8)
binary.BigEndian.PutUint64(buf8, uint64(messageId))
h.Write(buf8)
if content != nil && content.MessageContentType() == client.TypeMessageText {
textContent, ok := content.(*client.MessageText)
if !ok {
uhOh()
}
if textContent.Text != nil {
h.WriteString(textContent.Text.Text)
for _, entity := range textContent.Text.Entities {
buf4 := make([]byte, 4)
binary.BigEndian.PutUint32(buf4, uint32(entity.Offset))
h.Write(buf4)
binary.BigEndian.PutUint32(buf4, uint32(entity.Length))
h.Write(buf4)
h.WriteString(entity.Type.TextEntityTypeType())
}
}
}
return h.Sum64()
}
func (c *Client) updateLastMessageHash(chatId, messageId int64, content client.MessageContent) {
c.locks.lastMsgHashesLock.Lock()
defer c.locks.lastMsgHashesLock.Unlock()
c.lastMsgHashes[chatId] = c.calculateMessageHash(messageId, content)
}
func (c *Client) hasLastMessageHashChanged(chatId, messageId int64, content client.MessageContent) bool {
c.locks.lastMsgHashesLock.Lock()
defer c.locks.lastMsgHashesLock.Unlock()
oldHash, ok := c.lastMsgHashes[chatId]
newHash := c.calculateMessageHash(messageId, content)
if !ok {
log.Warnf("Last message hash for chat %v does not exist", chatId)
}
log.WithFields(log.Fields{
"old hash": oldHash,
"new hash": newHash,
}).Info("Message hashes")
return !ok || oldHash != newHash
}
func (c *Client) UpdateLastChatMessageId(chatId int64, messageId string) { func (c *Client) UpdateLastChatMessageId(chatId int64, messageId string) {
c.locks.lastMsgIdsLock.Lock() c.locks.lastMsgIdsLock.Lock()
defer c.locks.lastMsgIdsLock.Unlock() defer c.locks.lastMsgIdsLock.Unlock()