Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin 2021-12-22 16:52:20 +04:00
commit 888e5e1474
18 changed files with 313 additions and 120 deletions

View File

@ -110,7 +110,7 @@
- (void)updateAuthTokenForDatacenterWithId:(NSInteger)datacenterId authToken:(id _Nullable)authToken;
- (void)addressSetForDatacenterWithIdRequired:(NSInteger)datacenterId;
- (void)authInfoForDatacenterWithIdRequired:(NSInteger)datacenterId isCdn:(bool)isCdn selector:(MTDatacenterAuthInfoSelector)selector;
- (void)authInfoForDatacenterWithIdRequired:(NSInteger)datacenterId isCdn:(bool)isCdn selector:(MTDatacenterAuthInfoSelector)selector allowUnboundEphemeralKeys:(bool)allowUnboundEphemeralKeys;
- (void)authTokenForDatacenterWithIdRequired:(NSInteger)datacenterId authToken:(id _Nullable)authToken masterDatacenterId:(NSInteger)masterDatacenterId;
- (void)reportProblemsWithDatacenterAddressForId:(NSInteger)datacenterId address:(MTDatacenterAddress * _Nonnull)address;

View File

@ -7,7 +7,7 @@
@interface MTDatacenterAuthAction : NSObject
- (instancetype)initWithAuthKeyInfoSelector:(MTDatacenterAuthInfoSelector)authKeyInfoSelector isCdn:(bool)isCdn completion:(void (^)(MTDatacenterAuthAction *, bool))completion;
- (instancetype)initWithAuthKeyInfoSelector:(MTDatacenterAuthInfoSelector)authKeyInfoSelector isCdn:(bool)isCdn skipBind:(bool)skipBind completion:(void (^)(MTDatacenterAuthAction *, bool))completion;
- (void)execute:(MTContext *)context datacenterId:(NSInteger)datacenterId;
- (void)cancel;

View File

@ -47,6 +47,7 @@
@property (nonatomic) bool media;
@property (nonatomic) bool enforceMedia;
@property (nonatomic) bool cdn;
@property (nonatomic) bool allowUnboundEphemeralKeys;
@property (nonatomic) bool checkForProxyConnectionIssues;
@property (nonatomic) bool canResetAuthData;
@property (nonatomic) id requiredAuthToken;

View File

@ -247,9 +247,8 @@ static NSString *makeRandomPadding() {
}
MTProto *mtProto = [[MTProto alloc] initWithContext:context datacenterId:address.datacenterId usageCalculationInfo:nil requiredAuthToken:nil authTokenMasterDatacenterId:0];
if (address.datacenterId != 0) {
mtProto.useTempAuthKeys = currentContext.useTempAuthKeys;
}
mtProto.useTempAuthKeys = true;
mtProto.allowUnboundEphemeralKeys = true;
MTRequestMessageService *requestService = [[MTRequestMessageService alloc] initWithContext:context];
[mtProto addMessageService:requestService];

View File

