Update API [skip ci]

This commit is contained in:
Ilya Laktyushin 2020-02-27 21:26:07 +04:00
parent 8341247b5d
commit d8b99880ea
20 changed files with 116 additions and 32 deletions

View File

@ -106,7 +106,7 @@ public class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchFo
let deviceSpecificEncryptionParameters = BuildConfig.deviceSpecificEncryptionParameters(rootPath, baseAppBundleId: baseAppBundleId) let deviceSpecificEncryptionParameters = BuildConfig.deviceSpecificEncryptionParameters(rootPath, baseAppBundleId: baseAppBundleId)
let encryptionParameters = ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: deviceSpecificEncryptionParameters.key)!, salt: ValueBoxEncryptionParameters.Salt(data: deviceSpecificEncryptionParameters.salt)!) let encryptionParameters = ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: deviceSpecificEncryptionParameters.key)!, salt: ValueBoxEncryptionParameters.Salt(data: deviceSpecificEncryptionParameters.salt)!)
account = currentAccount(allocateIfNotExists: false, networkArguments: NetworkInitializationArguments(apiId: apiId, apiHash: apiHash, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, appData: .single(buildConfig.bundleData(withAppToken: nil, signatureDict: nil)), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider()), supplementary: true, manager: accountManager, rootPath: rootPath, auxiliaryMethods: accountAuxiliaryMethods, encryptionParameters: encryptionParameters) account = currentAccount(allocateIfNotExists: false, networkArguments: NetworkInitializationArguments(apiId: apiId, apiHash: apiHash, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, voipVersions: [], appData: .single(buildConfig.bundleData(withAppToken: nil, signatureDict: nil)), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider()), supplementary: true, manager: accountManager, rootPath: rootPath, auxiliaryMethods: accountAuxiliaryMethods, encryptionParameters: encryptionParameters)
|> mapToSignal { account -> Signal<Account?, NoError> in |> mapToSignal { account -> Signal<Account?, NoError> in
if let account = account { if let account = account {
switch account { switch account {

View File

@ -43,6 +43,7 @@ public struct Namespaces {
public static let CloudMaskPacks: Int32 = 1 public static let CloudMaskPacks: Int32 = 1
public static let EmojiKeywords: Int32 = 2 public static let EmojiKeywords: Int32 = 2
public static let CloudAnimatedEmoji: Int32 = 3 public static let CloudAnimatedEmoji: Int32 = 3
public static let CloudDice: Int32 = 4
} }
public struct OrderedItemList { public struct OrderedItemList {

View File

@ -12,6 +12,7 @@ public enum StickerPackReference: PostboxCoding, Hashable, Equatable {
case id(id: Int64, accessHash: Int64) case id(id: Int64, accessHash: Int64)
case name(String) case name(String)
case animatedEmoji case animatedEmoji
case dice
public init(decoder: PostboxDecoder) { public init(decoder: PostboxDecoder) {
switch decoder.decodeInt32ForKey("r", orElse: 0) { switch decoder.decodeInt32ForKey("r", orElse: 0) {
@ -21,6 +22,8 @@ public enum StickerPackReference: PostboxCoding, Hashable, Equatable {
self = .name(decoder.decodeStringForKey("n", orElse: "")) self = .name(decoder.decodeStringForKey("n", orElse: ""))
case 2: case 2:
self = .animatedEmoji self = .animatedEmoji
case 3:
self = .dice
default: default:
self = .name("") self = .name("")
assertionFailure() assertionFailure()
@ -38,6 +41,8 @@ public enum StickerPackReference: PostboxCoding, Hashable, Equatable {
encoder.encodeString(name, forKey: "n") encoder.encodeString(name, forKey: "n")
case .animatedEmoji: case .animatedEmoji:
encoder.encodeInt32(2, forKey: "r") encoder.encodeInt32(2, forKey: "r")
case .dice:
encoder.encodeInt32(3, forKey: "r")
} }
} }
@ -61,6 +66,12 @@ public enum StickerPackReference: PostboxCoding, Hashable, Equatable {
} else { } else {
return false return false
} }
case .dice:
if case .dice = rhs {
return true
} else {
return false
}
} }
} }
} }

View File

@ -513,7 +513,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1502174430] = { return Api.InputMessage.parse_inputMessageID($0) } dict[-1502174430] = { return Api.InputMessage.parse_inputMessageID($0) }
dict[-1160215659] = { return Api.InputMessage.parse_inputMessageReplyTo($0) } dict[-1160215659] = { return Api.InputMessage.parse_inputMessageReplyTo($0) }
dict[-2037963464] = { return Api.InputMessage.parse_inputMessagePinned($0) } dict[-2037963464] = { return Api.InputMessage.parse_inputMessagePinned($0) }
dict[-1564789301] = { return Api.PhoneCallProtocol.parse_phoneCallProtocol($0) } dict[-58224696] = { return Api.PhoneCallProtocol.parse_phoneCallProtocol($0) }
dict[-1237848657] = { return Api.StatsDateRangeDays.parse_statsDateRangeDays($0) } dict[-1237848657] = { return Api.StatsDateRangeDays.parse_statsDateRangeDays($0) }
dict[-1567175714] = { return Api.MessageFwdAuthor.parse_messageFwdAuthor($0) } dict[-1567175714] = { return Api.MessageFwdAuthor.parse_messageFwdAuthor($0) }
dict[-1539849235] = { return Api.WallPaper.parse_wallPaper($0) } dict[-1539849235] = { return Api.WallPaper.parse_wallPaper($0) }
@ -579,6 +579,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1645763991] = { return Api.InputStickerSet.parse_inputStickerSetID($0) } dict[-1645763991] = { return Api.InputStickerSet.parse_inputStickerSetID($0) }
dict[-2044933984] = { return Api.InputStickerSet.parse_inputStickerSetShortName($0) } dict[-2044933984] = { return Api.InputStickerSet.parse_inputStickerSetShortName($0) }
dict[42402760] = { return Api.InputStickerSet.parse_inputStickerSetAnimatedEmoji($0) } dict[42402760] = { return Api.InputStickerSet.parse_inputStickerSetAnimatedEmoji($0) }
dict[2044861011] = { return Api.InputStickerSet.parse_inputStickerSetDice($0) }
dict[-1729618630] = { return Api.BotInfo.parse_botInfo($0) } dict[-1729618630] = { return Api.BotInfo.parse_botInfo($0) }
dict[-1519637954] = { return Api.updates.State.parse_state($0) } dict[-1519637954] = { return Api.updates.State.parse_state($0) }
dict[372165663] = { return Api.FoundGif.parse_foundGif($0) } dict[372165663] = { return Api.FoundGif.parse_foundGif($0) }

View File

@ -14600,25 +14600,30 @@ public extension Api {
} }
public enum PhoneCallProtocol: TypeConstructorDescription { public enum PhoneCallProtocol: TypeConstructorDescription {
case phoneCallProtocol(flags: Int32, minLayer: Int32, maxLayer: Int32) case phoneCallProtocol(flags: Int32, minLayer: Int32, maxLayer: Int32, libraryVersions: [String])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
case .phoneCallProtocol(let flags, let minLayer, let maxLayer): case .phoneCallProtocol(let flags, let minLayer, let maxLayer, let libraryVersions):
if boxed { if boxed {
buffer.appendInt32(-1564789301) buffer.appendInt32(-58224696)
} }
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(minLayer, buffer: buffer, boxed: false) serializeInt32(minLayer, buffer: buffer, boxed: false)
serializeInt32(maxLayer, buffer: buffer, boxed: false) serializeInt32(maxLayer, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(libraryVersions.count))
for item in libraryVersions {
serializeString(item, buffer: buffer, boxed: false)
}
break break
} }
} }
public func descriptionFields() -> (String, [(String, Any)]) { public func descriptionFields() -> (String, [(String, Any)]) {
switch self { switch self {
case .phoneCallProtocol(let flags, let minLayer, let maxLayer): case .phoneCallProtocol(let flags, let minLayer, let maxLayer, let libraryVersions):
return ("phoneCallProtocol", [("flags", flags), ("minLayer", minLayer), ("maxLayer", maxLayer)]) return ("phoneCallProtocol", [("flags", flags), ("minLayer", minLayer), ("maxLayer", maxLayer), ("libraryVersions", libraryVersions)])
} }
} }
@ -14629,11 +14634,16 @@ public extension Api {
_2 = reader.readInt32() _2 = reader.readInt32()
var _3: Int32? var _3: Int32?
_3 = reader.readInt32() _3 = reader.readInt32()
var _4: [String]?
if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
}
let _c1 = _1 != nil let _c1 = _1 != nil
let _c2 = _2 != nil let _c2 = _2 != nil
let _c3 = _3 != nil let _c3 = _3 != nil
if _c1 && _c2 && _c3 { let _c4 = _4 != nil
return Api.PhoneCallProtocol.phoneCallProtocol(flags: _1!, minLayer: _2!, maxLayer: _3!) if _c1 && _c2 && _c3 && _c4 {
return Api.PhoneCallProtocol.phoneCallProtocol(flags: _1!, minLayer: _2!, maxLayer: _3!, libraryVersions: _4!)
} }
else { else {
return nil return nil
@ -16258,6 +16268,7 @@ public extension Api {
case inputStickerSetID(id: Int64, accessHash: Int64) case inputStickerSetID(id: Int64, accessHash: Int64)
case inputStickerSetShortName(shortName: String) case inputStickerSetShortName(shortName: String)
case inputStickerSetAnimatedEmoji case inputStickerSetAnimatedEmoji
case inputStickerSetDice
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
@ -16285,6 +16296,12 @@ public extension Api {
buffer.appendInt32(42402760) buffer.appendInt32(42402760)
} }
break
case .inputStickerSetDice:
if boxed {
buffer.appendInt32(2044861011)
}
break break
} }
} }
@ -16299,6 +16316,8 @@ public extension Api {
return ("inputStickerSetShortName", [("shortName", shortName)]) return ("inputStickerSetShortName", [("shortName", shortName)])
case .inputStickerSetAnimatedEmoji: case .inputStickerSetAnimatedEmoji:
return ("inputStickerSetAnimatedEmoji", []) return ("inputStickerSetAnimatedEmoji", [])
case .inputStickerSetDice:
return ("inputStickerSetDice", [])
} }
} }
@ -16333,6 +16352,9 @@ public extension Api {
public static func parse_inputStickerSetAnimatedEmoji(_ reader: BufferReader) -> InputStickerSet? { public static func parse_inputStickerSetAnimatedEmoji(_ reader: BufferReader) -> InputStickerSet? {
return Api.InputStickerSet.inputStickerSetAnimatedEmoji return Api.InputStickerSet.inputStickerSetAnimatedEmoji
} }
public static func parse_inputStickerSetDice(_ reader: BufferReader) -> InputStickerSet? {
return Api.InputStickerSet.inputStickerSetDice
}
} }
public enum BotInfo: TypeConstructorDescription { public enum BotInfo: TypeConstructorDescription {

View File

@ -75,6 +75,10 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
return OngoingCallContext.maxLayer return OngoingCallContext.maxLayer
} }
public static var voipVersions: [String] {
return [OngoingCallContext.version]
}
public init(accountManager: AccountManager, getDeviceAccessData: @escaping () -> (presentationData: PresentationData, present: (ViewController, Any?) -> Void, openSettings: () -> Void), isMediaPlaying: @escaping () -> Bool, resumeMediaPlayback: @escaping () -> Void, audioSession: ManagedAudioSession, activeAccounts: Signal<[Account], NoError>) { public init(accountManager: AccountManager, getDeviceAccessData: @escaping () -> (presentationData: PresentationData, present: (ViewController, Any?) -> Void, openSettings: () -> Void), isMediaPlaying: @escaping () -> Bool, resumeMediaPlayback: @escaping () -> Void, audioSession: ManagedAudioSession, activeAccounts: Signal<[Account], NoError>) {
self.getDeviceAccessData = getDeviceAccessData self.getDeviceAccessData = getDeviceAccessData
self.accountManager = accountManager self.accountManager = accountManager

View File

@ -901,7 +901,7 @@ public class Account {
self.supplementary = supplementary self.supplementary = supplementary
self.peerInputActivityManager = PeerInputActivityManager() self.peerInputActivityManager = PeerInputActivityManager()
self.callSessionManager = CallSessionManager(postbox: postbox, network: network, maxLayer: networkArguments.voipMaxLayer, addUpdates: { [weak self] updates in self.callSessionManager = CallSessionManager(postbox: postbox, network: network, maxLayer: networkArguments.voipMaxLayer, versions: networkArguments.voipVersions, addUpdates: { [weak self] updates in
self?.stateManager?.addUpdates(updates) self?.stateManager?.addUpdates(updates)
}) })
self.stateManager = AccountStateManager(accountPeerId: self.peerId, accountManager: accountManager, postbox: self.postbox, network: self.network, callSessionManager: self.callSessionManager, addIsContactUpdates: { [weak self] updates in self.stateManager = AccountStateManager(accountPeerId: self.peerId, accountManager: accountManager, postbox: self.postbox, network: self.network, callSessionManager: self.callSessionManager, addIsContactUpdates: { [weak self] updates in

View File

@ -76,6 +76,20 @@ public func cachedStickerPack(postbox: Postbox, network: Network, reference: Sti
} else { } else {
return (.fetching, true, nil) return (.fetching, true, nil)
} }
case .dice:
let namespace = Namespaces.ItemCollection.CloudDice
let id: ItemCollectionId.Id = 0
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id)))) as? CachedStickerPack, let info = cached.info {
previousHash = cached.hash
let current: CachedStickerPackResult = .result(info, cached.items, false)
if cached.hash != info.hash {
return (current, true, previousHash)
} else {
return (current, true, previousHash)
}
} else {
return (.fetching, true, nil)
}
} }
} }
|> mapToSignal { result, loadRemote, previousHash in |> mapToSignal { result, loadRemote, previousHash in
@ -148,6 +162,18 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id)))) as? CachedStickerPack, let info = cached.info { if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id)))) as? CachedStickerPack, let info = cached.info {
return (info, cached.items, false) return (info, cached.items, false)
} }
case .dice:
let namespace = Namespaces.ItemCollection.CloudDice
let id: ItemCollectionId.Id = 0
if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo {
let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id))
if !items.isEmpty {
return (currentInfo, items, true)
}
}
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id)))) as? CachedStickerPack, let info = cached.info {
return (info, cached.items, false)
}
} }
return nil return nil
} }

