diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 3de36d8..165ccc0 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -18,12 +18,16 @@ import ( // GenerateMessageId отдает по сути unix timestamp но ужасно специфическим образом // TODO: нахуя нужно битовое и на -4?? -func GenerateMessageId() int64 { +func GenerateMessageId(prevID int64) int64 { const billion = 1000 * 1000 * 1000 unixnano := time.Now().UnixNano() seconds := unixnano / billion nanoseconds := unixnano % billion - return (seconds << 32) | (nanoseconds & -4) + newID := (seconds << 32) | (nanoseconds & -4) + if newID <= prevID { + return GenerateMessageId(prevID) + } + return newID } func AuthKeyHash(key []byte) []byte { diff --git a/mtproto.go b/mtproto.go index 7ee97df..d998e03 100644 --- a/mtproto.go +++ b/mtproto.go @@ -53,6 +53,8 @@ type MTProto struct { // идентификаторы сообщений, нужны что бы посылать и принимать сообщения. seqNoMutex sync.Mutex seqNo int32 + lastMessageIDMutex sync.Mutex + lastMessageID int64 // айдишники DC для КОНКРЕТНОГО Приложения и клиента. Может меняться, но фиксирована для // связки приложение+клиент diff --git a/network.go b/network.go index e583c32..7131682 100644 --- a/network.go +++ b/network.go @@ -24,10 +24,13 @@ func (m *MTProto) sendPacket(request tl.Object, expectedTypes ...reflect.Type) ( return nil, errors.Wrap(err, "encoding request message") } + m.lastMessageIDMutex.Lock() var ( data messages.Common - msgID = utils.GenerateMessageId() + msgID = utils.GenerateMessageId(m.lastMessageID) ) + m.lastMessageIDMutex.Unlock() + m.lastMessageID = msgID // adding types for parser if required if len(expectedTypes) > 0 {