@ -1305,7 +1305,7 @@ static int32_t fixedTimeDifferenceValue = 0;
}];
}
- (void)authInfoForDatacenterWithIdRequired:(NSInteger)datacenterId isCdn:(bool)isCdn selector:(MTDatacenterAuthInfoSelector)selector
- (void)authInfoForDatacenterWithIdRequired:(NSInteger)datacenterId isCdn:(bool)isCdn selector:(MTDatacenterAuthInfoSelector)selector allowUnboundEphemeralKeys:(bool)allowUnboundEphemeralKeys
{
[[MTContext contextQueue] dispatchOnQueue:^
{
@ -1314,7 +1314,7 @@ static int32_t fixedTimeDifferenceValue = 0;
if (_datacenterAuthActions[infoKey] == nil)
{
__weak MTContext *weakSelf = self;
MTDatacenterAuthAction *authAction = [[MTDatacenterAuthAction alloc] initWithAuthKeyInfoSelector:selector isCdn:isCdn completion:^(MTDatacenterAuthAction *action, __unused bool success) {
MTDatacenterAuthAction *authAction = [[MTDatacenterAuthAction alloc] initWithAuthKeyInfoSelector:selector isCdn:isCdn skipBind:allowUnboundEphemeralKeys completion:^(MTDatacenterAuthAction *action, __unused bool success) {
[[MTContext contextQueue] dispatchOnQueue:^{
__strong MTContext *strongSelf = weakSelf;
if (strongSelf == nil) {
@ -1334,8 +1334,8 @@ static int32_t fixedTimeDifferenceValue = 0;
switch (selector) {
case MTDatacenterAuthInfoSelectorEphemeralMain:
case MTDatacenterAuthInfoSelectorEphemeralMedia: {
if ([self authInfoForDatacenterWithId:datacenterId selector:MTDatacenterAuthInfoSelectorPersistent] == nil) {
[self authInfoForDatacenterWithIdRequired:datacenterId isCdn:false selector:MTDatacenterAuthInfoSelectorPersistent];
if ([self authInfoForDatacenterWithId:datacenterId selector:MTDatacenterAuthInfoSelectorPersistent] == nil && !allowUnboundEphemeralKeys) {
[self authInfoForDatacenterWithIdRequired:datacenterId isCdn:false selector:MTDatacenterAuthInfoSelectorPersistent allowUnboundEphemeralKeys:false];
} else {
[authAction execute:self datacenterId:datacenterId];
}

View File

@ -20,6 +20,7 @@
void (^_completion)(MTDatacenterAuthAction *, bool);
bool _isCdn;
bool _skipBind;
MTDatacenterAuthInfoSelector _authKeyInfoSelector;
NSInteger _datacenterId;
@ -34,11 +35,12 @@
@implementation MTDatacenterAuthAction
- (instancetype)initWithAuthKeyInfoSelector:(MTDatacenterAuthInfoSelector)authKeyInfoSelector isCdn:(bool)isCdn completion:(void (^)(MTDatacenterAuthAction *, bool))completion {
- (instancetype)initWithAuthKeyInfoSelector:(MTDatacenterAuthInfoSelector)authKeyInfoSelector isCdn:(bool)isCdn skipBind:(bool)skipBind completion:(void (^)(MTDatacenterAuthAction *, bool))completion {
self = [super init];
if (self != nil) {
_authKeyInfoSelector = authKeyInfoSelector;
_isCdn = isCdn;
_skipBind = skipBind;
_completion = [completion copy];
}
return self;
@ -114,45 +116,53 @@
case MTDatacenterAuthInfoSelectorEphemeralMedia: {
MTContext *mainContext = _context;
if (mainContext != nil) {
MTDatacenterAuthInfo *persistentAuthInfo = [mainContext authInfoForDatacenterWithId:_datacenterId selector:MTDatacenterAuthInfoSelectorPersistent];
if (persistentAuthInfo != nil) {
_bindMtProto = [[MTProto alloc] initWithContext:mainContext datacenterId:_datacenterId usageCalculationInfo:nil requiredAuthToken:nil authTokenMasterDatacenterId:0];
_bindMtProto.cdn = false;
_bindMtProto.useUnauthorizedMode = false;
_bindMtProto.useTempAuthKeys = true;
_bindMtProto.useExplicitAuthKey = authKey;
if (_skipBind) {
MTDatacenterAuthInfo *authInfo = [[MTDatacenterAuthInfo alloc] initWithAuthKey:authKey.authKey authKeyId:authKey.authKeyId saltSet:@[[[MTDatacenterSaltInfo alloc] initWithSalt:0 firstValidMessageId:timestamp lastValidMessageId:timestamp + (29.0 * 60.0) * 4294967296]] authKeyAttributes:nil];
switch (_authKeyInfoSelector) {
case MTDatacenterAuthInfoSelectorEphemeralMain:
_bindMtProto.media = false;
break;
case MTDatacenterAuthInfoSelectorEphemeralMedia:
_bindMtProto.media = true;
_bindMtProto.enforceMedia = true;
break;
default:
break;
}
[_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:authInfo selector:_authKeyInfoSelector];
__weak MTDatacenterAuthAction *weakSelf = self;
[_bindMtProto addMessageService:[[MTBindKeyMessageService alloc] initWithPersistentKey:[[MTDatacenterAuthKey alloc] initWithAuthKey:persistentAuthInfo.authKey authKeyId:persistentAuthInfo.authKeyId notBound:false] ephemeralKey:authKey completion:^(bool success) {
__strong MTDatacenterAuthAction *strongSelf = weakSelf;
if (strongSelf == nil) {
return;
}
[strongSelf->_bindMtProto stop];
[self complete];
} else {
MTDatacenterAuthInfo *persistentAuthInfo = [mainContext authInfoForDatacenterWithId:_datacenterId selector:MTDatacenterAuthInfoSelectorPersistent];
if (persistentAuthInfo != nil) {
_bindMtProto = [[MTProto alloc] initWithContext:mainContext datacenterId:_datacenterId usageCalculationInfo:nil requiredAuthToken:nil authTokenMasterDatacenterId:0];
_bindMtProto.cdn = false;
_bindMtProto.useUnauthorizedMode = false;
_bindMtProto.useTempAuthKeys = true;
_bindMtProto.useExplicitAuthKey = authKey;
if (success) {
MTDatacenterAuthInfo *authInfo = [[MTDatacenterAuthInfo alloc] initWithAuthKey:authKey.authKey authKeyId:authKey.authKeyId saltSet:@[[[MTDatacenterSaltInfo alloc] initWithSalt:0 firstValidMessageId:timestamp lastValidMessageId:timestamp + (29.0 * 60.0) * 4294967296]] authKeyAttributes:nil];
[strongSelf->_context updateAuthInfoForDatacenterWithId:strongSelf->_datacenterId authInfo:authInfo selector:strongSelf->_authKeyInfoSelector];
[strongSelf complete];
} else {
[strongSelf fail];
switch (_authKeyInfoSelector) {
case MTDatacenterAuthInfoSelectorEphemeralMain:
_bindMtProto.media = false;
break;
case MTDatacenterAuthInfoSelectorEphemeralMedia:
_bindMtProto.media = true;
_bindMtProto.enforceMedia = true;
break;
default:
break;
}
}]];
[_bindMtProto resume];
__weak MTDatacenterAuthAction *weakSelf = self;
[_bindMtProto addMessageService:[[MTBindKeyMessageService alloc] initWithPersistentKey:[[MTDatacenterAuthKey alloc] initWithAuthKey:persistentAuthInfo.authKey authKeyId:persistentAuthInfo.authKeyId notBound:false] ephemeralKey:authKey completion:^(bool success) {
__strong MTDatacenterAuthAction *strongSelf = weakSelf;
if (strongSelf == nil) {
return;
}
[strongSelf->_bindMtProto stop];
if (success) {
MTDatacenterAuthInfo *authInfo = [[MTDatacenterAuthInfo alloc] initWithAuthKey:authKey.authKey authKeyId:authKey.authKeyId saltSet:@[[[MTDatacenterSaltInfo alloc] initWithSalt:0 firstValidMessageId:timestamp lastValidMessageId:timestamp + (29.0 * 60.0) * 4294967296]] authKeyAttributes:nil];
[strongSelf->_context updateAuthInfoForDatacenterWithId:strongSelf->_datacenterId authInfo:authInfo selector:strongSelf->_authKeyInfoSelector];
[strongSelf complete];
} else {
[strongSelf fail];
}
}]];
[_bindMtProto resume];
}
}
}
}

View File

@ -249,7 +249,7 @@
MTMetaDisposable *disposable = [[MTMetaDisposable alloc] init];
[[MTContext contextQueue] dispatchOnQueue:^{
MTDatacenterAuthAction *action = [[MTDatacenterAuthAction alloc] initWithAuthKeyInfoSelector:MTDatacenterAuthInfoSelectorEphemeralMain isCdn:false completion:^(__unused MTDatacenterAuthAction *action, bool success) {
MTDatacenterAuthAction *action = [[MTDatacenterAuthAction alloc] initWithAuthKeyInfoSelector:MTDatacenterAuthInfoSelectorEphemeralMain isCdn:false skipBind:false completion:^(__unused MTDatacenterAuthAction *action, bool success) {
[subscriber putNext:@(!success)];
[subscriber putCompletion];
}];

View File

@ -119,7 +119,7 @@
}
else {
[context authInfoForDatacenterWithIdRequired:_targetDatacenterId isCdn:false selector:MTDatacenterAuthInfoSelectorPersistent];
[context authInfoForDatacenterWithIdRequired:_targetDatacenterId isCdn:false selector:MTDatacenterAuthInfoSelectorPersistent allowUnboundEphemeralKeys:false];
}
}
}

View File

@ -875,7 +875,7 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
} else {
[_context performBatchUpdates:^{
[_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil selector:selector];
[_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:_cdn selector:selector];
[_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:_cdn selector:selector allowUnboundEphemeralKeys:_allowUnboundEphemeralKeys];
}];
_mtState |= MTProtoStateAwaitingDatacenterAuthorization;
_awaitingAuthInfoForSelector = @(selector);
@ -2064,7 +2064,7 @@ static NSString *dumpHexString(NSData *data, int maxLength) {
[_context performBatchUpdates:^{
[_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil selector:authInfoSelector];
[_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:true selector:authInfoSelector];
[_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:true selector:authInfoSelector allowUnboundEphemeralKeys:_allowUnboundEphemeralKeys];
}];
_mtState |= MTProtoStateAwaitingDatacenterAuthorization;
_awaitingAuthInfoForSelector = @(authInfoSelector);
@ -2078,7 +2078,7 @@ static NSString *dumpHexString(NSData *data, int maxLength) {
[_context removeTokenForDatacenterWithId:_datacenterId];
[_context performBatchUpdates:^{
[_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil selector:authInfoSelector];
[_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:false selector:authInfoSelector];
[_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:false selector:authInfoSelector allowUnboundEphemeralKeys:_allowUnboundEphemeralKeys];
}];
_mtState |= MTProtoStateAwaitingDatacenterAuthorization;
_awaitingAuthInfoForSelector = @(authInfoSelector);
@ -2087,7 +2087,7 @@ static NSString *dumpHexString(NSData *data, int maxLength) {
[_context performBatchUpdates:^{
[_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil selector:authInfoSelector];
[_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:false selector:authInfoSelector];
[_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:false selector:authInfoSelector allowUnboundEphemeralKeys:_allowUnboundEphemeralKeys];
}];
_mtState |= MTProtoStateAwaitingDatacenterAuthorization;
_awaitingAuthInfoForSelector = @(authInfoSelector);
@ -2099,7 +2099,7 @@ static NSString *dumpHexString(NSData *data, int maxLength) {
[_context performBatchUpdates:^{
[_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil selector:authInfoSelector];
[_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:false selector:authInfoSelector];
[_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:false selector:authInfoSelector allowUnboundEphemeralKeys:_allowUnboundEphemeralKeys];
}];
_mtState |= MTProtoStateAwaitingDatacenterAuthorization;
_awaitingAuthInfoForSelector = @(authInfoSelector);

View File

@ -1806,7 +1806,8 @@ public final class PostboxDecoder {
let result = try AdaptedPostboxDecoder().decode(T.self, from: innerData)
return result
} catch let error {
assertionFailure("Decoding error: \(error)")
postboxLog("Decoding error: \(error)")
//assertionFailure("Decoding error: \(error)")
return nil
}
} else {

View File

@ -758,7 +758,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1625153079] = { return Api.InputWebFileLocation.parse_inputWebFileGeoPointLocation($0) }
dict[-1275374751] = { return Api.EmojiLanguage.parse_emojiLanguage($0) }
dict[1601666510] = { return Api.MessageFwdHeader.parse_messageFwdHeader($0) }
dict[-783162982] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) }
dict[981691896] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) }
dict[-1012849566] = { return Api.BaseTheme.parse_baseThemeClassic($0) }
dict[-69724536] = { return Api.BaseTheme.parse_baseThemeDay($0) }
dict[-1212997976] = { return Api.BaseTheme.parse_baseThemeNight($0) }
@ -791,7 +791,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[594408994] = { return Api.EmojiKeyword.parse_emojiKeywordDeleted($0) }
dict[-290921362] = { return Api.upload.CdnFile.parse_cdnFileReuploadNeeded($0) }
dict[-1449145777] = { return Api.upload.CdnFile.parse_cdnFile($0) }
dict[1679961905] = { return Api.AvailableReaction.parse_availableReaction($0) }
dict[1424116867] = { return Api.AvailableReaction.parse_availableReaction($0) }
dict[415997816] = { return Api.help.InviteText.parse_inviteText($0) }
dict[-1826077446] = { return Api.MessageUserReaction.parse_messageUserReaction($0) }
dict[1984755728] = { return Api.BotInlineMessage.parse_botInlineMessageMediaAuto($0) }

View File

@ -19708,17 +19708,19 @@ public extension Api {
}
public enum SponsoredMessage: TypeConstructorDescription {
case sponsoredMessage(flags: Int32, randomId: Buffer, fromId: Api.Peer, channelPost: Int32?, startParam: String?, message: String, entities: [Api.MessageEntity]?)
case sponsoredMessage(flags: Int32, randomId: Buffer, fromId: Api.Peer?, chatInvite: Api.ChatInvite?, chatInviteHash: String?, channelPost: Int32?, startParam: String?, message: String, entities: [Api.MessageEntity]?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .sponsoredMessage(let flags, let randomId, let fromId, let channelPost, let startParam, let message, let entities):
case .sponsoredMessage(let flags, let randomId, let fromId, let chatInvite, let chatInviteHash, let channelPost, let startParam, let message, let entities):
if boxed {
buffer.appendInt32(-783162982)
buffer.appendInt32(981691896)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeBytes(randomId, buffer: buffer, boxed: false)
fromId.serialize(buffer, true)
if Int(flags) & Int(1 << 3) != 0 {fromId!.serialize(buffer, true)}
if Int(flags) & Int(1 << 4) != 0 {chatInvite!.serialize(buffer, true)}
if Int(flags) & Int(1 << 4) != 0 {serializeString(chatInviteHash!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(channelPost!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 0) != 0 {serializeString(startParam!, buffer: buffer, boxed: false)}
serializeString(message, buffer: buffer, boxed: false)
@ -19733,8 +19735,8 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .sponsoredMessage(let flags, let randomId, let fromId, let channelPost, let startParam, let message, let entities):
return ("sponsoredMessage", [("flags", flags), ("randomId", randomId), ("fromId", fromId), ("channelPost", channelPost), ("startParam", startParam), ("message", message), ("entities", entities)])
case .sponsoredMessage(let flags, let randomId, let fromId, let chatInvite, let chatInviteHash, let channelPost, let startParam, let message, let entities):
return ("sponsoredMessage", [("flags", flags), ("randomId", randomId), ("fromId", fromId), ("chatInvite", chatInvite), ("chatInviteHash", chatInviteHash), ("channelPost", channelPost), ("startParam", startParam), ("message", message), ("entities", entities)])
}
}
@ -19744,28 +19746,36 @@ public extension Api {
var _2: Buffer?
_2 = parseBytes(reader)
var _3: Api.Peer?
if let signature = reader.readInt32() {
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
_3 = Api.parse(reader, signature: signature) as? Api.Peer
}
var _4: Int32?
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
} }
var _4: Api.ChatInvite?
if Int(_1!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() {
_4 = Api.parse(reader, signature: signature) as? Api.ChatInvite
} }
var _5: String?
if Int(_1!) & Int(1 << 0) != 0 {_5 = parseString(reader) }
var _6: String?
_6 = parseString(reader)
var _7: [Api.MessageEntity]?
if Int(_1!) & Int(1 << 4) != 0 {_5 = parseString(reader) }
var _6: Int32?
if Int(_1!) & Int(1 << 2) != 0 {_6 = reader.readInt32() }
var _7: String?
if Int(_1!) & Int(1 << 0) != 0 {_7 = parseString(reader) }
var _8: String?
_8 = parseString(reader)
var _9: [Api.MessageEntity]?
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
_9 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
let _c6 = _6 != nil
let _c7 = (Int(_1!) & Int(1 << 1) == 0) || _7 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
return Api.SponsoredMessage.sponsoredMessage(flags: _1!, randomId: _2!, fromId: _3!, channelPost: _4, startParam: _5, message: _6!, entities: _7)
let _c3 = (Int(_1!) & Int(1 << 3) == 0) || _3 != nil
let _c4 = (Int(_1!) & Int(1 << 4) == 0) || _4 != nil
let _c5 = (Int(_1!) & Int(1 << 4) == 0) || _5 != nil
let _c6 = (Int(_1!) & Int(1 << 2) == 0) || _6 != nil
let _c7 = (Int(_1!) & Int(1 << 0) == 0) || _7 != nil
let _c8 = _8 != nil
let _c9 = (Int(_1!) & Int(1 << 1) == 0) || _9 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 {
return Api.SponsoredMessage.sponsoredMessage(flags: _1!, randomId: _2!, fromId: _3, chatInvite: _4, chatInviteHash: _5, channelPost: _6, startParam: _7, message: _8!, entities: _9)
}
else {
return nil
@ -20190,17 +20200,18 @@ public extension Api {
}
public enum AvailableReaction: TypeConstructorDescription {
case availableReaction(reaction: String, title: String, staticIcon: Api.Document, selectAnimation: Api.Document, activateAnimation: Api.Document, effectAnimation: Api.Document)
case availableReaction(reaction: String, title: String, staticIcon: Api.Document, appearAnimation: Api.Document, selectAnimation: Api.Document, activateAnimation: Api.Document, effectAnimation: Api.Document)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .availableReaction(let reaction, let title, let staticIcon, let selectAnimation, let activateAnimation, let effectAnimation):
case .availableReaction(let reaction, let title, let staticIcon, let appearAnimation, let selectAnimation, let activateAnimation, let effectAnimation):
if boxed {
buffer.appendInt32(1679961905)
buffer.appendInt32(1424116867)
}
serializeString(reaction, buffer: buffer, boxed: false)
serializeString(title, buffer: buffer, boxed: false)
staticIcon.serialize(buffer, true)
appearAnimation.serialize(buffer, true)
selectAnimation.serialize(buffer, true)
activateAnimation.serialize(buffer, true)
effectAnimation.serialize(buffer, true)
@ -20210,8 +20221,8 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .availableReaction(let reaction, let title, let staticIcon, let selectAnimation, let activateAnimation, let effectAnimation):
return ("availableReaction", [("reaction", reaction), ("title", title), ("staticIcon", staticIcon), ("selectAnimation", selectAnimation), ("activateAnimation", activateAnimation), ("effectAnimation", effectAnimation)])
case .availableReaction(let reaction, let title, let staticIcon, let appearAnimation, let selectAnimation, let activateAnimation, let effectAnimation):
return ("availableReaction", [("reaction", reaction), ("title", title), ("staticIcon", staticIcon), ("appearAnimation", appearAnimation), ("selectAnimation", selectAnimation), ("activateAnimation", activateAnimation), ("effectAnimation", effectAnimation)])
}
}
@ -20236,14 +20247,19 @@ public extension Api {
if let signature = reader.readInt32() {
_6 = Api.parse(reader, signature: signature) as? Api.Document
}
var _7: Api.Document?
if let signature = reader.readInt32() {
_7 = Api.parse(reader, signature: signature) as? Api.Document
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
let _c6 = _6 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
return Api.AvailableReaction.availableReaction(reaction: _1!, title: _2!, staticIcon: _3!, selectAnimation: _4!, activateAnimation: _5!, effectAnimation: _6!)
let _c7 = _7 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
return Api.AvailableReaction.availableReaction(reaction: _1!, title: _2!, staticIcon: _3!, appearAnimation: _4!, selectAnimation: _5!, activateAnimation: _6!, effectAnimation: _7!)
}
else {
return nil

View File

@ -4591,6 +4591,20 @@ public extension Api {
return result
})
}
public static func setDefaultReaction(emoji: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(1474910882)
serializeString(emoji, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.setDefaultReaction", parameters: [("emoji", emoji)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public struct channels {
public static func readHistory(channel: Api.InputChannel, maxId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {

View File

@ -113,7 +113,7 @@ public class UnauthorizedAccount {
}
for id in datacenterIds {
if network.context.authInfoForDatacenter(withId: id, selector: .persistent) == nil {
network.context.authInfoForDatacenter(withIdRequired: id, isCdn: false, selector: .ephemeralMain)
network.context.authInfoForDatacenter(withIdRequired: id, isCdn: false, selector: .ephemeralMain, allowUnboundEphemeralKeys: false)
}
}
network.context.beginExplicitBackupAddressDiscovery()
@ -200,6 +200,16 @@ public func accountWithId(accountManager: AccountManager<TelegramAccountManagerT
state = backupState
let dict = NSMutableDictionary()
dict.setObject(MTDatacenterAuthInfo(authKey: backupData.masterDatacenterKey, authKeyId: backupData.masterDatacenterKeyId, saltSet: [], authKeyAttributes: [:])!, forKey: backupData.masterDatacenterId as NSNumber)
for (id, datacenterKey) in backupData.additionalDatacenterKeys {
dict.setObject(MTDatacenterAuthInfo(
authKey: datacenterKey.key,
authKeyId: datacenterKey.keyId,
saltSet: [],
authKeyAttributes: [:]
)!, forKey: id as NSNumber)
}
let data = NSKeyedArchiver.archivedData(withRootObject: dict)
transaction.setState(backupState)
transaction.setKeychainEntry(data, forKey: "persistent:datacenterAuthInfoById")
@ -807,6 +817,34 @@ public func accountBackupData(postbox: Postbox) -> Signal<AccountBackupData?, No
guard let datacenterAuthInfo = authInfo.object(forKey: state.masterDatacenterId as NSNumber) as? MTDatacenterAuthInfo else {
return nil
}
var additionalDatacenterKeys: [Int32: AccountBackupData.DatacenterKey] = [:]
for item in authInfo {
guard let idNumber = item.key as? NSNumber else {
continue
}
guard let id = idNumber as? Int32 else {
continue
}
if id <= 0 || id > 10 {
continue
}
if id == state.masterDatacenterId {
continue
}
guard let otherDatacenterAuthInfo = authInfo.object(forKey: idNumber) as? MTDatacenterAuthInfo else {
continue
}
guard let otherAuthKey = otherDatacenterAuthInfo.authKey else {
continue
}
additionalDatacenterKeys[id] = AccountBackupData.DatacenterKey(
id: id,
keyId: otherDatacenterAuthInfo.authKeyId,
key: otherAuthKey
)
}
guard let authKey = datacenterAuthInfo.authKey else {
return nil
}
@ -817,7 +855,8 @@ public func accountBackupData(postbox: Postbox) -> Signal<AccountBackupData?, No
masterDatacenterKey: authKey,
masterDatacenterKeyId: datacenterAuthInfo.authKeyId,
notificationEncryptionKeyId: notificationsKey?.id,
notificationEncryptionKey: notificationsKey?.data
notificationEncryptionKey: notificationsKey?.data,
additionalDatacenterKeys: additionalDatacenterKeys
)
}
}

View File

@ -516,7 +516,14 @@ func initializedNetwork(accountId: AccountRecordId, arguments: NetworkInitializa
}
}
#endif
context.setDiscoverBackupAddressListSignal(MTBackupAddressSignals.fetchBackupIps(testingEnvironment, currentContext: context, additionalSource: wrappedAdditionalSource, phoneNumber: phoneNumber))
if !supplementary {
context.setDiscoverBackupAddressListSignal(MTBackupAddressSignals.fetchBackupIps(testingEnvironment, currentContext: context, additionalSource: wrappedAdditionalSource, phoneNumber: phoneNumber))
}
/*#if DEBUG
context.beginExplicitBackupAddressDiscovery()
#endif*/
let mtProto = MTProto(context: context, datacenterId: datacenterId, usageCalculationInfo: usageCalculationInfo(basePath: basePath, category: nil), requiredAuthToken: nil, authTokenMasterDatacenterId: 0)!
mtProto.useTempAuthKeys = context.useTempAuthKeys

View File

@ -9,6 +9,7 @@ public final class AvailableReactions: Equatable, Codable {
case value
case title
case staticIcon
case appearAnimation
case selectAnimation
case activateAnimation
case effectAnimation
@ -17,6 +18,7 @@ public final class AvailableReactions: Equatable, Codable {
public let value: String
public let title: String
public let staticIcon: TelegramMediaFile
public let appearAnimation: TelegramMediaFile
public let selectAnimation: TelegramMediaFile
public let activateAnimation: TelegramMediaFile
public let effectAnimation: TelegramMediaFile
@ -25,6 +27,7 @@ public final class AvailableReactions: Equatable, Codable {
value: String,
title: String,
staticIcon: TelegramMediaFile,
appearAnimation: TelegramMediaFile,
selectAnimation: TelegramMediaFile,
activateAnimation: TelegramMediaFile,
effectAnimation: TelegramMediaFile
@ -32,6 +35,7 @@ public final class AvailableReactions: Equatable, Codable {
self.value = value
self.title = title
self.staticIcon = staticIcon
self.appearAnimation = appearAnimation
self.selectAnimation = selectAnimation
self.activateAnimation = activateAnimation
self.effectAnimation = effectAnimation
@ -47,6 +51,9 @@ public final class AvailableReactions: Equatable, Codable {
if lhs.staticIcon != rhs.staticIcon {
return false
}
if lhs.appearAnimation != rhs.appearAnimation {
return false
}
if lhs.selectAnimation != rhs.selectAnimation {
return false
}
@ -68,6 +75,9 @@ public final class AvailableReactions: Equatable, Codable {
let staticIconData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .staticIcon)
self.staticIcon = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: staticIconData.data)))
let appearAnimationData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .appearAnimation)
self.appearAnimation = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: appearAnimationData.data)))
let selectAnimationData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: .selectAnimation)
self.selectAnimation = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: selectAnimationData.data)))
@ -85,6 +95,7 @@ public final class AvailableReactions: Equatable, Codable {
try container.encode(self.title, forKey: .title)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.staticIcon), forKey: .staticIcon)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.appearAnimation), forKey: .appearAnimation)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.selectAnimation), forKey: .selectAnimation)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.activateAnimation), forKey: .activateAnimation)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.effectAnimation), forKey: .effectAnimation)
@ -135,10 +146,13 @@ public final class AvailableReactions: Equatable, Codable {
private extension AvailableReactions.Reaction {
convenience init?(apiReaction: Api.AvailableReaction) {
switch apiReaction {
case let .availableReaction(reaction, title, staticIcon, selectAnimation, activateAnimation, effectAnimation):
case let .availableReaction(reaction, title, staticIcon, appearAnimation, selectAnimation, activateAnimation, effectAnimation):
guard let staticIconFile = telegramMediaFileFromApiDocument(staticIcon) else {
return nil
}
guard let appearAnimationFile = telegramMediaFileFromApiDocument(appearAnimation) else {
return nil
}
guard let selectAnimationFile = telegramMediaFileFromApiDocument(selectAnimation) else {
return nil
}
@ -152,6 +166,7 @@ private extension AvailableReactions.Reaction {
value: reaction,
title: title,
staticIcon: staticIconFile,
appearAnimation: appearAnimationFile,
selectAnimation: selectAnimationFile,
activateAnimation: activateAnimationFile,
effectAnimation: effectAnimationFile

View File

@ -2,12 +2,39 @@ import Foundation
import Postbox
public struct AccountBackupData: Codable, Equatable {
private enum CodingKeys: String, CodingKey {
case masterDatacenterId
case peerId
case masterDatacenterKey
case masterDatacenterKeyId
case notificationEncryptionKeyId
case notificationEncryptionKey
case additionalDatacenterKeys
}
public struct DatacenterKey: Codable, Equatable {
public var id: Int32
public var keyId: Int64
public var key: Data
public init(
id: Int32,
keyId: Int64,
key: Data
) {
self.id = id
self.keyId = keyId
self.key = key
}
}
public var masterDatacenterId: Int32
public var peerId: Int64
public var masterDatacenterKey: Data
public var masterDatacenterKeyId: Int64
public var notificationEncryptionKeyId: Data?
public var notificationEncryptionKey: Data?
public var additionalDatacenterKeys: [Int32: DatacenterKey]
public init(
masterDatacenterId: Int32,
@ -15,7 +42,8 @@ public struct AccountBackupData: Codable, Equatable {
masterDatacenterKey: Data,
masterDatacenterKeyId: Int64,
notificationEncryptionKeyId: Data?,
notificationEncryptionKey: Data?
notificationEncryptionKey: Data?,
additionalDatacenterKeys: [Int32: DatacenterKey]
) {
self.masterDatacenterId = masterDatacenterId
self.peerId = peerId
@ -23,6 +51,31 @@ public struct AccountBackupData: Codable, Equatable {
self.masterDatacenterKeyId = masterDatacenterKeyId
self.notificationEncryptionKeyId = notificationEncryptionKeyId
self.notificationEncryptionKey = notificationEncryptionKey
self.additionalDatacenterKeys = additionalDatacenterKeys
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.masterDatacenterId = try container.decode(Int32.self, forKey: .masterDatacenterId)
self.peerId = try container.decode(Int64.self, forKey: .peerId)
self.masterDatacenterKey = try container.decode(Data.self, forKey: .masterDatacenterKey)
self.masterDatacenterKeyId = try container.decode(Int64.self, forKey: .masterDatacenterKeyId)
self.notificationEncryptionKeyId = try container.decodeIfPresent(Data.self, forKey: .notificationEncryptionKeyId)
self.notificationEncryptionKey = try container.decodeIfPresent(Data.self, forKey: .notificationEncryptionKey)
self.additionalDatacenterKeys = try container.decodeIfPresent([Int32: DatacenterKey].self, forKey: .additionalDatacenterKeys) ?? [:]
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.masterDatacenterId, forKey: .masterDatacenterId)
try container.encode(self.peerId, forKey: .peerId)
try container.encode(self.masterDatacenterKey, forKey: .masterDatacenterKey)
try container.encode(self.masterDatacenterKeyId, forKey: .masterDatacenterKeyId)
try container.encodeIfPresent(self.notificationEncryptionKeyId, forKey: .notificationEncryptionKeyId)
try container.encodeIfPresent(self.notificationEncryptionKey, forKey: .notificationEncryptionKey)
try container.encode(self.additionalDatacenterKeys, forKey: .additionalDatacenterKeys)
}
}

View File

@ -10,16 +10,38 @@ private class AdMessagesHistoryContextImpl {
case text
case textEntities
case media
case authorId
case target
case messageId
case startParam
}
enum Target: Equatable, Codable {
enum DecodingError: Error {
case generic
}
enum CodingKeys: String, CodingKey {
case peer
}
case peer(PeerId)
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if let peer = try container.decodeIfPresent(Int64.self, forKey: .peer) {
self = .peer(PeerId(peer))
} else {
throw DecodingError.generic
}
}
}
public let opaqueId: Data
public let text: String
public let textEntities: [MessageTextEntity]
public let media: [Media]
public let authorId: PeerId
public let target: Target
public let messageId: MessageId?
public let startParam: String?
@ -28,7 +50,7 @@ private class AdMessagesHistoryContextImpl {
text: String,
textEntities: [MessageTextEntity],
media: [Media],
authorId: PeerId,
target: Target,
messageId: MessageId?,
startParam: String?
) {
@ -36,7 +58,7 @@ private class AdMessagesHistoryContextImpl {
self.text = text
self.textEntities = textEntities
self.media = media
self.authorId = authorId
self.target = target
self.messageId = messageId
self.startParam = startParam
}
@ -54,7 +76,7 @@ private class AdMessagesHistoryContextImpl {
return PostboxDecoder(buffer: MemoryBuffer(data: data)).decodeRootObject() as? Media
}
self.authorId = try container.decode(PeerId.self, forKey: .authorId)
self.target = try container.decode(Target.self, forKey: .target)
self.messageId = try container.decodeIfPresent(MessageId.self, forKey: .messageId)
self.startParam = try container.decodeIfPresent(String.self, forKey: .startParam)
}
@ -73,7 +95,7 @@ private class AdMessagesHistoryContextImpl {
}
try container.encode(mediaData, forKey: .media)
try container.encode(self.authorId, forKey: .authorId)
try container.encode(self.target, forKey: .target)
try container.encodeIfPresent(self.messageId, forKey: .messageId)
try container.encodeIfPresent(self.startParam, forKey: .startParam)
}
@ -96,7 +118,7 @@ private class AdMessagesHistoryContextImpl {
return false
}
}
if lhs.authorId != rhs.authorId {
if lhs.target != rhs.target {
return false
}
if lhs.messageId != rhs.messageId {
@ -108,7 +130,7 @@ private class AdMessagesHistoryContextImpl {
return true
}
func toMessage(peerId: PeerId, transaction: Transaction) -> Message {
func toMessage(peerId: PeerId, transaction: Transaction) -> Message? {
var attributes: [MessageAttribute] = []
attributes.append(AdMessageAttribute(opaqueId: self.opaqueId, startParam: self.startParam, messageId: self.messageId))
@ -122,9 +144,18 @@ private class AdMessagesHistoryContextImpl {
if let peer = transaction.getPeer(peerId) {
messagePeers[peer.id] = peer
}
if let peer = transaction.getPeer(self.authorId) {
messagePeers[peer.id] = peer
let author: Peer
switch self.target {
case let .peer(peerId):
if let peer = transaction.getPeer(peerId) {
author = peer
} else {
return nil
}
}
messagePeers[author.id] = author
return Message(
stableId: 0,
@ -140,7 +171,7 @@ private class AdMessagesHistoryContextImpl {
globalTags: [],
localTags: [],
forwardInfo: nil,
author: transaction.getPeer(self.authorId),
author: author,
text: self.text,
attributes: attributes,
media: self.media,
@ -270,7 +301,7 @@ private class AdMessagesHistoryContextImpl {
|> mapToSignal { cachedState -> Signal<State, NoError> in
if let cachedState = cachedState, cachedState.timestamp >= Int32(Date().timeIntervalSince1970) - 5 * 60 {
return account.postbox.transaction { transaction -> State in
return State(messages: cachedState.messages.map { message in
return State(messages: cachedState.messages.compactMap { message -> Message? in
return message.toMessage(peerId: peerId, transaction: transaction)
})
}
@ -325,35 +356,42 @@ private class AdMessagesHistoryContextImpl {
for message in messages {
switch message {
case let .sponsoredMessage(_, randomId, fromId, channelPost, startParam, message, entities):
case let .sponsoredMessage(_, randomId, fromId, chatInvite, chatInviteHash, channelPost, startParam, message, entities):
var parsedEntities: [MessageTextEntity] = []
if let entities = entities {
parsedEntities = messageTextEntitiesFromApiEntities(entities)
}
let _ = chatInvite
let _ = chatInviteHash
var target: CachedMessage.Target?
if let fromId = fromId {
target = .peer(fromId.peerId)
}
var messageId: MessageId?
if let fromId = fromId, let channelPost = channelPost {
messageId = MessageId(peerId: fromId.peerId, namespace: Namespaces.Message.Cloud, id: channelPost)
}
let parsedMedia: [Media] = []
/*if let media = media {
let (mediaValue, _) = textMediaAndExpirationTimerFromApiMedia(media, peerId)
if let mediaValue = mediaValue {
parsedMedia.append(mediaValue)
}
}*/
parsedMessages.append(CachedMessage(
opaqueId: randomId.makeData(),
text: message,
textEntities: parsedEntities,
media: parsedMedia,
authorId: fromId.peerId,
messageId: channelPost.flatMap { MessageId(peerId: fromId.peerId, namespace: Namespaces.Message.Cloud, id: $0) },
startParam: startParam
))
if let target = target {
parsedMessages.append(CachedMessage(
opaqueId: randomId.makeData(),
text: message,
textEntities: parsedEntities,
media: [],
target: target,
messageId: messageId,
startParam: startParam
))
}
}
}
CachedState.setCached(transaction: transaction, peerId: peerId, state: CachedState(timestamp: Int32(Date().timeIntervalSince1970), messages: parsedMessages))
return parsedMessages.map { message in
return parsedMessages.compactMap { message -> Message? in
return message.toMessage(peerId: peerId, transaction: transaction)
}
}