mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 21:45:19 +00:00
218 lines
7.7 KiB
Objective-C
218 lines
7.7 KiB
Objective-C
#import <MtProtoKit/MTTimeSyncMessageService.h>
|
|
|
|
#import <MtProtoKit/MTTime.h>
|
|
#import <MtProtoKit/MTContext.h>
|
|
#import <MtProtoKit/MTProto.h>
|
|
#import <MtProtoKit/MTSerialization.h>
|
|
#import <MtProtoKit/MTOutgoingMessage.h>
|
|
#import <MtProtoKit/MTIncomingMessage.h>
|
|
#import <MtProtoKit/MTPreparedMessage.h>
|
|
#import <MtProtoKit/MTMessageTransaction.h>
|
|
#import <MtProtoKit/MTDatacenterSaltInfo.h>
|
|
#import "MTBuffer.h"
|
|
#import "MTFutureSaltsMessage.h"
|
|
|
|
@interface MTTimeSyncMessageService ()
|
|
{
|
|
int64_t _currentMessageId;
|
|
id _currentTransactionId;
|
|
CFAbsoluteTime _currentSampleAbsoluteStartTime;
|
|
|
|
NSUInteger _takenSampleCount;
|
|
NSUInteger _requiredSampleCount;
|
|
NSMutableArray *_takenSamples;
|
|
|
|
NSMutableArray *_futureSalts;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation MTTimeSyncMessageService
|
|
|
|
- (instancetype)init
|
|
{
|
|
self = [super init];
|
|
if (self != nil)
|
|
{
|
|
_takenSamples = [[NSMutableArray alloc] init];
|
|
_futureSalts = [[NSMutableArray alloc] init];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)mtProtoDidAddService:(MTProto *)mtProto
|
|
{
|
|
[mtProto requestTransportTransaction];
|
|
}
|
|
|
|
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector sessionInfo:(MTSessionInfo *)sessionInfo scheme:(MTTransportScheme *)scheme
|
|
{
|
|
if (_currentTransactionId == nil)
|
|
{
|
|
_currentMessageId = 0;
|
|
_currentTransactionId = nil;
|
|
_currentSampleAbsoluteStartTime = 0.0;
|
|
|
|
MTBuffer *getFutureSaltsBuffer = [[MTBuffer alloc] init];
|
|
[getFutureSaltsBuffer appendInt32:(int32_t)0xb921bd04];
|
|
[getFutureSaltsBuffer appendInt32:_futureSalts.count != 0 ? 1 : 32];
|
|
|
|
MTOutgoingMessage *outgoingMessage = [[MTOutgoingMessage alloc] initWithData:getFutureSaltsBuffer.data metadata:@"getFutureSalts" additionalDebugDescription:nil shortMetadata:@"getFutureSalts"];
|
|
|
|
return [[MTMessageTransaction alloc] initWithMessagePayload:@[outgoingMessage] prepared:nil failed:nil completion:^(NSDictionary *messageInternalIdToTransactionId, NSDictionary *messageInternalIdToPreparedMessage, __unused NSDictionary *messageInternalIdToQuickAckId)
|
|
{
|
|
MTPreparedMessage *preparedMessage = messageInternalIdToPreparedMessage[outgoingMessage.internalId];
|
|
if (preparedMessage != nil && messageInternalIdToTransactionId[outgoingMessage.internalId] != nil)
|
|
{
|
|
_currentMessageId = preparedMessage.messageId;
|
|
_currentTransactionId = messageInternalIdToTransactionId[outgoingMessage.internalId];
|
|
_currentSampleAbsoluteStartTime = MTAbsoluteSystemTime();
|
|
}
|
|
}];
|
|
}
|
|
else
|
|
return nil;
|
|
}
|
|
|
|
- (void)mtProto:(MTProto *)__unused mtProto messageDeliveryFailed:(int64_t)messageId
|
|
{
|
|
if (messageId == _currentMessageId)
|
|
{
|
|
_currentMessageId = 0;
|
|
_currentTransactionId = nil;
|
|
_currentSampleAbsoluteStartTime = 0.0;
|
|
|
|
[mtProto requestTransportTransaction];
|
|
}
|
|
}
|
|
|
|
- (void)mtProto:(MTProto *)mtProto transactionsMayHaveFailed:(NSArray *)transactionIds
|
|
{
|
|
if (_currentTransactionId != nil && [transactionIds containsObject:_currentTransactionId])
|
|
{
|
|
_currentTransactionId = nil;
|
|
|
|
[mtProto requestTransportTransaction];
|
|
}
|
|
}
|
|
|
|
- (void)mtProtoAllTransactionsMayHaveFailed:(MTProto *)mtProto
|
|
{
|
|
if (_currentTransactionId != nil)
|
|
{
|
|
_currentTransactionId = nil;
|
|
|
|
[mtProto requestTransportTransaction];
|
|
}
|
|
}
|
|
|
|
- (void)mtProtoDidChangeSession:(MTProto *)mtProto
|
|
{
|
|
_currentMessageId = 0;
|
|
_currentTransactionId = nil;
|
|
_currentSampleAbsoluteStartTime = 0.0;
|
|
|
|
[mtProto requestTransportTransaction];
|
|
}
|
|
|
|
- (void)mtProtoServerDidChangeSession:(MTProto *)mtProto firstValidMessageId:(int64_t)firstValidMessageId messageIdsInFirstValidContainer:(NSArray *)messageIdsInFirstValidContainer
|
|
{
|
|
if (_currentMessageId != 0 && _currentMessageId < firstValidMessageId && ![messageIdsInFirstValidContainer containsObject:@(_currentMessageId)])
|
|
{
|
|
_currentMessageId = 0;
|
|
_currentTransactionId = nil;
|
|
_currentSampleAbsoluteStartTime = 0.0;
|
|
|
|
[mtProto requestTransportTransaction];
|
|
}
|
|
}
|
|
|
|
- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector networkType:(int32_t)networkType
|
|
{
|
|
if ([message.body isKindOfClass:[MTFutureSaltsMessage class]] && ((MTFutureSaltsMessage *)message.body).requestMessageId == _currentMessageId)
|
|
{
|
|
_currentMessageId = 0;
|
|
_currentTransactionId = nil;
|
|
|
|
NSMutableArray *saltList = [[NSMutableArray alloc] init];
|
|
for (MTFutureSalt *futureSalt in ((MTFutureSaltsMessage *)message.body).salts)
|
|
{
|
|
[saltList addObject:[[MTDatacenterSaltInfo alloc] initWithSalt:futureSalt.salt firstValidMessageId:futureSalt.validSince * 4294967296 lastValidMessageId:futureSalt.validUntil * 4294967296]];
|
|
}
|
|
|
|
[_futureSalts addObjectsFromArray:saltList];
|
|
|
|
NSTimeInterval timeDifference = message.messageId / 4294967296.0 - [[NSDate date] timeIntervalSince1970];
|
|
[_takenSamples addObject:@(timeDifference)];
|
|
_takenSampleCount++;
|
|
|
|
bool requestTransaction = false;
|
|
|
|
if (_requiredSampleCount == 0)
|
|
{
|
|
if (ABS(MTAbsoluteSystemTime() - _currentSampleAbsoluteStartTime) > 1.0)
|
|
{
|
|
_requiredSampleCount = 6;
|
|
requestTransaction = true;
|
|
}
|
|
}
|
|
|
|
if (_takenSampleCount >= _requiredSampleCount)
|
|
{
|
|
NSTimeInterval maxSampleAbs = 0.0;
|
|
NSUInteger maxSampleIndex = NSNotFound;
|
|
NSTimeInterval minSampleAbs = 0.0;
|
|
NSUInteger minSampleIndex = NSNotFound;
|
|
|
|
NSInteger index = -1;
|
|
for (NSNumber *nSample in _takenSamples)
|
|
{
|
|
index++;
|
|
|
|
if (maxSampleIndex == NSNotFound || ABS([nSample doubleValue]) > maxSampleAbs)
|
|
{
|
|
maxSampleAbs = ABS([nSample doubleValue]);
|
|
maxSampleIndex = (NSUInteger)index;
|
|
}
|
|
|
|
if (minSampleIndex == NSNotFound || ABS([nSample doubleValue]) < minSampleAbs)
|
|
{
|
|
minSampleAbs = ABS([nSample doubleValue]);
|
|
minSampleIndex = (NSUInteger)index;
|
|
}
|
|
}
|
|
|
|
NSMutableIndexSet *indexSet = [[NSMutableIndexSet alloc] init];
|
|
if (maxSampleIndex != NSNotFound)
|
|
[indexSet addIndex:maxSampleIndex];
|
|
if (minSampleIndex != NSNotFound)
|
|
[indexSet addIndex:minSampleIndex];
|
|
[_takenSamples removeObjectsAtIndexes:indexSet];
|
|
|
|
NSTimeInterval totalTimeDifference = 0.0;
|
|
if (_takenSamples.count != 0)
|
|
{
|
|
NSTimeInterval timeDifferenceSum = 0.0;
|
|
for (NSNumber *nSample in _takenSamples)
|
|
{
|
|
timeDifferenceSum += [nSample doubleValue];
|
|
}
|
|
totalTimeDifference = timeDifferenceSum / _takenSamples.count;
|
|
}
|
|
else
|
|
totalTimeDifference = timeDifference;
|
|
|
|
id<MTTimeSyncMessageServiceDelegate> delegate = _delegate;
|
|
if ([delegate respondsToSelector:@selector(timeSyncServiceCompleted:timeDifference:saltList:)])
|
|
[delegate timeSyncServiceCompleted:self timeDifference:totalTimeDifference saltList:_futureSalts];
|
|
}
|
|
else
|
|
requestTransaction = true;
|
|
|
|
if (requestTransaction)
|
|
[mtProto requestTransportTransaction];
|
|
}
|
|
}
|
|
|
|
@end
|