View File

@ -4,7 +4,6 @@ import MtProtoKit
import SwiftSignalKit import SwiftSignalKit
import TelegramApi import TelegramApi
import SyncCore import SyncCore
private let minLayer: Int32 = 65 private let minLayer: Int32 = 65
@ -241,6 +240,7 @@ private final class CallSessionManagerContext {
private let postbox: Postbox private let postbox: Postbox
private let network: Network private let network: Network
private let maxLayer: Int32 private let maxLayer: Int32
private let versions: [String]
private let addUpdates: (Api.Updates) -> Void private let addUpdates: (Api.Updates) -> Void
private let ringingSubscribers = Bag<([CallSessionRingingState]) -> Void>() private let ringingSubscribers = Bag<([CallSessionRingingState]) -> Void>()
@ -249,11 +249,12 @@ private final class CallSessionManagerContext {
private let disposables = DisposableSet() private let disposables = DisposableSet()
init(queue: Queue, postbox: Postbox, network: Network, maxLayer: Int32, addUpdates: @escaping (Api.Updates) -> Void) { init(queue: Queue, postbox: Postbox, network: Network, maxLayer: Int32, versions: [String], addUpdates: @escaping (Api.Updates) -> Void) {
self.queue = queue self.queue = queue
self.postbox = postbox self.postbox = postbox
self.network = network self.network = network
self.maxLayer = maxLayer self.maxLayer = maxLayer
self.versions = versions
self.addUpdates = addUpdates self.addUpdates = addUpdates
} }
@ -469,7 +470,7 @@ private final class CallSessionManagerContext {
if let context = self.contexts[internalId] { if let context = self.contexts[internalId] {
switch context.state { switch context.state {
case let .ringing(id, accessHash, gAHash, b): case let .ringing(id, accessHash, gAHash, b):
context.state = .accepting(id: id, accessHash: accessHash, gAHash: gAHash, b: b, disposable: (acceptCallSession(postbox: self.postbox, network: self.network, stableId: id, accessHash: accessHash, b: b, maxLayer: self.maxLayer) |> deliverOn(self.queue)).start(next: { [weak self] result in context.state = .accepting(id: id, accessHash: accessHash, gAHash: gAHash, b: b, disposable: (acceptCallSession(postbox: self.postbox, network: self.network, stableId: id, accessHash: accessHash, b: b, maxLayer: self.maxLayer, versions: self.versions) |> deliverOn(self.queue)).start(next: { [weak self] result in
if let strongSelf = self, let context = strongSelf.contexts[internalId] { if let strongSelf = self, let context = strongSelf.contexts[internalId] {
if case .accepting = context.state { if case .accepting = context.state {
switch result { switch result {
@ -534,7 +535,7 @@ private final class CallSessionManagerContext {
let keyVisualHash = MTSha256(key + gA)! let keyVisualHash = MTSha256(key + gA)!
context.state = .confirming(id: id, accessHash: accessHash, key: key, keyId: keyId, keyVisualHash: keyVisualHash, disposable: (confirmCallSession(network: self.network, stableId: id, accessHash: accessHash, gA: gA, keyFingerprint: keyId, maxLayer: self.maxLayer) |> deliverOnMainQueue).start(next: { [weak self] updatedCall in context.state = .confirming(id: id, accessHash: accessHash, key: key, keyId: keyId, keyVisualHash: keyVisualHash, disposable: (confirmCallSession(network: self.network, stableId: id, accessHash: accessHash, gA: gA, keyFingerprint: keyId, maxLayer: self.maxLayer, versions: self.versions) |> deliverOnMainQueue).start(next: { [weak self] updatedCall in
if let strongSelf = self, let context = strongSelf.contexts[internalId], case .confirming = context.state { if let strongSelf = self, let context = strongSelf.contexts[internalId], case .confirming = context.state {
if let updatedCall = updatedCall { if let updatedCall = updatedCall {
strongSelf.updateSession(updatedCall, completion: { _ in }) strongSelf.updateSession(updatedCall, completion: { _ in })
@ -616,7 +617,7 @@ private final class CallSessionManagerContext {
if let (key, calculatedKeyId, keyVisualHash) = self.makeSessionEncryptionKey(config: config, gAHash: gAHash, b: b, gA: gAOrB.makeData()) { if let (key, calculatedKeyId, keyVisualHash) = self.makeSessionEncryptionKey(config: config, gAHash: gAHash, b: b, gA: gAOrB.makeData()) {
if keyFingerprint == calculatedKeyId { if keyFingerprint == calculatedKeyId {
switch callProtocol { switch callProtocol {
case let .phoneCallProtocol(_, _, maxLayer): case let .phoneCallProtocol(_, _, maxLayer, _):
context.state = .active(id: id, accessHash: accessHash, beginTimestamp: startDate, key: key, keyId: calculatedKeyId, keyVisualHash: keyVisualHash, connections: parseConnectionSet(primary: connections.first!, alternative: Array(connections[1...])), maxLayer: maxLayer, allowsP2P: allowsP2P) context.state = .active(id: id, accessHash: accessHash, beginTimestamp: startDate, key: key, keyId: calculatedKeyId, keyVisualHash: keyVisualHash, connections: parseConnectionSet(primary: connections.first!, alternative: Array(connections[1...])), maxLayer: maxLayer, allowsP2P: allowsP2P)
self.contextUpdated(internalId: internalId) self.contextUpdated(internalId: internalId)
} }
@ -628,7 +629,7 @@ private final class CallSessionManagerContext {
} }
case let .confirming(id, accessHash, key, keyId, keyVisualHash, _): case let .confirming(id, accessHash, key, keyId, keyVisualHash, _):
switch callProtocol { switch callProtocol {
case let .phoneCallProtocol(_, _, maxLayer): case let .phoneCallProtocol(_, _, maxLayer, _):
context.state = .active(id: id, accessHash: accessHash, beginTimestamp: startDate, key: key, keyId: keyId, keyVisualHash: keyVisualHash, connections: parseConnectionSet(primary: connections.first!, alternative: Array(connections[1...])), maxLayer: maxLayer, allowsP2P: allowsP2P) context.state = .active(id: id, accessHash: accessHash, beginTimestamp: startDate, key: key, keyId: keyId, keyVisualHash: keyVisualHash, connections: parseConnectionSet(primary: connections.first!, alternative: Array(connections[1...])), maxLayer: maxLayer, allowsP2P: allowsP2P)
self.contextUpdated(internalId: internalId) self.contextUpdated(internalId: internalId)
} }
@ -709,7 +710,7 @@ private final class CallSessionManagerContext {
let randomStatus = SecRandomCopyBytes(nil, 256, aBytes.assumingMemoryBound(to: UInt8.self)) let randomStatus = SecRandomCopyBytes(nil, 256, aBytes.assumingMemoryBound(to: UInt8.self))
let a = Data(bytesNoCopy: aBytes, count: 256, deallocator: .free) let a = Data(bytesNoCopy: aBytes, count: 256, deallocator: .free)
if randomStatus == 0 { if randomStatus == 0 {
self.contexts[internalId] = CallSessionContext(peerId: peerId, isOutgoing: true, state: .requesting(a: a, disposable: (requestCallSession(postbox: self.postbox, network: self.network, peerId: peerId, a: a, maxLayer: self.maxLayer) |> deliverOn(queue)).start(next: { [weak self] result in self.contexts[internalId] = CallSessionContext(peerId: peerId, isOutgoing: true, state: .requesting(a: a, disposable: (requestCallSession(postbox: self.postbox, network: self.network, peerId: peerId, a: a, maxLayer: self.maxLayer, versions: self.versions) |> deliverOn(queue)).start(next: { [weak self] result in
if let strongSelf = self, let context = strongSelf.contexts[internalId] { if let strongSelf = self, let context = strongSelf.contexts[internalId] {
if case .requesting = context.state { if case .requesting = context.state {
switch result { switch result {
@ -743,9 +744,9 @@ public final class CallSessionManager {
private let queue = Queue() private let queue = Queue()
private var contextRef: Unmanaged<CallSessionManagerContext>? private var contextRef: Unmanaged<CallSessionManagerContext>?
init(postbox: Postbox, network: Network, maxLayer: Int32, addUpdates: @escaping (Api.Updates) -> Void) { init(postbox: Postbox, network: Network, maxLayer: Int32, versions: [String], addUpdates: @escaping (Api.Updates) -> Void) {
self.queue.async { self.queue.async {
let context = CallSessionManagerContext(queue: self.queue, postbox: postbox, network: network, maxLayer: maxLayer, addUpdates: addUpdates) let context = CallSessionManagerContext(queue: self.queue, postbox: postbox, network: network, maxLayer: maxLayer, versions: versions, addUpdates: addUpdates)
self.contextRef = Unmanaged.passRetained(context) self.contextRef = Unmanaged.passRetained(context)
} }
} }
@ -846,7 +847,7 @@ private enum AcceptCallResult {
case success(AcceptedCall) case success(AcceptedCall)
} }
private func acceptCallSession(postbox: Postbox, network: Network, stableId: CallSessionStableId, accessHash: Int64, b: Data, maxLayer: Int32) -> Signal<AcceptCallResult, NoError> { private func acceptCallSession(postbox: Postbox, network: Network, stableId: CallSessionStableId, accessHash: Int64, b: Data, maxLayer: Int32, versions: [String]) -> Signal<AcceptCallResult, NoError> {
return validatedEncryptionConfig(postbox: postbox, network: network) return validatedEncryptionConfig(postbox: postbox, network: network)
|> mapToSignal { config -> Signal<AcceptCallResult, NoError> in |> mapToSignal { config -> Signal<AcceptCallResult, NoError> in
var gValue: Int32 = config.g.byteSwapped var gValue: Int32 = config.g.byteSwapped
@ -861,7 +862,7 @@ private func acceptCallSession(postbox: Postbox, network: Network, stableId: Cal
return .single(.failed) return .single(.failed)
} }
return network.request(Api.functions.phone.acceptCall(peer: .inputPhoneCall(id: stableId, accessHash: accessHash), gB: Buffer(data: gb), protocol: .phoneCallProtocol(flags: (1 << 0) | (1 << 1), minLayer: minLayer, maxLayer: maxLayer))) return network.request(Api.functions.phone.acceptCall(peer: .inputPhoneCall(id: stableId, accessHash: accessHash), gB: Buffer(data: gb), protocol: .phoneCallProtocol(flags: (1 << 0) | (1 << 1), minLayer: minLayer, maxLayer: maxLayer, libraryVersions: versions)))
|> map(Optional.init) |> map(Optional.init)
|> `catch` { _ -> Signal<Api.phone.PhoneCall?, NoError> in |> `catch` { _ -> Signal<Api.phone.PhoneCall?, NoError> in
return .single(nil) return .single(nil)
@ -887,7 +888,7 @@ private func acceptCallSession(postbox: Postbox, network: Network, stableId: Cal
case let .phoneCall(flags, id, _, _, _, _, gAOrB, _, callProtocol, connections, startDate): case let .phoneCall(flags, id, _, _, _, _, gAOrB, _, callProtocol, connections, startDate):
if id == stableId { if id == stableId {
switch callProtocol{ switch callProtocol{
case let .phoneCallProtocol(_, _, maxLayer): case let .phoneCallProtocol(_, _, maxLayer, _):
return .success(.call(config: config, gA: gAOrB.makeData(), timestamp: startDate, connections: parseConnectionSet(primary: connections.first!, alternative: Array(connections[1...])), maxLayer: maxLayer, allowsP2P: (flags & (1 << 5)) != 0)) return .success(.call(config: config, gA: gAOrB.makeData(), timestamp: startDate, connections: parseConnectionSet(primary: connections.first!, alternative: Array(connections[1...])), maxLayer: maxLayer, allowsP2P: (flags & (1 << 5)) != 0))
} }
} else { } else {
@ -908,7 +909,7 @@ private enum RequestCallSessionResult {
case failed(CallSessionError) case failed(CallSessionError)
} }
private func requestCallSession(postbox: Postbox, network: Network, peerId: PeerId, a: Data, maxLayer: Int32) -> Signal<RequestCallSessionResult, NoError> { private func requestCallSession(postbox: Postbox, network: Network, peerId: PeerId, a: Data, maxLayer: Int32, versions: [String]) -> Signal<RequestCallSessionResult, NoError> {
return validatedEncryptionConfig(postbox: postbox, network: network) return validatedEncryptionConfig(postbox: postbox, network: network)
|> mapToSignal { config -> Signal<RequestCallSessionResult, NoError> in |> mapToSignal { config -> Signal<RequestCallSessionResult, NoError> in
return postbox.transaction { transaction -> Signal<RequestCallSessionResult, NoError> in return postbox.transaction { transaction -> Signal<RequestCallSessionResult, NoError> in
@ -924,7 +925,7 @@ private func requestCallSession(postbox: Postbox, network: Network, peerId: Peer
let gAHash = MTSha256(ga)! let gAHash = MTSha256(ga)!
return network.request(Api.functions.phone.requestCall(flags: 0, userId: inputUser, randomId: Int32(bitPattern: arc4random()), gAHash: Buffer(data: gAHash), protocol: .phoneCallProtocol(flags: (1 << 0) | (1 << 1), minLayer: minLayer, maxLayer: maxLayer))) return network.request(Api.functions.phone.requestCall(flags: 0, userId: inputUser, randomId: Int32(bitPattern: arc4random()), gAHash: Buffer(data: gAHash), protocol: .phoneCallProtocol(flags: (1 << 0) | (1 << 1), minLayer: minLayer, maxLayer: maxLayer, libraryVersions: versions)))
|> map { result -> RequestCallSessionResult in |> map { result -> RequestCallSessionResult in
switch result { switch result {
case let .phoneCall(phoneCall, _): case let .phoneCall(phoneCall, _):
@ -960,8 +961,8 @@ private func requestCallSession(postbox: Postbox, network: Network, peerId: Peer
} }
} }
private func confirmCallSession(network: Network, stableId: CallSessionStableId, accessHash: Int64, gA: Data, keyFingerprint: Int64, maxLayer: Int32) -> Signal<Api.PhoneCall?, NoError> { private func confirmCallSession(network: Network, stableId: CallSessionStableId, accessHash: Int64, gA: Data, keyFingerprint: Int64, maxLayer: Int32, versions: [String]) -> Signal<Api.PhoneCall?, NoError> {
return network.request(Api.functions.phone.confirmCall(peer: Api.InputPhoneCall.inputPhoneCall(id: stableId, accessHash: accessHash), gA: Buffer(data: gA), keyFingerprint: keyFingerprint, protocol: .phoneCallProtocol(flags: (1 << 0) | (1 << 1), minLayer: minLayer, maxLayer: maxLayer))) return network.request(Api.functions.phone.confirmCall(peer: Api.InputPhoneCall.inputPhoneCall(id: stableId, accessHash: accessHash), gA: Buffer(data: gA), keyFingerprint: keyFingerprint, protocol: .phoneCallProtocol(flags: (1 << 0) | (1 << 1), minLayer: minLayer, maxLayer: maxLayer, libraryVersions: versions)))
|> map(Optional.init) |> map(Optional.init)
|> `catch` { _ -> Signal<Api.phone.PhoneCall?, NoError> in |> `catch` { _ -> Signal<Api.phone.PhoneCall?, NoError> in
return .single(nil) return .single(nil)

View File

@ -18,6 +18,8 @@ extension StickerPackReference {
return .inputStickerSetShortName(shortName: name) return .inputStickerSetShortName(shortName: name)
case .animatedEmoji: case .animatedEmoji:
return .inputStickerSetAnimatedEmoji return .inputStickerSetAnimatedEmoji
case .dice:
return .inputStickerSetDice
} }
} }
} }

View File

@ -403,16 +403,18 @@ public struct NetworkInitializationArguments {
public let languagesCategory: String public let languagesCategory: String
public let appVersion: String public let appVersion: String
public let voipMaxLayer: Int32 public let voipMaxLayer: Int32
public let voipVersions: [String]
public let appData: Signal<Data?, NoError> public let appData: Signal<Data?, NoError>
public let autolockDeadine: Signal<Int32?, NoError> public let autolockDeadine: Signal<Int32?, NoError>
public let encryptionProvider: EncryptionProvider public let encryptionProvider: EncryptionProvider
public init(apiId: Int32, apiHash: String, languagesCategory: String, appVersion: String, voipMaxLayer: Int32, appData: Signal<Data?, NoError>, autolockDeadine: Signal<Int32?, NoError>, encryptionProvider: EncryptionProvider) { public init(apiId: Int32, apiHash: String, languagesCategory: String, appVersion: String, voipMaxLayer: Int32, voipVersions: [String], appData: Signal<Data?, NoError>, autolockDeadine: Signal<Int32?, NoError>, encryptionProvider: EncryptionProvider) {
self.apiId = apiId self.apiId = apiId
self.apiHash = apiHash self.apiHash = apiHash
self.languagesCategory = languagesCategory self.languagesCategory = languagesCategory
self.appVersion = appVersion self.appVersion = appVersion
self.voipMaxLayer = voipMaxLayer self.voipMaxLayer = voipMaxLayer
self.voipVersions = voipVersions
self.appData = appData self.appData = appData
self.autolockDeadine = autolockDeadine self.autolockDeadine = autolockDeadine
self.encryptionProvider = encryptionProvider self.encryptionProvider = encryptionProvider

View File

@ -38,6 +38,9 @@ public func requestStickerSet(postbox: Postbox, network: Network, reference: Sti
case .animatedEmoji: case .animatedEmoji:
collectionId = nil collectionId = nil
input = .inputStickerSetAnimatedEmoji input = .inputStickerSetAnimatedEmoji
case .dice:
collectionId = nil
input = .inputStickerSetDice
} }
let localSignal: (ItemCollectionId) -> Signal<(ItemCollectionInfo, [ItemCollectionItem])?, NoError> = { collectionId in let localSignal: (ItemCollectionId) -> Signal<(ItemCollectionInfo, [ItemCollectionItem])?, NoError> = { collectionId in

View File

@ -62,7 +62,7 @@ public func addSavedSticker(postbox: Postbox, network: Network, file: TelegramMe
if !found { if !found {
fetchReference = packReference fetchReference = packReference
} }
case .animatedEmoji: case .animatedEmoji, .dice:
break break
} }
if let fetchReference = fetchReference { if let fetchReference = fetchReference {

View File

@ -59,6 +59,8 @@ extension StickerPackReference {
self = .name(shortName) self = .name(shortName)
case .inputStickerSetAnimatedEmoji: case .inputStickerSetAnimatedEmoji:
self = .animatedEmoji self = .animatedEmoji
case .inputStickerSetDice:
self = .dice
} }
} }
} }

View File

@ -393,7 +393,7 @@ final class SharedApplicationContext {
} }
} }
let networkArguments = NetworkInitializationArguments(apiId: apiId, apiHash: apiHash, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: PresentationCallManagerImpl.voipMaxLayer, appData: self.deviceToken.get() let networkArguments = NetworkInitializationArguments(apiId: apiId, apiHash: apiHash, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: PresentationCallManagerImpl.voipMaxLayer, voipVersions: PresentationCallManagerImpl.voipVersions, appData: self.deviceToken.get()
|> map { token in |> map { token in
let data = buildConfig.bundleData(withAppToken: token, signatureDict: signatureDict) let data = buildConfig.bundleData(withAppToken: token, signatureDict: signatureDict)
if let data = data, let jsonString = String(data: data, encoding: .utf8) { if let data = data, let jsonString = String(data: data, encoding: .utf8) {

View File

@ -154,7 +154,7 @@ public final class NotificationViewControllerImpl {
return nil return nil
}) })
sharedAccountContext = SharedAccountContextImpl(mainWindow: nil, basePath: rootPath, encryptionParameters: ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: self.initializationData.encryptionParameters.0)!, salt: ValueBoxEncryptionParameters.Salt(data: self.initializationData.encryptionParameters.1)!), accountManager: accountManager, appLockContext: appLockContext, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: self.initializationData.apiId, apiHash: self.initializationData.apiHash, languagesCategory: self.initializationData.languagesCategory, appVersion: self.initializationData.appVersion, voipMaxLayer: 0, appData: .single(self.initializationData.bundleData), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider()), rootPath: rootPath, legacyBasePath: nil, legacyCache: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in }) sharedAccountContext = SharedAccountContextImpl(mainWindow: nil, basePath: rootPath, encryptionParameters: ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: self.initializationData.encryptionParameters.0)!, salt: ValueBoxEncryptionParameters.Salt(data: self.initializationData.encryptionParameters.1)!), accountManager: accountManager, appLockContext: appLockContext, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: self.initializationData.apiId, apiHash: self.initializationData.apiHash, languagesCategory: self.initializationData.languagesCategory, appVersion: self.initializationData.appVersion, voipMaxLayer: 0, voipVersions: [], appData: .single(self.initializationData.bundleData), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider()), rootPath: rootPath, legacyBasePath: nil, legacyCache: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in })
presentationDataPromise.set(sharedAccountContext!.presentationData) presentationDataPromise.set(sharedAccountContext!.presentationData)
} }

View File

@ -192,7 +192,7 @@ public class ShareRootControllerImpl {
return nil return nil
}) })
let sharedContext = SharedAccountContextImpl(mainWindow: nil, basePath: rootPath, encryptionParameters: ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: self.initializationData.encryptionParameters.0)!, salt: ValueBoxEncryptionParameters.Salt(data: self.initializationData.encryptionParameters.1)!), accountManager: accountManager, appLockContext: appLockContext, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: self.initializationData.apiId, apiHash: self.initializationData.apiHash, languagesCategory: self.initializationData.languagesCategory, appVersion: self.initializationData.appVersion, voipMaxLayer: 0, appData: .single(self.initializationData.bundleData), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider()), rootPath: rootPath, legacyBasePath: nil, legacyCache: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in }) let sharedContext = SharedAccountContextImpl(mainWindow: nil, basePath: rootPath, encryptionParameters: ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: self.initializationData.encryptionParameters.0)!, salt: ValueBoxEncryptionParameters.Salt(data: self.initializationData.encryptionParameters.1)!), accountManager: accountManager, appLockContext: appLockContext, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: self.initializationData.apiId, apiHash: self.initializationData.apiHash, languagesCategory: self.initializationData.languagesCategory, appVersion: self.initializationData.appVersion, voipMaxLayer: 0, voipVersions: [], appData: .single(self.initializationData.bundleData), autolockDeadine: .single(nil), encryptionProvider: OpenSSLEncryptionProvider()), rootPath: rootPath, legacyBasePath: nil, legacyCache: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in })
presentationDataPromise.set(sharedContext.presentationData) presentationDataPromise.set(sharedContext.presentationData)
internalContext = InternalContext(sharedContext: sharedContext) internalContext = InternalContext(sharedContext: sharedContext)
globalInternalContext = internalContext globalInternalContext = internalContext

View File

@ -173,6 +173,10 @@ public final class OngoingCallContext {
return OngoingCallThreadLocalContext.maxLayer() return OngoingCallThreadLocalContext.maxLayer()
} }
public static var version: String {
return OngoingCallThreadLocalContext.version()!
}
public init(account: Account, callSessionManager: CallSessionManager, internalId: CallSessionInternalId, proxyServer: ProxyServerSettings?, initialNetworkType: NetworkType, updatedNetworkType: Signal<NetworkType, NoError>, serializedData: String?, dataSaving: VoiceCallDataSaving, derivedState: VoipDerivedState) { public init(account: Account, callSessionManager: CallSessionManager, internalId: CallSessionInternalId, proxyServer: ProxyServerSettings?, initialNetworkType: NetworkType, updatedNetworkType: Signal<NetworkType, NoError>, serializedData: String?, dataSaving: VoiceCallDataSaving, derivedState: VoipDerivedState) {
let _ = setupLogs let _ = setupLogs
OngoingCallThreadLocalContext.applyServerConfig(serializedData) OngoingCallThreadLocalContext.applyServerConfig(serializedData)

View File

@ -59,6 +59,7 @@ typedef NS_ENUM(int32_t, OngoingCallDataSaving) {
+ (void)setupLoggingFunction:(void (* _Nullable)(NSString * _Nullable))loggingFunction; + (void)setupLoggingFunction:(void (* _Nullable)(NSString * _Nullable))loggingFunction;
+ (void)applyServerConfig:(NSString * _Nullable)data; + (void)applyServerConfig:(NSString * _Nullable)data;
+ (int32_t)maxLayer; + (int32_t)maxLayer;
+ (NSString *)version;
@property (nonatomic, copy) void (^ _Nullable stateChanged)(OngoingCallState); @property (nonatomic, copy) void (^ _Nullable stateChanged)(OngoingCallState);
@property (nonatomic, copy) void (^ _Nullable signalBarsChanged)(int32_t); @property (nonatomic, copy) void (^ _Nullable signalBarsChanged)(int32_t);

View File

@ -218,6 +218,10 @@ static int callControllerDataSavingForType(OngoingCallDataSaving type) {
return tgvoip::VoIPController::GetConnectionMaxLayer(); return tgvoip::VoIPController::GetConnectionMaxLayer();
} }
+ (NSString *)version {
return [NSString stringWithUTF8String:tgvoip::VoIPController::GetVersion()];
}
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueue> _Nonnull)queue proxy:(VoipProxyServer * _Nullable)proxy networkType:(OngoingCallNetworkType)networkType dataSaving:(OngoingCallDataSaving)dataSaving derivedState:(NSData * _Nonnull)derivedState { - (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueue> _Nonnull)queue proxy:(VoipProxyServer * _Nullable)proxy networkType:(OngoingCallNetworkType)networkType dataSaving:(OngoingCallDataSaving)dataSaving derivedState:(NSData * _Nonnull)derivedState {
self = [super init]; self = [super init];
if (self != nil) { if (self != nil) {