diff --git a/submodules/TelegramApi/Sources/SecretApiLayer101.swift b/submodules/TelegramApi/Sources/SecretApiLayer101.swift new file mode 100644 index 0000000000..4c870f3f02 --- /dev/null +++ b/submodules/TelegramApi/Sources/SecretApiLayer101.swift @@ -0,0 +1,1581 @@ + +fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { + var dict: [Int32 : (BufferReader) -> Any?] = [:] + dict[-1471112230] = { return $0.readInt32() } + dict[570911930] = { return $0.readInt64() } + dict[571523412] = { return $0.readDouble() } + dict[-1255641564] = { return parseString($0) } + dict[-1586283796] = { return SecretApi101.DecryptedMessageAction.parse_decryptedMessageActionSetMessageTTL($0) } + dict[206520510] = { return SecretApi101.DecryptedMessageAction.parse_decryptedMessageActionReadMessages($0) } + dict[1700872964] = { return SecretApi101.DecryptedMessageAction.parse_decryptedMessageActionDeleteMessages($0) } + dict[-1967000459] = { return SecretApi101.DecryptedMessageAction.parse_decryptedMessageActionScreenshotMessages($0) } + dict[1729750108] = { return SecretApi101.DecryptedMessageAction.parse_decryptedMessageActionFlushHistory($0) } + dict[-217806717] = { return SecretApi101.DecryptedMessageAction.parse_decryptedMessageActionNotifyLayer($0) } + dict[1360072880] = { return SecretApi101.DecryptedMessageAction.parse_decryptedMessageActionResend($0) } + dict[-204906213] = { return SecretApi101.DecryptedMessageAction.parse_decryptedMessageActionRequestKey($0) } + dict[1877046107] = { return SecretApi101.DecryptedMessageAction.parse_decryptedMessageActionAcceptKey($0) } + dict[-586814357] = { return SecretApi101.DecryptedMessageAction.parse_decryptedMessageActionAbortKey($0) } + dict[-332526693] = { return SecretApi101.DecryptedMessageAction.parse_decryptedMessageActionCommitKey($0) } + dict[-1473258141] = { return SecretApi101.DecryptedMessageAction.parse_decryptedMessageActionNoop($0) } + dict[236446268] = { return SecretApi101.PhotoSize.parse_photoSizeEmpty($0) } + dict[2009052699] = { return SecretApi101.PhotoSize.parse_photoSize($0) } + dict[-374917894] = { return SecretApi101.PhotoSize.parse_photoCachedSize($0) } + dict[2086234950] = { return SecretApi101.FileLocation.parse_fileLocationUnavailable($0) } + dict[1406570614] = { return SecretApi101.FileLocation.parse_fileLocation($0) } + dict[467867529] = { return SecretApi101.DecryptedMessageLayer.parse_decryptedMessageLayer($0) } + dict[1930838368] = { return SecretApi101.DecryptedMessage.parse_decryptedMessageService($0) } + dict[-1848883596] = { return SecretApi101.DecryptedMessage.parse_decryptedMessage($0) } + dict[1815593308] = { return SecretApi101.DocumentAttribute.parse_documentAttributeImageSize($0) } + dict[297109817] = { return SecretApi101.DocumentAttribute.parse_documentAttributeAnimated($0) } + dict[358154344] = { return SecretApi101.DocumentAttribute.parse_documentAttributeFilename($0) } + dict[978674434] = { return SecretApi101.DocumentAttribute.parse_documentAttributeSticker($0) } + dict[-1739392570] = { return SecretApi101.DocumentAttribute.parse_documentAttributeAudio($0) } + dict[250621158] = { return SecretApi101.DocumentAttribute.parse_documentAttributeVideo($0) } + dict[-2044933984] = { return SecretApi101.InputStickerSet.parse_inputStickerSetShortName($0) } + dict[-4838507] = { return SecretApi101.InputStickerSet.parse_inputStickerSetEmpty($0) } + dict[-1148011883] = { return SecretApi101.MessageEntity.parse_messageEntityUnknown($0) } + dict[-100378723] = { return SecretApi101.MessageEntity.parse_messageEntityMention($0) } + dict[1868782349] = { return SecretApi101.MessageEntity.parse_messageEntityHashtag($0) } + dict[1827637959] = { return SecretApi101.MessageEntity.parse_messageEntityBotCommand($0) } + dict[1859134776] = { return SecretApi101.MessageEntity.parse_messageEntityUrl($0) } + dict[1692693954] = { return SecretApi101.MessageEntity.parse_messageEntityEmail($0) } + dict[-1117713463] = { return SecretApi101.MessageEntity.parse_messageEntityBold($0) } + dict[-2106619040] = { return SecretApi101.MessageEntity.parse_messageEntityItalic($0) } + dict[681706865] = { return SecretApi101.MessageEntity.parse_messageEntityCode($0) } + dict[1938967520] = { return SecretApi101.MessageEntity.parse_messageEntityPre($0) } + dict[1990644519] = { return SecretApi101.MessageEntity.parse_messageEntityTextUrl($0) } + dict[-1672577397] = { return SecretApi101.MessageEntity.parse_messageEntityUnderline($0) } + dict[-1090087980] = { return SecretApi101.MessageEntity.parse_messageEntityStrike($0) } + dict[34469328] = { return SecretApi101.MessageEntity.parse_messageEntityBlockquote($0) } + dict[144661578] = { return SecretApi101.DecryptedMessageMedia.parse_decryptedMessageMediaEmpty($0) } + dict[893913689] = { return SecretApi101.DecryptedMessageMedia.parse_decryptedMessageMediaGeoPoint($0) } + dict[1485441687] = { return SecretApi101.DecryptedMessageMedia.parse_decryptedMessageMediaContact($0) } + dict[1474341323] = { return SecretApi101.DecryptedMessageMedia.parse_decryptedMessageMediaAudio($0) } + dict[-90853155] = { return SecretApi101.DecryptedMessageMedia.parse_decryptedMessageMediaExternalDocument($0) } + dict[-235238024] = { return SecretApi101.DecryptedMessageMedia.parse_decryptedMessageMediaPhoto($0) } + dict[2063502050] = { return SecretApi101.DecryptedMessageMedia.parse_decryptedMessageMediaDocument($0) } + dict[-1760785394] = { return SecretApi101.DecryptedMessageMedia.parse_decryptedMessageMediaVideo($0) } + dict[-1978796689] = { return SecretApi101.DecryptedMessageMedia.parse_decryptedMessageMediaVenue($0) } + dict[-452652584] = { return SecretApi101.DecryptedMessageMedia.parse_decryptedMessageMediaWebPage($0) } + return dict +}() + +public struct SecretApi101 { + public static func parse(_ buffer: Buffer) -> Any? { + let reader = BufferReader(buffer) + if let signature = reader.readInt32() { + return parse(reader, signature: signature) + } + return nil + } + + fileprivate static func parse(_ reader: BufferReader, signature: Int32) -> Any? { + if let parser = parsers[signature] { + return parser(reader) + } + else { + telegramApiLog("Type constructor \(String(signature, radix: 16, uppercase: false)) not found") + return nil + } + } + + fileprivate static func parseVector(_ reader: BufferReader, elementSignature: Int32, elementType: T.Type) -> [T]? { + if let count = reader.readInt32() { + var array = [T]() + var i: Int32 = 0 + while i < count { + var signature = elementSignature + if elementSignature == 0 { + if let unboxedSignature = reader.readInt32() { + signature = unboxedSignature + } + else { + return nil + } + } + if let item = SecretApi101.parse(reader, signature: signature) as? T { + array.append(item) + } + else { + return nil + } + i += 1 + } + return array + } + return nil + } + + public static func serializeObject(_ object: Any, buffer: Buffer, boxed: Swift.Bool) { + switch object { + case let _1 as SecretApi101.DecryptedMessageAction: + _1.serialize(buffer, boxed) + case let _1 as SecretApi101.PhotoSize: + _1.serialize(buffer, boxed) + case let _1 as SecretApi101.FileLocation: + _1.serialize(buffer, boxed) + case let _1 as SecretApi101.DecryptedMessageLayer: + _1.serialize(buffer, boxed) + case let _1 as SecretApi101.DecryptedMessage: + _1.serialize(buffer, boxed) + case let _1 as SecretApi101.DocumentAttribute: + _1.serialize(buffer, boxed) + case let _1 as SecretApi101.InputStickerSet: + _1.serialize(buffer, boxed) + case let _1 as SecretApi101.MessageEntity: + _1.serialize(buffer, boxed) + case let _1 as SecretApi101.DecryptedMessageMedia: + _1.serialize(buffer, boxed) + default: + break + } + } + + public enum DecryptedMessageAction { + case decryptedMessageActionSetMessageTTL(ttlSeconds: Int32) + case decryptedMessageActionReadMessages(randomIds: [Int64]) + case decryptedMessageActionDeleteMessages(randomIds: [Int64]) + case decryptedMessageActionScreenshotMessages(randomIds: [Int64]) + case decryptedMessageActionFlushHistory + case decryptedMessageActionNotifyLayer(layer: Int32) + case decryptedMessageActionResend(startSeqNo: Int32, endSeqNo: Int32) + case decryptedMessageActionRequestKey(exchangeId: Int64, gA: Buffer) + case decryptedMessageActionAcceptKey(exchangeId: Int64, gB: Buffer, keyFingerprint: Int64) + case decryptedMessageActionAbortKey(exchangeId: Int64) + case decryptedMessageActionCommitKey(exchangeId: Int64, keyFingerprint: Int64) + case decryptedMessageActionNoop + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .decryptedMessageActionSetMessageTTL(let ttlSeconds): + if boxed { + buffer.appendInt32(-1586283796) + } + serializeInt32(ttlSeconds, buffer: buffer, boxed: false) + break + case .decryptedMessageActionReadMessages(let randomIds): + if boxed { + buffer.appendInt32(206520510) + } + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(randomIds.count)) + for item in randomIds { + serializeInt64(item, buffer: buffer, boxed: false) + } + break + case .decryptedMessageActionDeleteMessages(let randomIds): + if boxed { + buffer.appendInt32(1700872964) + } + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(randomIds.count)) + for item in randomIds { + serializeInt64(item, buffer: buffer, boxed: false) + } + break + case .decryptedMessageActionScreenshotMessages(let randomIds): + if boxed { + buffer.appendInt32(-1967000459) + } + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(randomIds.count)) + for item in randomIds { + serializeInt64(item, buffer: buffer, boxed: false) + } + break + case .decryptedMessageActionFlushHistory: + if boxed { + buffer.appendInt32(1729750108) + } + + break + case .decryptedMessageActionNotifyLayer(let layer): + if boxed { + buffer.appendInt32(-217806717) + } + serializeInt32(layer, buffer: buffer, boxed: false) + break + case .decryptedMessageActionResend(let startSeqNo, let endSeqNo): + if boxed { + buffer.appendInt32(1360072880) + } + serializeInt32(startSeqNo, buffer: buffer, boxed: false) + serializeInt32(endSeqNo, buffer: buffer, boxed: false) + break + case .decryptedMessageActionRequestKey(let exchangeId, let gA): + if boxed { + buffer.appendInt32(-204906213) + } + serializeInt64(exchangeId, buffer: buffer, boxed: false) + serializeBytes(gA, buffer: buffer, boxed: false) + break + case .decryptedMessageActionAcceptKey(let exchangeId, let gB, let keyFingerprint): + if boxed { + buffer.appendInt32(1877046107) + } + serializeInt64(exchangeId, buffer: buffer, boxed: false) + serializeBytes(gB, buffer: buffer, boxed: false) + serializeInt64(keyFingerprint, buffer: buffer, boxed: false) + break + case .decryptedMessageActionAbortKey(let exchangeId): + if boxed { + buffer.appendInt32(-586814357) + } + serializeInt64(exchangeId, buffer: buffer, boxed: false) + break + case .decryptedMessageActionCommitKey(let exchangeId, let keyFingerprint): + if boxed { + buffer.appendInt32(-332526693) + } + serializeInt64(exchangeId, buffer: buffer, boxed: false) + serializeInt64(keyFingerprint, buffer: buffer, boxed: false) + break + case .decryptedMessageActionNoop: + if boxed { + buffer.appendInt32(-1473258141) + } + + break + } + } + fileprivate static func parse_decryptedMessageActionSetMessageTTL(_ reader: BufferReader) -> DecryptedMessageAction? { + var _1: Int32? + _1 = reader.readInt32() + let _c1 = _1 != nil + if _c1 { + return SecretApi101.DecryptedMessageAction.decryptedMessageActionSetMessageTTL(ttlSeconds: _1!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageActionReadMessages(_ reader: BufferReader) -> DecryptedMessageAction? { + var _1: [Int64]? + if let _ = reader.readInt32() { + _1 = SecretApi101.parseVector(reader, elementSignature: 570911930, elementType: Int64.self) + } + let _c1 = _1 != nil + if _c1 { + return SecretApi101.DecryptedMessageAction.decryptedMessageActionReadMessages(randomIds: _1!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageActionDeleteMessages(_ reader: BufferReader) -> DecryptedMessageAction? { + var _1: [Int64]? + if let _ = reader.readInt32() { + _1 = SecretApi101.parseVector(reader, elementSignature: 570911930, elementType: Int64.self) + } + let _c1 = _1 != nil + if _c1 { + return SecretApi101.DecryptedMessageAction.decryptedMessageActionDeleteMessages(randomIds: _1!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageActionScreenshotMessages(_ reader: BufferReader) -> DecryptedMessageAction? { + var _1: [Int64]? + if let _ = reader.readInt32() { + _1 = SecretApi101.parseVector(reader, elementSignature: 570911930, elementType: Int64.self) + } + let _c1 = _1 != nil + if _c1 { + return SecretApi101.DecryptedMessageAction.decryptedMessageActionScreenshotMessages(randomIds: _1!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageActionFlushHistory(_ reader: BufferReader) -> DecryptedMessageAction? { + return SecretApi101.DecryptedMessageAction.decryptedMessageActionFlushHistory + } + fileprivate static func parse_decryptedMessageActionNotifyLayer(_ reader: BufferReader) -> DecryptedMessageAction? { + var _1: Int32? + _1 = reader.readInt32() + let _c1 = _1 != nil + if _c1 { + return SecretApi101.DecryptedMessageAction.decryptedMessageActionNotifyLayer(layer: _1!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageActionResend(_ reader: BufferReader) -> DecryptedMessageAction? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.DecryptedMessageAction.decryptedMessageActionResend(startSeqNo: _1!, endSeqNo: _2!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageActionRequestKey(_ reader: BufferReader) -> DecryptedMessageAction? { + var _1: Int64? + _1 = reader.readInt64() + var _2: Buffer? + _2 = parseBytes(reader) + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.DecryptedMessageAction.decryptedMessageActionRequestKey(exchangeId: _1!, gA: _2!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageActionAcceptKey(_ reader: BufferReader) -> DecryptedMessageAction? { + var _1: Int64? + _1 = reader.readInt64() + var _2: Buffer? + _2 = parseBytes(reader) + var _3: Int64? + _3 = reader.readInt64() + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + if _c1 && _c2 && _c3 { + return SecretApi101.DecryptedMessageAction.decryptedMessageActionAcceptKey(exchangeId: _1!, gB: _2!, keyFingerprint: _3!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageActionAbortKey(_ reader: BufferReader) -> DecryptedMessageAction? { + var _1: Int64? + _1 = reader.readInt64() + let _c1 = _1 != nil + if _c1 { + return SecretApi101.DecryptedMessageAction.decryptedMessageActionAbortKey(exchangeId: _1!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageActionCommitKey(_ reader: BufferReader) -> DecryptedMessageAction? { + var _1: Int64? + _1 = reader.readInt64() + var _2: Int64? + _2 = reader.readInt64() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.DecryptedMessageAction.decryptedMessageActionCommitKey(exchangeId: _1!, keyFingerprint: _2!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageActionNoop(_ reader: BufferReader) -> DecryptedMessageAction? { + return SecretApi101.DecryptedMessageAction.decryptedMessageActionNoop + } + + + } + + public enum PhotoSize { + case photoSizeEmpty(type: String) + case photoSize(type: String, location: SecretApi101.FileLocation, w: Int32, h: Int32, size: Int32) + case photoCachedSize(type: String, location: SecretApi101.FileLocation, w: Int32, h: Int32, bytes: Buffer) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .photoSizeEmpty(let type): + if boxed { + buffer.appendInt32(236446268) + } + serializeString(type, buffer: buffer, boxed: false) + break + case .photoSize(let type, let location, let w, let h, let size): + if boxed { + buffer.appendInt32(2009052699) + } + serializeString(type, buffer: buffer, boxed: false) + location.serialize(buffer, true) + serializeInt32(w, buffer: buffer, boxed: false) + serializeInt32(h, buffer: buffer, boxed: false) + serializeInt32(size, buffer: buffer, boxed: false) + break + case .photoCachedSize(let type, let location, let w, let h, let bytes): + if boxed { + buffer.appendInt32(-374917894) + } + serializeString(type, buffer: buffer, boxed: false) + location.serialize(buffer, true) + serializeInt32(w, buffer: buffer, boxed: false) + serializeInt32(h, buffer: buffer, boxed: false) + serializeBytes(bytes, buffer: buffer, boxed: false) + break + } + } + fileprivate static func parse_photoSizeEmpty(_ reader: BufferReader) -> PhotoSize? { + var _1: String? + _1 = parseString(reader) + let _c1 = _1 != nil + if _c1 { + return SecretApi101.PhotoSize.photoSizeEmpty(type: _1!) + } + else { + return nil + } + } + fileprivate static func parse_photoSize(_ reader: BufferReader) -> PhotoSize? { + var _1: String? + _1 = parseString(reader) + var _2: SecretApi101.FileLocation? + if let signature = reader.readInt32() { + _2 = SecretApi101.parse(reader, signature: signature) as? SecretApi101.FileLocation + } + var _3: Int32? + _3 = reader.readInt32() + var _4: Int32? + _4 = reader.readInt32() + var _5: Int32? + _5 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = _5 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 { + return SecretApi101.PhotoSize.photoSize(type: _1!, location: _2!, w: _3!, h: _4!, size: _5!) + } + else { + return nil + } + } + fileprivate static func parse_photoCachedSize(_ reader: BufferReader) -> PhotoSize? { + var _1: String? + _1 = parseString(reader) + var _2: SecretApi101.FileLocation? + if let signature = reader.readInt32() { + _2 = SecretApi101.parse(reader, signature: signature) as? SecretApi101.FileLocation + } + var _3: Int32? + _3 = reader.readInt32() + var _4: Int32? + _4 = reader.readInt32() + var _5: Buffer? + _5 = parseBytes(reader) + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = _5 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 { + return SecretApi101.PhotoSize.photoCachedSize(type: _1!, location: _2!, w: _3!, h: _4!, bytes: _5!) + } + else { + return nil + } + } + + + } + + public enum FileLocation { + case fileLocationUnavailable(volumeId: Int64, localId: Int32, secret: Int64) + case fileLocation(dcId: Int32, volumeId: Int64, localId: Int32, secret: Int64) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .fileLocationUnavailable(let volumeId, let localId, let secret): + if boxed { + buffer.appendInt32(2086234950) + } + serializeInt64(volumeId, buffer: buffer, boxed: false) + serializeInt32(localId, buffer: buffer, boxed: false) + serializeInt64(secret, buffer: buffer, boxed: false) + break + case .fileLocation(let dcId, let volumeId, let localId, let secret): + if boxed { + buffer.appendInt32(1406570614) + } + serializeInt32(dcId, buffer: buffer, boxed: false) + serializeInt64(volumeId, buffer: buffer, boxed: false) + serializeInt32(localId, buffer: buffer, boxed: false) + serializeInt64(secret, buffer: buffer, boxed: false) + break + } + } + fileprivate static func parse_fileLocationUnavailable(_ reader: BufferReader) -> FileLocation? { + var _1: Int64? + _1 = reader.readInt64() + var _2: Int32? + _2 = reader.readInt32() + var _3: Int64? + _3 = reader.readInt64() + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + if _c1 && _c2 && _c3 { + return SecretApi101.FileLocation.fileLocationUnavailable(volumeId: _1!, localId: _2!, secret: _3!) + } + else { + return nil + } + } + fileprivate static func parse_fileLocation(_ reader: BufferReader) -> FileLocation? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int64? + _2 = reader.readInt64() + var _3: Int32? + _3 = reader.readInt32() + var _4: Int64? + _4 = reader.readInt64() + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + if _c1 && _c2 && _c3 && _c4 { + return SecretApi101.FileLocation.fileLocation(dcId: _1!, volumeId: _2!, localId: _3!, secret: _4!) + } + else { + return nil + } + } + + + } + + public enum DecryptedMessageLayer { + case decryptedMessageLayer(randomBytes: Buffer, layer: Int32, inSeqNo: Int32, outSeqNo: Int32, message: SecretApi101.DecryptedMessage) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .decryptedMessageLayer(let randomBytes, let layer, let inSeqNo, let outSeqNo, let message): + if boxed { + buffer.appendInt32(467867529) + } + serializeBytes(randomBytes, buffer: buffer, boxed: false) + serializeInt32(layer, buffer: buffer, boxed: false) + serializeInt32(inSeqNo, buffer: buffer, boxed: false) + serializeInt32(outSeqNo, buffer: buffer, boxed: false) + message.serialize(buffer, true) + break + } + } + fileprivate static func parse_decryptedMessageLayer(_ reader: BufferReader) -> DecryptedMessageLayer? { + var _1: Buffer? + _1 = parseBytes(reader) + var _2: Int32? + _2 = reader.readInt32() + var _3: Int32? + _3 = reader.readInt32() + var _4: Int32? + _4 = reader.readInt32() + var _5: SecretApi101.DecryptedMessage? + if let signature = reader.readInt32() { + _5 = SecretApi101.parse(reader, signature: signature) as? SecretApi101.DecryptedMessage + } + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = _5 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 { + return SecretApi101.DecryptedMessageLayer.decryptedMessageLayer(randomBytes: _1!, layer: _2!, inSeqNo: _3!, outSeqNo: _4!, message: _5!) + } + else { + return nil + } + } + + + } + + public enum DecryptedMessage { + case decryptedMessageService(randomId: Int64, action: SecretApi101.DecryptedMessageAction) + case decryptedMessage(flags: Int32, randomId: Int64, ttl: Int32, message: String, media: SecretApi101.DecryptedMessageMedia?, entities: [SecretApi101.MessageEntity]?, viaBotName: String?, replyToRandomId: Int64?, groupedId: Int64?) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .decryptedMessageService(let randomId, let action): + if boxed { + buffer.appendInt32(1930838368) + } + serializeInt64(randomId, buffer: buffer, boxed: false) + action.serialize(buffer, true) + break + case .decryptedMessage(let flags, let randomId, let ttl, let message, let media, let entities, let viaBotName, let replyToRandomId, let groupedId): + if boxed { + buffer.appendInt32(-1848883596) + } + serializeInt32(flags, buffer: buffer, boxed: false) + serializeInt64(randomId, buffer: buffer, boxed: false) + serializeInt32(ttl, buffer: buffer, boxed: false) + serializeString(message, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 9) != 0 {media!.serialize(buffer, true)} + if Int(flags) & Int(1 << 7) != 0 {buffer.appendInt32(481674261) + buffer.appendInt32(Int32(entities!.count)) + for item in entities! { + item.serialize(buffer, true) + }} + if Int(flags) & Int(1 << 11) != 0 {serializeString(viaBotName!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 3) != 0 {serializeInt64(replyToRandomId!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 17) != 0 {serializeInt64(groupedId!, buffer: buffer, boxed: false)} + break + } + } + fileprivate static func parse_decryptedMessageService(_ reader: BufferReader) -> DecryptedMessage? { + var _1: Int64? + _1 = reader.readInt64() + var _2: SecretApi101.DecryptedMessageAction? + if let signature = reader.readInt32() { + _2 = SecretApi101.parse(reader, signature: signature) as? SecretApi101.DecryptedMessageAction + } + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.DecryptedMessage.decryptedMessageService(randomId: _1!, action: _2!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessage(_ reader: BufferReader) -> DecryptedMessage? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int64? + _2 = reader.readInt64() + var _3: Int32? + _3 = reader.readInt32() + var _4: String? + _4 = parseString(reader) + var _5: SecretApi101.DecryptedMessageMedia? + if Int(_1!) & Int(1 << 9) != 0 {if let signature = reader.readInt32() { + _5 = SecretApi101.parse(reader, signature: signature) as? SecretApi101.DecryptedMessageMedia + } } + var _6: [SecretApi101.MessageEntity]? + if Int(_1!) & Int(1 << 7) != 0 {if let _ = reader.readInt32() { + _6 = SecretApi101.parseVector(reader, elementSignature: 0, elementType: SecretApi101.MessageEntity.self) + } } + var _7: String? + if Int(_1!) & Int(1 << 11) != 0 {_7 = parseString(reader) } + var _8: Int64? + if Int(_1!) & Int(1 << 3) != 0 {_8 = reader.readInt64() } + var _9: Int64? + if Int(_1!) & Int(1 << 17) != 0 {_9 = reader.readInt64() } + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = (Int(_1!) & Int(1 << 9) == 0) || _5 != nil + let _c6 = (Int(_1!) & Int(1 << 7) == 0) || _6 != nil + let _c7 = (Int(_1!) & Int(1 << 11) == 0) || _7 != nil + let _c8 = (Int(_1!) & Int(1 << 3) == 0) || _8 != nil + let _c9 = (Int(_1!) & Int(1 << 17) == 0) || _9 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 { + return SecretApi101.DecryptedMessage.decryptedMessage(flags: _1!, randomId: _2!, ttl: _3!, message: _4!, media: _5, entities: _6, viaBotName: _7, replyToRandomId: _8, groupedId: _9) + } + else { + return nil + } + } + + + } + + public enum DocumentAttribute { + case documentAttributeImageSize(w: Int32, h: Int32) + case documentAttributeAnimated + case documentAttributeFilename(fileName: String) + case documentAttributeSticker(alt: String, stickerset: SecretApi101.InputStickerSet) + case documentAttributeAudio(flags: Int32, duration: Int32, title: String?, performer: String?, waveform: Buffer?) + case documentAttributeVideo(flags: Int32, duration: Int32, w: Int32, h: Int32) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .documentAttributeImageSize(let w, let h): + if boxed { + buffer.appendInt32(1815593308) + } + serializeInt32(w, buffer: buffer, boxed: false) + serializeInt32(h, buffer: buffer, boxed: false) + break + case .documentAttributeAnimated: + if boxed { + buffer.appendInt32(297109817) + } + + break + case .documentAttributeFilename(let fileName): + if boxed { + buffer.appendInt32(358154344) + } + serializeString(fileName, buffer: buffer, boxed: false) + break + case .documentAttributeSticker(let alt, let stickerset): + if boxed { + buffer.appendInt32(978674434) + } + serializeString(alt, buffer: buffer, boxed: false) + stickerset.serialize(buffer, true) + break + case .documentAttributeAudio(let flags, let duration, let title, let performer, let waveform): + if boxed { + buffer.appendInt32(-1739392570) + } + serializeInt32(flags, buffer: buffer, boxed: false) + serializeInt32(duration, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 0) != 0 {serializeString(title!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 1) != 0 {serializeString(performer!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 2) != 0 {serializeBytes(waveform!, buffer: buffer, boxed: false)} + break + case .documentAttributeVideo(let flags, let duration, let w, let h): + if boxed { + buffer.appendInt32(250621158) + } + serializeInt32(flags, buffer: buffer, boxed: false) + serializeInt32(duration, buffer: buffer, boxed: false) + serializeInt32(w, buffer: buffer, boxed: false) + serializeInt32(h, buffer: buffer, boxed: false) + break + } + } + fileprivate static func parse_documentAttributeImageSize(_ reader: BufferReader) -> DocumentAttribute? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.DocumentAttribute.documentAttributeImageSize(w: _1!, h: _2!) + } + else { + return nil + } + } + fileprivate static func parse_documentAttributeAnimated(_ reader: BufferReader) -> DocumentAttribute? { + return SecretApi101.DocumentAttribute.documentAttributeAnimated + } + fileprivate static func parse_documentAttributeFilename(_ reader: BufferReader) -> DocumentAttribute? { + var _1: String? + _1 = parseString(reader) + let _c1 = _1 != nil + if _c1 { + return SecretApi101.DocumentAttribute.documentAttributeFilename(fileName: _1!) + } + else { + return nil + } + } + fileprivate static func parse_documentAttributeSticker(_ reader: BufferReader) -> DocumentAttribute? { + var _1: String? + _1 = parseString(reader) + var _2: SecretApi101.InputStickerSet? + if let signature = reader.readInt32() { + _2 = SecretApi101.parse(reader, signature: signature) as? SecretApi101.InputStickerSet + } + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.DocumentAttribute.documentAttributeSticker(alt: _1!, stickerset: _2!) + } + else { + return nil + } + } + fileprivate static func parse_documentAttributeAudio(_ reader: BufferReader) -> DocumentAttribute? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + var _3: String? + if Int(_1!) & Int(1 << 0) != 0 {_3 = parseString(reader) } + var _4: String? + if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) } + var _5: Buffer? + if Int(_1!) & Int(1 << 2) != 0 {_5 = parseBytes(reader) } + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil + let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil + let _c5 = (Int(_1!) & Int(1 << 2) == 0) || _5 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 { + return SecretApi101.DocumentAttribute.documentAttributeAudio(flags: _1!, duration: _2!, title: _3, performer: _4, waveform: _5) + } + else { + return nil + } + } + fileprivate static func parse_documentAttributeVideo(_ reader: BufferReader) -> DocumentAttribute? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + var _3: Int32? + _3 = reader.readInt32() + var _4: Int32? + _4 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + if _c1 && _c2 && _c3 && _c4 { + return SecretApi101.DocumentAttribute.documentAttributeVideo(flags: _1!, duration: _2!, w: _3!, h: _4!) + } + else { + return nil + } + } + + + } + + public enum InputStickerSet { + case inputStickerSetShortName(shortName: String) + case inputStickerSetEmpty + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .inputStickerSetShortName(let shortName): + if boxed { + buffer.appendInt32(-2044933984) + } + serializeString(shortName, buffer: buffer, boxed: false) + break + case .inputStickerSetEmpty: + if boxed { + buffer.appendInt32(-4838507) + } + + break + } + } + fileprivate static func parse_inputStickerSetShortName(_ reader: BufferReader) -> InputStickerSet? { + var _1: String? + _1 = parseString(reader) + let _c1 = _1 != nil + if _c1 { + return SecretApi101.InputStickerSet.inputStickerSetShortName(shortName: _1!) + } + else { + return nil + } + } + fileprivate static func parse_inputStickerSetEmpty(_ reader: BufferReader) -> InputStickerSet? { + return SecretApi101.InputStickerSet.inputStickerSetEmpty + } + + + } + + public enum MessageEntity { + case messageEntityUnknown(offset: Int32, length: Int32) + case messageEntityMention(offset: Int32, length: Int32) + case messageEntityHashtag(offset: Int32, length: Int32) + case messageEntityBotCommand(offset: Int32, length: Int32) + case messageEntityUrl(offset: Int32, length: Int32) + case messageEntityEmail(offset: Int32, length: Int32) + case messageEntityBold(offset: Int32, length: Int32) + case messageEntityItalic(offset: Int32, length: Int32) + case messageEntityCode(offset: Int32, length: Int32) + case messageEntityPre(offset: Int32, length: Int32, language: String) + case messageEntityTextUrl(offset: Int32, length: Int32, url: String) + case messageEntityUnderline(offset: Int32, length: Int32) + case messageEntityStrike(offset: Int32, length: Int32) + case messageEntityBlockquote(offset: Int32, length: Int32) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .messageEntityUnknown(let offset, let length): + if boxed { + buffer.appendInt32(-1148011883) + } + serializeInt32(offset, buffer: buffer, boxed: false) + serializeInt32(length, buffer: buffer, boxed: false) + break + case .messageEntityMention(let offset, let length): + if boxed { + buffer.appendInt32(-100378723) + } + serializeInt32(offset, buffer: buffer, boxed: false) + serializeInt32(length, buffer: buffer, boxed: false) + break + case .messageEntityHashtag(let offset, let length): + if boxed { + buffer.appendInt32(1868782349) + } + serializeInt32(offset, buffer: buffer, boxed: false) + serializeInt32(length, buffer: buffer, boxed: false) + break + case .messageEntityBotCommand(let offset, let length): + if boxed { + buffer.appendInt32(1827637959) + } + serializeInt32(offset, buffer: buffer, boxed: false) + serializeInt32(length, buffer: buffer, boxed: false) + break + case .messageEntityUrl(let offset, let length): + if boxed { + buffer.appendInt32(1859134776) + } + serializeInt32(offset, buffer: buffer, boxed: false) + serializeInt32(length, buffer: buffer, boxed: false) + break + case .messageEntityEmail(let offset, let length): + if boxed { + buffer.appendInt32(1692693954) + } + serializeInt32(offset, buffer: buffer, boxed: false) + serializeInt32(length, buffer: buffer, boxed: false) + break + case .messageEntityBold(let offset, let length): + if boxed { + buffer.appendInt32(-1117713463) + } + serializeInt32(offset, buffer: buffer, boxed: false) + serializeInt32(length, buffer: buffer, boxed: false) + break + case .messageEntityItalic(let offset, let length): + if boxed { + buffer.appendInt32(-2106619040) + } + serializeInt32(offset, buffer: buffer, boxed: false) + serializeInt32(length, buffer: buffer, boxed: false) + break + case .messageEntityCode(let offset, let length): + if boxed { + buffer.appendInt32(681706865) + } + serializeInt32(offset, buffer: buffer, boxed: false) + serializeInt32(length, buffer: buffer, boxed: false) + break + case .messageEntityPre(let offset, let length, let language): + if boxed { + buffer.appendInt32(1938967520) + } + serializeInt32(offset, buffer: buffer, boxed: false) + serializeInt32(length, buffer: buffer, boxed: false) + serializeString(language, buffer: buffer, boxed: false) + break + case .messageEntityTextUrl(let offset, let length, let url): + if boxed { + buffer.appendInt32(1990644519) + } + serializeInt32(offset, buffer: buffer, boxed: false) + serializeInt32(length, buffer: buffer, boxed: false) + serializeString(url, buffer: buffer, boxed: false) + break + case .messageEntityUnderline(let offset, let length): + if boxed { + buffer.appendInt32(-1672577397) + } + serializeInt32(offset, buffer: buffer, boxed: false) + serializeInt32(length, buffer: buffer, boxed: false) + break + case .messageEntityStrike(let offset, let length): + if boxed { + buffer.appendInt32(-1090087980) + } + serializeInt32(offset, buffer: buffer, boxed: false) + serializeInt32(length, buffer: buffer, boxed: false) + break + case .messageEntityBlockquote(let offset, let length): + if boxed { + buffer.appendInt32(34469328) + } + serializeInt32(offset, buffer: buffer, boxed: false) + serializeInt32(length, buffer: buffer, boxed: false) + break + } + } + fileprivate static func parse_messageEntityUnknown(_ reader: BufferReader) -> MessageEntity? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.MessageEntity.messageEntityUnknown(offset: _1!, length: _2!) + } + else { + return nil + } + } + fileprivate static func parse_messageEntityMention(_ reader: BufferReader) -> MessageEntity? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.MessageEntity.messageEntityMention(offset: _1!, length: _2!) + } + else { + return nil + } + } + fileprivate static func parse_messageEntityHashtag(_ reader: BufferReader) -> MessageEntity? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.MessageEntity.messageEntityHashtag(offset: _1!, length: _2!) + } + else { + return nil + } + } + fileprivate static func parse_messageEntityBotCommand(_ reader: BufferReader) -> MessageEntity? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.MessageEntity.messageEntityBotCommand(offset: _1!, length: _2!) + } + else { + return nil + } + } + fileprivate static func parse_messageEntityUrl(_ reader: BufferReader) -> MessageEntity? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.MessageEntity.messageEntityUrl(offset: _1!, length: _2!) + } + else { + return nil + } + } + fileprivate static func parse_messageEntityEmail(_ reader: BufferReader) -> MessageEntity? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.MessageEntity.messageEntityEmail(offset: _1!, length: _2!) + } + else { + return nil + } + } + fileprivate static func parse_messageEntityBold(_ reader: BufferReader) -> MessageEntity? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.MessageEntity.messageEntityBold(offset: _1!, length: _2!) + } + else { + return nil + } + } + fileprivate static func parse_messageEntityItalic(_ reader: BufferReader) -> MessageEntity? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.MessageEntity.messageEntityItalic(offset: _1!, length: _2!) + } + else { + return nil + } + } + fileprivate static func parse_messageEntityCode(_ reader: BufferReader) -> MessageEntity? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.MessageEntity.messageEntityCode(offset: _1!, length: _2!) + } + else { + return nil + } + } + fileprivate static func parse_messageEntityPre(_ reader: BufferReader) -> MessageEntity? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + var _3: String? + _3 = parseString(reader) + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + if _c1 && _c2 && _c3 { + return SecretApi101.MessageEntity.messageEntityPre(offset: _1!, length: _2!, language: _3!) + } + else { + return nil + } + } + fileprivate static func parse_messageEntityTextUrl(_ reader: BufferReader) -> MessageEntity? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + var _3: String? + _3 = parseString(reader) + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + if _c1 && _c2 && _c3 { + return SecretApi101.MessageEntity.messageEntityTextUrl(offset: _1!, length: _2!, url: _3!) + } + else { + return nil + } + } + fileprivate static func parse_messageEntityUnderline(_ reader: BufferReader) -> MessageEntity? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.MessageEntity.messageEntityUnderline(offset: _1!, length: _2!) + } + else { + return nil + } + } + fileprivate static func parse_messageEntityStrike(_ reader: BufferReader) -> MessageEntity? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.MessageEntity.messageEntityStrike(offset: _1!, length: _2!) + } + else { + return nil + } + } + fileprivate static func parse_messageEntityBlockquote(_ reader: BufferReader) -> MessageEntity? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.MessageEntity.messageEntityBlockquote(offset: _1!, length: _2!) + } + else { + return nil + } + } + + } + + public enum DecryptedMessageMedia { + case decryptedMessageMediaEmpty + case decryptedMessageMediaGeoPoint(lat: Double, long: Double) + case decryptedMessageMediaContact(phoneNumber: String, firstName: String, lastName: String, userId: Int32) + case decryptedMessageMediaAudio(duration: Int32, mimeType: String, size: Int32, key: Buffer, iv: Buffer) + case decryptedMessageMediaExternalDocument(id: Int64, accessHash: Int64, date: Int32, mimeType: String, size: Int32, thumb: SecretApi101.PhotoSize, dcId: Int32, attributes: [SecretApi101.DocumentAttribute]) + case decryptedMessageMediaPhoto(thumb: Buffer, thumbW: Int32, thumbH: Int32, w: Int32, h: Int32, size: Int32, key: Buffer, iv: Buffer, caption: String) + case decryptedMessageMediaDocument(thumb: Buffer, thumbW: Int32, thumbH: Int32, mimeType: String, size: Int32, key: Buffer, iv: Buffer, attributes: [SecretApi101.DocumentAttribute], caption: String) + case decryptedMessageMediaVideo(thumb: Buffer, thumbW: Int32, thumbH: Int32, duration: Int32, mimeType: String, w: Int32, h: Int32, size: Int32, key: Buffer, iv: Buffer, caption: String) + case decryptedMessageMediaVenue(lat: Double, long: Double, title: String, address: String, provider: String, venueId: String) + case decryptedMessageMediaWebPage(url: String) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .decryptedMessageMediaEmpty: + if boxed { + buffer.appendInt32(144661578) + } + + break + case .decryptedMessageMediaGeoPoint(let lat, let long): + if boxed { + buffer.appendInt32(893913689) + } + serializeDouble(lat, buffer: buffer, boxed: false) + serializeDouble(long, buffer: buffer, boxed: false) + break + case .decryptedMessageMediaContact(let phoneNumber, let firstName, let lastName, let userId): + if boxed { + buffer.appendInt32(1485441687) + } + serializeString(phoneNumber, buffer: buffer, boxed: false) + serializeString(firstName, buffer: buffer, boxed: false) + serializeString(lastName, buffer: buffer, boxed: false) + serializeInt32(userId, buffer: buffer, boxed: false) + break + case .decryptedMessageMediaAudio(let duration, let mimeType, let size, let key, let iv): + if boxed { + buffer.appendInt32(1474341323) + } + serializeInt32(duration, buffer: buffer, boxed: false) + serializeString(mimeType, buffer: buffer, boxed: false) + serializeInt32(size, buffer: buffer, boxed: false) + serializeBytes(key, buffer: buffer, boxed: false) + serializeBytes(iv, buffer: buffer, boxed: false) + break + case .decryptedMessageMediaExternalDocument(let id, let accessHash, let date, let mimeType, let size, let thumb, let dcId, let attributes): + if boxed { + buffer.appendInt32(-90853155) + } + serializeInt64(id, buffer: buffer, boxed: false) + serializeInt64(accessHash, buffer: buffer, boxed: false) + serializeInt32(date, buffer: buffer, boxed: false) + serializeString(mimeType, buffer: buffer, boxed: false) + serializeInt32(size, buffer: buffer, boxed: false) + thumb.serialize(buffer, true) + serializeInt32(dcId, buffer: buffer, boxed: false) + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(attributes.count)) + for item in attributes { + item.serialize(buffer, true) + } + break + case .decryptedMessageMediaPhoto(let thumb, let thumbW, let thumbH, let w, let h, let size, let key, let iv, let caption): + if boxed { + buffer.appendInt32(-235238024) + } + serializeBytes(thumb, buffer: buffer, boxed: false) + serializeInt32(thumbW, buffer: buffer, boxed: false) + serializeInt32(thumbH, buffer: buffer, boxed: false) + serializeInt32(w, buffer: buffer, boxed: false) + serializeInt32(h, buffer: buffer, boxed: false) + serializeInt32(size, buffer: buffer, boxed: false) + serializeBytes(key, buffer: buffer, boxed: false) + serializeBytes(iv, buffer: buffer, boxed: false) + serializeString(caption, buffer: buffer, boxed: false) + break + case .decryptedMessageMediaDocument(let thumb, let thumbW, let thumbH, let mimeType, let size, let key, let iv, let attributes, let caption): + if boxed { + buffer.appendInt32(2063502050) + } + serializeBytes(thumb, buffer: buffer, boxed: false) + serializeInt32(thumbW, buffer: buffer, boxed: false) + serializeInt32(thumbH, buffer: buffer, boxed: false) + serializeString(mimeType, buffer: buffer, boxed: false) + serializeInt32(size, buffer: buffer, boxed: false) + serializeBytes(key, buffer: buffer, boxed: false) + serializeBytes(iv, buffer: buffer, boxed: false) + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(attributes.count)) + for item in attributes { + item.serialize(buffer, true) + } + serializeString(caption, buffer: buffer, boxed: false) + break + case .decryptedMessageMediaVideo(let thumb, let thumbW, let thumbH, let duration, let mimeType, let w, let h, let size, let key, let iv, let caption): + if boxed { + buffer.appendInt32(-1760785394) + } + serializeBytes(thumb, buffer: buffer, boxed: false) + serializeInt32(thumbW, buffer: buffer, boxed: false) + serializeInt32(thumbH, buffer: buffer, boxed: false) + serializeInt32(duration, buffer: buffer, boxed: false) + serializeString(mimeType, buffer: buffer, boxed: false) + serializeInt32(w, buffer: buffer, boxed: false) + serializeInt32(h, buffer: buffer, boxed: false) + serializeInt32(size, buffer: buffer, boxed: false) + serializeBytes(key, buffer: buffer, boxed: false) + serializeBytes(iv, buffer: buffer, boxed: false) + serializeString(caption, buffer: buffer, boxed: false) + break + case .decryptedMessageMediaVenue(let lat, let long, let title, let address, let provider, let venueId): + if boxed { + buffer.appendInt32(-1978796689) + } + serializeDouble(lat, buffer: buffer, boxed: false) + serializeDouble(long, buffer: buffer, boxed: false) + serializeString(title, buffer: buffer, boxed: false) + serializeString(address, buffer: buffer, boxed: false) + serializeString(provider, buffer: buffer, boxed: false) + serializeString(venueId, buffer: buffer, boxed: false) + break + case .decryptedMessageMediaWebPage(let url): + if boxed { + buffer.appendInt32(-452652584) + } + serializeString(url, buffer: buffer, boxed: false) + break + } + } + fileprivate static func parse_decryptedMessageMediaEmpty(_ reader: BufferReader) -> DecryptedMessageMedia? { + return SecretApi101.DecryptedMessageMedia.decryptedMessageMediaEmpty + } + fileprivate static func parse_decryptedMessageMediaGeoPoint(_ reader: BufferReader) -> DecryptedMessageMedia? { + var _1: Double? + _1 = reader.readDouble() + var _2: Double? + _2 = reader.readDouble() + let _c1 = _1 != nil + let _c2 = _2 != nil + if _c1 && _c2 { + return SecretApi101.DecryptedMessageMedia.decryptedMessageMediaGeoPoint(lat: _1!, long: _2!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageMediaContact(_ reader: BufferReader) -> DecryptedMessageMedia? { + var _1: String? + _1 = parseString(reader) + var _2: String? + _2 = parseString(reader) + var _3: String? + _3 = parseString(reader) + var _4: Int32? + _4 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + if _c1 && _c2 && _c3 && _c4 { + return SecretApi101.DecryptedMessageMedia.decryptedMessageMediaContact(phoneNumber: _1!, firstName: _2!, lastName: _3!, userId: _4!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageMediaAudio(_ reader: BufferReader) -> DecryptedMessageMedia? { + var _1: Int32? + _1 = reader.readInt32() + var _2: String? + _2 = parseString(reader) + var _3: Int32? + _3 = reader.readInt32() + var _4: Buffer? + _4 = parseBytes(reader) + var _5: Buffer? + _5 = parseBytes(reader) + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = _5 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 { + return SecretApi101.DecryptedMessageMedia.decryptedMessageMediaAudio(duration: _1!, mimeType: _2!, size: _3!, key: _4!, iv: _5!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageMediaExternalDocument(_ reader: BufferReader) -> DecryptedMessageMedia? { + var _1: Int64? + _1 = reader.readInt64() + var _2: Int64? + _2 = reader.readInt64() + var _3: Int32? + _3 = reader.readInt32() + var _4: String? + _4 = parseString(reader) + var _5: Int32? + _5 = reader.readInt32() + var _6: SecretApi101.PhotoSize? + if let signature = reader.readInt32() { + _6 = SecretApi101.parse(reader, signature: signature) as? SecretApi101.PhotoSize + } + var _7: Int32? + _7 = reader.readInt32() + var _8: [SecretApi101.DocumentAttribute]? + if let _ = reader.readInt32() { + _8 = SecretApi101.parseVector(reader, elementSignature: 0, elementType: SecretApi101.DocumentAttribute.self) + } + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = _5 != nil + let _c6 = _6 != nil + let _c7 = _7 != nil + let _c8 = _8 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 { + return SecretApi101.DecryptedMessageMedia.decryptedMessageMediaExternalDocument(id: _1!, accessHash: _2!, date: _3!, mimeType: _4!, size: _5!, thumb: _6!, dcId: _7!, attributes: _8!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageMediaPhoto(_ reader: BufferReader) -> DecryptedMessageMedia? { + var _1: Buffer? + _1 = parseBytes(reader) + var _2: Int32? + _2 = reader.readInt32() + var _3: Int32? + _3 = reader.readInt32() + var _4: Int32? + _4 = reader.readInt32() + var _5: Int32? + _5 = reader.readInt32() + var _6: Int32? + _6 = reader.readInt32() + var _7: Buffer? + _7 = parseBytes(reader) + var _8: Buffer? + _8 = parseBytes(reader) + var _9: String? + _9 = parseString(reader) + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = _5 != nil + let _c6 = _6 != nil + let _c7 = _7 != nil + let _c8 = _8 != nil + let _c9 = _9 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 { + return SecretApi101.DecryptedMessageMedia.decryptedMessageMediaPhoto(thumb: _1!, thumbW: _2!, thumbH: _3!, w: _4!, h: _5!, size: _6!, key: _7!, iv: _8!, caption: _9!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageMediaDocument(_ reader: BufferReader) -> DecryptedMessageMedia? { + var _1: Buffer? + _1 = parseBytes(reader) + var _2: Int32? + _2 = reader.readInt32() + var _3: Int32? + _3 = reader.readInt32() + var _4: String? + _4 = parseString(reader) + var _5: Int32? + _5 = reader.readInt32() + var _6: Buffer? + _6 = parseBytes(reader) + var _7: Buffer? + _7 = parseBytes(reader) + var _8: [SecretApi101.DocumentAttribute]? + if let _ = reader.readInt32() { + _8 = SecretApi101.parseVector(reader, elementSignature: 0, elementType: SecretApi101.DocumentAttribute.self) + } + var _9: String? + _9 = parseString(reader) + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = _5 != nil + let _c6 = _6 != nil + let _c7 = _7 != nil + let _c8 = _8 != nil + let _c9 = _9 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 { + return SecretApi101.DecryptedMessageMedia.decryptedMessageMediaDocument(thumb: _1!, thumbW: _2!, thumbH: _3!, mimeType: _4!, size: _5!, key: _6!, iv: _7!, attributes: _8!, caption: _9!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageMediaVideo(_ reader: BufferReader) -> DecryptedMessageMedia? { + var _1: Buffer? + _1 = parseBytes(reader) + var _2: Int32? + _2 = reader.readInt32() + var _3: Int32? + _3 = reader.readInt32() + var _4: Int32? + _4 = reader.readInt32() + var _5: String? + _5 = parseString(reader) + var _6: Int32? + _6 = reader.readInt32() + var _7: Int32? + _7 = reader.readInt32() + var _8: Int32? + _8 = reader.readInt32() + var _9: Buffer? + _9 = parseBytes(reader) + var _10: Buffer? + _10 = parseBytes(reader) + var _11: String? + _11 = parseString(reader) + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = _5 != nil + let _c6 = _6 != nil + let _c7 = _7 != nil + let _c8 = _8 != nil + let _c9 = _9 != nil + let _c10 = _10 != nil + let _c11 = _11 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 { + return SecretApi101.DecryptedMessageMedia.decryptedMessageMediaVideo(thumb: _1!, thumbW: _2!, thumbH: _3!, duration: _4!, mimeType: _5!, w: _6!, h: _7!, size: _8!, key: _9!, iv: _10!, caption: _11!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageMediaVenue(_ reader: BufferReader) -> DecryptedMessageMedia? { + var _1: Double? + _1 = reader.readDouble() + var _2: Double? + _2 = reader.readDouble() + var _3: String? + _3 = parseString(reader) + var _4: String? + _4 = parseString(reader) + var _5: String? + _5 = parseString(reader) + var _6: String? + _6 = parseString(reader) + 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 SecretApi101.DecryptedMessageMedia.decryptedMessageMediaVenue(lat: _1!, long: _2!, title: _3!, address: _4!, provider: _5!, venueId: _6!) + } + else { + return nil + } + } + fileprivate static func parse_decryptedMessageMediaWebPage(_ reader: BufferReader) -> DecryptedMessageMedia? { + var _1: String? + _1 = parseString(reader) + let _c1 = _1 != nil + if _c1 { + return SecretApi101.DecryptedMessageMedia.decryptedMessageMediaWebPage(url: _1!) + } + else { + return nil + } + } + + + } + + public struct functions { + + } + +} diff --git a/submodules/TelegramApi/TelegramApi_Xcode.xcodeproj/project.pbxproj b/submodules/TelegramApi/TelegramApi_Xcode.xcodeproj/project.pbxproj index 1f399c776d..7dc67ed056 100644 --- a/submodules/TelegramApi/TelegramApi_Xcode.xcodeproj/project.pbxproj +++ b/submodules/TelegramApi/TelegramApi_Xcode.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 09E9601B22C2BE4900B13673 /* SecretApiLayer101.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09E9601A22C2BE4900B13673 /* SecretApiLayer101.swift */; }; D035732422B5C1FC00F0920D /* TelegramApi.h in Headers */ = {isa = PBXBuildFile; fileRef = D035732222B5C1FC00F0920D /* TelegramApi.h */; settings = {ATTRIBUTES = (Public, ); }; }; D035733422B5C29900F0920D /* Api0.swift in Sources */ = {isa = PBXBuildFile; fileRef = D035733022B5C29900F0920D /* Api0.swift */; }; D035733522B5C29900F0920D /* Api2.swift in Sources */ = {isa = PBXBuildFile; fileRef = D035733122B5C29900F0920D /* Api2.swift */; }; @@ -32,6 +33,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 09E9601A22C2BE4900B13673 /* SecretApiLayer101.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecretApiLayer101.swift; sourceTree = ""; }; D035731F22B5C1FC00F0920D /* TelegramApi.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TelegramApi.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D035732222B5C1FC00F0920D /* TelegramApi.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TelegramApi.h; sourceTree = ""; }; D035732322B5C1FC00F0920D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -94,6 +96,7 @@ D035734522B5C9BF00F0920D /* SecretApiLayer8.swift */, D035734422B5C9BF00F0920D /* SecretApiLayer46.swift */, D035734622B5C9BF00F0920D /* SecretApiLayer73.swift */, + 09E9601A22C2BE4900B13673 /* SecretApiLayer101.swift */, D035733C22B5C39100F0920D /* DeserializeFunctionResponse.swift */, D035733A22B5C31400F0920D /* TelegramApiLogger.swift */, D035733822B5C2E200F0920D /* Buffer.swift */, @@ -230,6 +233,7 @@ D035733D22B5C39100F0920D /* DeserializeFunctionResponse.swift in Sources */, D035734822B5C9BF00F0920D /* SecretApiLayer8.swift in Sources */, D035733522B5C29900F0920D /* Api2.swift in Sources */, + 09E9601B22C2BE4900B13673 /* SecretApiLayer101.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/submodules/TelegramCore/TelegramCore/ManagedSecretChatOutgoingOperations.swift b/submodules/TelegramCore/TelegramCore/ManagedSecretChatOutgoingOperations.swift index d716a24340..861c0607df 100644 --- a/submodules/TelegramCore/TelegramCore/ManagedSecretChatOutgoingOperations.swift +++ b/submodules/TelegramCore/TelegramCore/ManagedSecretChatOutgoingOperations.swift @@ -361,6 +361,7 @@ private enum BoxedDecryptedMessage { case layer8(SecretApi8.DecryptedMessage) case layer46(SecretApi46.DecryptedMessage) case layer73(SecretApi73.DecryptedMessage) + case layer101(SecretApi101.DecryptedMessage) func serialize(_ buffer: Buffer, role: SecretChatRole, sequenceInfo: SecretChatOperationSequenceInfo?) { switch self { @@ -405,6 +406,26 @@ private enum BoxedDecryptedMessage { assertionFailure() } + let _ = message.serialize(buffer, true) + case let .layer101(message): + buffer.appendInt32(0x1be31789) + let randomBytes = malloc(15)! + arc4random_buf(randomBytes, 15) + serializeBytes(Buffer(memory: randomBytes, size: 15, capacity: 15, freeWhenDone: false), buffer: buffer, boxed: false) + free(randomBytes) + buffer.appendInt32(101) + + if let sequenceInfo = sequenceInfo { + let inSeqNo = (sequenceInfo.topReceivedOperationIndex + 1) * 2 + (role == .creator ? 0 : 1) + let outSeqNo = sequenceInfo.operationIndex * 2 + (role == .creator ? 1 : 0) + buffer.appendInt32(inSeqNo) + buffer.appendInt32(outSeqNo) + } else { + buffer.appendInt32(0) + buffer.appendInt32(0) + assertionFailure() + } + let _ = message.serialize(buffer, true) } } @@ -567,6 +588,59 @@ private func decryptedAttributes73(_ attributes: [TelegramMediaFileAttribute], t return result } +private func decryptedAttributes101(_ attributes: [TelegramMediaFileAttribute], transaction: Transaction) -> [SecretApi101.DocumentAttribute] { + var result: [SecretApi101.DocumentAttribute] = [] + for attribute in attributes { + switch attribute { + case let .FileName(fileName): + result.append(.documentAttributeFilename(fileName: fileName)) + case .Animated: + result.append(.documentAttributeAnimated) + case let .Sticker(displayText, packReference, _): + var stickerSet: SecretApi101.InputStickerSet = .inputStickerSetEmpty + if let packReference = packReference { + switch packReference { + case let .name(name): + stickerSet = .inputStickerSetShortName(shortName: name) + case .id: + if let (info, _, _) = cachedStickerPack(transaction: transaction, reference: packReference) { + stickerSet = .inputStickerSetShortName(shortName: info.shortName) + } + } + } + result.append(.documentAttributeSticker(alt: displayText, stickerset: stickerSet)) + case let .ImageSize(size): + result.append(.documentAttributeImageSize(w: Int32(size.width), h: Int32(size.height))) + case let .Video(duration, size, videoFlags): + var flags: Int32 = 0 + if videoFlags.contains(.instantRoundVideo) { + flags |= 1 << 0 + } + result.append(.documentAttributeVideo(flags: flags, duration: Int32(duration), w: Int32(size.width), h: Int32(size.height))) + case let .Audio(isVoice, duration, title, performer, waveform): + var flags: Int32 = 0 + if isVoice { + flags |= (1 << 10) + } + if let _ = title { + flags |= Int32(1 << 0) + } + if let _ = performer { + flags |= Int32(1 << 1) + } + var waveformBuffer: Buffer? + if let waveform = waveform { + flags |= Int32(1 << 2) + waveformBuffer = Buffer(data: waveform.makeData()) + } + result.append(.documentAttributeAudio(flags: flags, duration: Int32(duration), title: title, performer: performer, waveform: waveformBuffer)) + case .HasLinkedStickers: + break + } + } + return result +} + private func decryptedEntities73(_ entities: [MessageTextEntity]?) -> [SecretApi73.MessageEntity]? { guard let entities = entities else { return nil @@ -614,6 +688,53 @@ private func decryptedEntities73(_ entities: [MessageTextEntity]?) -> [SecretApi return result } +private func decryptedEntities101(_ entities: [MessageTextEntity]?) -> [SecretApi101.MessageEntity]? { + guard let entities = entities else { + return nil + } + + var result: [SecretApi101.MessageEntity] = [] + for entity in entities { + switch entity.type { + case .Unknown: + break + case .Mention: + result.append(.messageEntityMention(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count))) + case .Hashtag: + result.append(.messageEntityHashtag(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count))) + case .BotCommand: + result.append(.messageEntityBotCommand(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count))) + case .Url: + result.append(.messageEntityUrl(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count))) + case .Email: + result.append(.messageEntityEmail(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count))) + case .Bold: + result.append(.messageEntityBold(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count))) + case .Italic: + result.append(.messageEntityItalic(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count))) + case .Code: + result.append(.messageEntityCode(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count))) + case .Pre: + result.append(.messageEntityPre(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count), language: "")) + case let .TextUrl(url): + result.append(.messageEntityTextUrl(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count), url: url)) + case .TextMention: + break + case .PhoneNumber: + break + case .Strikethrough: + result.append(.messageEntityStrike(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count))) + case .BlockQuote: + result.append(.messageEntityBlockquote(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count))) + case .Underline: + result.append(.messageEntityUnderline(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count))) + case .Custom: + break + } + } + return result +} + private func boxedDecryptedMessage(transaction: Transaction, message: Message, globallyUniqueId: Int64, uploadedFile: SecretChatOutgoingFile?, thumbnailData: [MediaId: (CGSize, Data)], layer: SecretChatLayer) -> BoxedDecryptedMessage { let media: Media? = message.media.first var messageAutoremoveTimeout: Int32 = 0 @@ -691,6 +812,20 @@ private func boxedDecryptedMessage(transaction: Transaction, message: Message, g flags |= (1 << 17) } return .layer73(.decryptedMessage(flags: flags, randomId: globallyUniqueId, ttl: messageAutoremoveTimeout, message: message.text, media: decryptedMedia, entities: decryptedEntites, viaBotName: viaBotName, replyToRandomId: replyGlobalId, groupedId: message.groupingKey)) + case .layer101: + if let _ = viaBotName { + flags |= (1 << 11) + } + let decryptedEntites = entities.flatMap(decryptedEntities101) + if let _ = decryptedEntites { + flags |= (1 << 7) + } + let decryptedMedia = SecretApi101.DecryptedMessageMedia.decryptedMessageMediaPhoto(thumb: thumb, thumbW: thumbW, thumbH: thumbH, w: Int32(largestRepresentation.dimensions.width), h: Int32(largestRepresentation.dimensions.height), size: uploadedFile.size, key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv), caption: "") + flags |= (1 << 9) + if message.groupingKey != nil { + flags |= (1 << 17) + } + return .layer101(.decryptedMessage(flags: flags, randomId: globallyUniqueId, ttl: messageAutoremoveTimeout, message: message.text, media: decryptedMedia, entities: decryptedEntites, viaBotName: viaBotName, replyToRandomId: replyGlobalId, groupedId: message.groupingKey)) } } else if let file = media as? TelegramMediaFile { let thumbW: Int32 @@ -786,6 +921,37 @@ private func boxedDecryptedMessage(transaction: Transaction, message: Message, g flags |= (1 << 9) return .layer73(.decryptedMessage(flags: flags, randomId: globallyUniqueId, ttl: messageAutoremoveTimeout, message: message.text, media: decryptedMedia, entities: decryptedEntites, viaBotName: viaBotName, replyToRandomId: replyGlobalId, groupedId: message.groupingKey)) } + case .layer101: + var decryptedMedia: SecretApi101.DecryptedMessageMedia? + + if let uploadedFile = uploadedFile { + decryptedMedia = SecretApi101.DecryptedMessageMedia.decryptedMessageMediaDocument(thumb: thumb, thumbW: thumbW, thumbH: thumbH, mimeType: file.mimeType, size: uploadedFile.size, key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv), attributes: decryptedAttributes101(file.attributes, transaction: transaction), caption: "") + } else { + if let resource = file.resource as? CloudDocumentMediaResource, let size = file.size { + let thumb: SecretApi101.PhotoSize + if let smallestRepresentation = smallestImageRepresentation(file.previewRepresentations), let thumbResource = smallestRepresentation.resource as? CloudFileMediaResource { + thumb = .photoSize(type: "s", location: .fileLocation(dcId: Int32(thumbResource.datacenterId), volumeId: thumbResource.volumeId, localId: thumbResource.localId, secret: thumbResource.secret), w: Int32(smallestRepresentation.dimensions.width), h: Int32(smallestRepresentation.dimensions.height), size: thumbResource.size.flatMap(Int32.init) ?? 0) + } else { + thumb = SecretApi101.PhotoSize.photoSizeEmpty(type: "s") + } + decryptedMedia = SecretApi101.DecryptedMessageMedia.decryptedMessageMediaExternalDocument(id: resource.fileId, accessHash: resource.accessHash, date: 0, mimeType: file.mimeType, size: Int32(size), thumb: thumb, dcId: Int32(resource.datacenterId), attributes: decryptedAttributes101(file.attributes, transaction: transaction)) + } + } + + if let decryptedMedia = decryptedMedia { + if let _ = viaBotName { + flags |= (1 << 11) + } + let decryptedEntites = entities.flatMap(decryptedEntities101) + if let _ = decryptedEntites { + flags |= (1 << 7) + } + if message.groupingKey != nil { + flags |= (1 << 17) + } + flags |= (1 << 9) + return .layer101(.decryptedMessage(flags: flags, randomId: globallyUniqueId, ttl: messageAutoremoveTimeout, message: message.text, media: decryptedMedia, entities: decryptedEntites, viaBotName: viaBotName, replyToRandomId: replyGlobalId, groupedId: message.groupingKey)) + } } } else if let webpage = media as? TelegramMediaWebpage { var url: String? @@ -815,6 +981,17 @@ private func boxedDecryptedMessage(transaction: Transaction, message: Message, g let decryptedMedia = SecretApi73.DecryptedMessageMedia.decryptedMessageMediaWebPage(url: url) flags |= (1 << 9) return .layer73(.decryptedMessage(flags: flags, randomId: globallyUniqueId, ttl: messageAutoremoveTimeout, message: message.text, media: decryptedMedia, entities: decryptedEntites, viaBotName: viaBotName, replyToRandomId: replyGlobalId, groupedId: message.groupingKey)) + case .layer101: + if let _ = viaBotName { + flags |= (1 << 11) + } + let decryptedEntites = entities.flatMap(decryptedEntities101) + if let _ = decryptedEntites { + flags |= (1 << 7) + } + let decryptedMedia = SecretApi101.DecryptedMessageMedia.decryptedMessageMediaWebPage(url: url) + flags |= (1 << 9) + return .layer101(.decryptedMessage(flags: flags, randomId: globallyUniqueId, ttl: messageAutoremoveTimeout, message: message.text, media: decryptedMedia, entities: decryptedEntites, viaBotName: viaBotName, replyToRandomId: replyGlobalId, groupedId: message.groupingKey)) } } } else if let location = media as? TelegramMediaMap { @@ -850,6 +1027,23 @@ private func boxedDecryptedMessage(transaction: Transaction, message: Message, g decryptedMedia = .decryptedMessageMediaGeoPoint(lat: location.latitude, long: location.longitude) } return .layer73(.decryptedMessage(flags: flags, randomId: globallyUniqueId, ttl: messageAutoremoveTimeout, message: message.text, media: decryptedMedia, entities: decryptedEntites, viaBotName: viaBotName, replyToRandomId: replyGlobalId, groupedId: message.groupingKey)) + case .layer101: + if let _ = viaBotName { + flags |= (1 << 11) + } + let decryptedEntites = entities.flatMap(decryptedEntities101) + if let _ = decryptedEntites { + flags |= (1 << 7) + } + + let decryptedMedia: SecretApi101.DecryptedMessageMedia + flags |= (1 << 9) + if let venue = location.venue { + decryptedMedia = .decryptedMessageMediaVenue(lat: location.latitude, long: location.longitude, title: venue.title, address: venue.address ?? "", provider: venue.provider ?? "", venueId: venue.id ?? "") + } else { + decryptedMedia = .decryptedMessageMediaGeoPoint(lat: location.latitude, long: location.longitude) + } + return .layer101(.decryptedMessage(flags: flags, randomId: globallyUniqueId, ttl: messageAutoremoveTimeout, message: message.text, media: decryptedMedia, entities: decryptedEntites, viaBotName: viaBotName, replyToRandomId: replyGlobalId, groupedId: message.groupingKey)) } } else if let contact = media as? TelegramMediaContact { switch layer { @@ -874,6 +1068,18 @@ private func boxedDecryptedMessage(transaction: Transaction, message: Message, g let decryptedMedia: SecretApi73.DecryptedMessageMedia = .decryptedMessageMediaContact(phoneNumber: contact.phoneNumber, firstName: contact.firstName, lastName: contact.lastName, userId: 0) flags |= (1 << 9) return .layer73(.decryptedMessage(flags: flags, randomId: globallyUniqueId, ttl: messageAutoremoveTimeout, message: message.text, media: decryptedMedia, entities: decryptedEntites, viaBotName: viaBotName, replyToRandomId: replyGlobalId, groupedId: message.groupingKey)) + case .layer101: + if let _ = viaBotName { + flags |= (1 << 11) + } + let decryptedEntites = entities.flatMap(decryptedEntities101) + if let _ = decryptedEntites { + flags |= (1 << 7) + } + + let decryptedMedia: SecretApi101.DecryptedMessageMedia = .decryptedMessageMediaContact(phoneNumber: contact.phoneNumber, firstName: contact.firstName, lastName: contact.lastName, userId: 0) + flags |= (1 << 9) + return .layer101(.decryptedMessage(flags: flags, randomId: globallyUniqueId, ttl: messageAutoremoveTimeout, message: message.text, media: decryptedMedia, entities: decryptedEntites, viaBotName: viaBotName, replyToRandomId: replyGlobalId, groupedId: message.groupingKey)) } } } @@ -899,6 +1105,15 @@ private func boxedDecryptedMessage(transaction: Transaction, message: Message, g flags |= (1 << 7) } return .layer73(.decryptedMessage(flags: flags, randomId: globallyUniqueId, ttl: messageAutoremoveTimeout, message: message.text, media: .decryptedMessageMediaEmpty, entities: decryptedEntites, viaBotName: viaBotName, replyToRandomId: replyGlobalId, groupedId: message.groupingKey)) + case .layer101: + if let _ = viaBotName { + flags |= (1 << 11) + } + let decryptedEntites = entities.flatMap(decryptedEntities101) + if let _ = decryptedEntites { + flags |= (1 << 7) + } + return .layer101(.decryptedMessage(flags: flags, randomId: globallyUniqueId, ttl: messageAutoremoveTimeout, message: message.text, media: .decryptedMessageMediaEmpty, entities: decryptedEntites, viaBotName: viaBotName, replyToRandomId: replyGlobalId, groupedId: message.groupingKey)) } } @@ -916,6 +1131,8 @@ private func boxedDecryptedSecretMessageAction(action: SecretMessageAction) -> B return .layer46(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionDeleteMessages(randomIds: globallyUniqueIds))) case .layer73: return .layer73(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionDeleteMessages(randomIds: globallyUniqueIds))) + case .layer101: + return .layer101(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionDeleteMessages(randomIds: globallyUniqueIds))) } case let .screenshotMessages(layer, actionGloballyUniqueId, globallyUniqueIds, _): switch layer { @@ -929,6 +1146,8 @@ private func boxedDecryptedSecretMessageAction(action: SecretMessageAction) -> B return .layer46(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionScreenshotMessages(randomIds: globallyUniqueIds))) case .layer73: return .layer73(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionScreenshotMessages(randomIds: globallyUniqueIds))) + case .layer101: + return .layer101(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionScreenshotMessages(randomIds: globallyUniqueIds))) } case let .clearHistory(layer, actionGloballyUniqueId): switch layer { @@ -941,6 +1160,8 @@ private func boxedDecryptedSecretMessageAction(action: SecretMessageAction) -> B return .layer46(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionFlushHistory)) case .layer73: return .layer73(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionFlushHistory)) + case .layer101: + return .layer101(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionFlushHistory)) } case let .resendOperations(layer, actionGloballyUniqueId, fromSeqNo, toSeqNo): switch layer { @@ -948,6 +1169,8 @@ private func boxedDecryptedSecretMessageAction(action: SecretMessageAction) -> B return .layer46(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionResend(startSeqNo: fromSeqNo, endSeqNo: toSeqNo))) case .layer73: return .layer73(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionResend(startSeqNo: fromSeqNo, endSeqNo: toSeqNo))) + case .layer101: + return .layer101(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionResend(startSeqNo: fromSeqNo, endSeqNo: toSeqNo))) } case let .reportLayerSupport(layer, actionGloballyUniqueId, layerSupport): switch layer { @@ -961,6 +1184,8 @@ private func boxedDecryptedSecretMessageAction(action: SecretMessageAction) -> B return .layer46(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionNotifyLayer(layer: layerSupport))) case .layer73: return .layer73(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionNotifyLayer(layer: layerSupport))) + case .layer101: + return .layer101(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionNotifyLayer(layer: layerSupport))) } case let .pfsRequestKey(layer, actionGloballyUniqueId, rekeySessionId, gA): switch layer { @@ -968,6 +1193,8 @@ private func boxedDecryptedSecretMessageAction(action: SecretMessageAction) -> B return .layer46(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionRequestKey(exchangeId: rekeySessionId, gA: Buffer(buffer: gA)))) case .layer73: return .layer73(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionRequestKey(exchangeId: rekeySessionId, gA: Buffer(buffer: gA)))) + case .layer101: + return .layer101(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionRequestKey(exchangeId: rekeySessionId, gA: Buffer(buffer: gA)))) } case let .pfsAcceptKey(layer, actionGloballyUniqueId, rekeySessionId, gB, keyFingerprint): switch layer { @@ -975,6 +1202,8 @@ private func boxedDecryptedSecretMessageAction(action: SecretMessageAction) -> B return .layer46(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionAcceptKey(exchangeId: rekeySessionId, gB: Buffer(buffer: gB), keyFingerprint: keyFingerprint))) case .layer73: return .layer73(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionAcceptKey(exchangeId: rekeySessionId, gB: Buffer(buffer: gB), keyFingerprint: keyFingerprint))) + case .layer101: + return .layer101(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionAcceptKey(exchangeId: rekeySessionId, gB: Buffer(buffer: gB), keyFingerprint: keyFingerprint))) } case let .pfsAbortSession(layer, actionGloballyUniqueId, rekeySessionId): switch layer { @@ -982,6 +1211,8 @@ private func boxedDecryptedSecretMessageAction(action: SecretMessageAction) -> B return .layer46(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionAbortKey(exchangeId: rekeySessionId))) case .layer73: return .layer73(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionAbortKey(exchangeId: rekeySessionId))) + case .layer101: + return .layer101(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionAbortKey(exchangeId: rekeySessionId))) } case let .pfsCommitKey(layer, actionGloballyUniqueId, rekeySessionId, keyFingerprint): switch layer { @@ -989,6 +1220,8 @@ private func boxedDecryptedSecretMessageAction(action: SecretMessageAction) -> B return .layer46(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionCommitKey(exchangeId: rekeySessionId, keyFingerprint: keyFingerprint))) case .layer73: return .layer73(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionCommitKey(exchangeId: rekeySessionId, keyFingerprint: keyFingerprint))) + case .layer101: + return .layer101(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionCommitKey(exchangeId: rekeySessionId, keyFingerprint: keyFingerprint))) } case let .noop(layer, actionGloballyUniqueId): switch layer { @@ -996,6 +1229,8 @@ private func boxedDecryptedSecretMessageAction(action: SecretMessageAction) -> B return .layer46(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionNoop)) case .layer73: return .layer73(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionNoop)) + case .layer101: + return .layer101(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionNoop)) } case let .readMessageContents(layer, actionGloballyUniqueId, globallyUniqueIds): switch layer { @@ -1009,6 +1244,8 @@ private func boxedDecryptedSecretMessageAction(action: SecretMessageAction) -> B return .layer46(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionReadMessages(randomIds: globallyUniqueIds))) case .layer73: return .layer73(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionReadMessages(randomIds: globallyUniqueIds))) + case .layer101: + return .layer101(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionReadMessages(randomIds: globallyUniqueIds))) } case let .setMessageAutoremoveTimeout(layer, actionGloballyUniqueId, timeout, _): switch layer { @@ -1022,6 +1259,8 @@ private func boxedDecryptedSecretMessageAction(action: SecretMessageAction) -> B return .layer46(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionSetMessageTTL(ttlSeconds: timeout))) case .layer73: return .layer73(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionSetMessageTTL(ttlSeconds: timeout))) + case .layer101: + return .layer101(.decryptedMessageService(randomId: actionGloballyUniqueId, action: .decryptedMessageActionSetMessageTTL(ttlSeconds: timeout))) } } } diff --git a/submodules/TelegramCore/TelegramCore/ProcessSecretChatIncomingDecryptedOperations.swift b/submodules/TelegramCore/TelegramCore/ProcessSecretChatIncomingDecryptedOperations.swift index 0b950bf85c..a03847477b 100644 --- a/submodules/TelegramCore/TelegramCore/ProcessSecretChatIncomingDecryptedOperations.swift +++ b/submodules/TelegramCore/TelegramCore/ProcessSecretChatIncomingDecryptedOperations.swift @@ -52,6 +52,10 @@ private func parsedServiceAction(_ operation: SecretChatIncomingDecryptedOperati if let parsedObject = SecretApi73.parse(Buffer(bufferNoCopy: operation.contents)), let apiMessage = parsedObject as? SecretApi73.DecryptedMessage { return SecretChatServiceAction(apiMessage) } + case .layer101: + if let parsedObject = SecretApi101.parse(Buffer(bufferNoCopy: operation.contents)), let apiMessage = parsedObject as? SecretApi101.DecryptedMessage { + return SecretChatServiceAction(apiMessage) + } } return nil } @@ -153,6 +157,18 @@ func processSecretChatIncomingDecryptedOperations(mediaBox: MediaBox, transactio } else { contentParsingError = true } + case .layer101: + if let parsedObject = SecretApi101.parse(Buffer(bufferNoCopy: operation.contents)), let apiMessage = parsedObject as? SecretApi101.DecryptedMessage { + if let (parsedMessage, parsedResources) = parseMessage(peerId: peerId, authorId: updatedPeer.regularPeerId, tagLocalIndex: entry.tagLocalIndex, timestamp: operation.timestamp, apiMessage: apiMessage, file: operation.file, messageIdForGloballyUniqueMessageId: { id in + return transaction.messageIdForGloballyUniqueMessageId(peerId: peerId, id: id) + }) { + message = parsedMessage + resources = parsedResources + } + serviceAction = SecretChatServiceAction(apiMessage) + } else { + contentParsingError = true + } } switch updatedState.embeddedState { @@ -214,7 +230,11 @@ func processSecretChatIncomingDecryptedOperations(mediaBox: MediaBox, transactio case .handshake: throw MessageParsingError.invalidChatState case .basicLayer: - if layerSupport >= 73 { + if layerSupport >= 101 { + let sequenceBasedLayerState = SecretChatSequenceBasedLayerState(layerNegotiationState: SecretChatLayerNegotiationState(activeLayer: .layer101, locallyRequestedLayer: 101, remotelyRequestedLayer: layerSupport), rekeyState: nil, baseIncomingOperationIndex: entry.tagLocalIndex, baseOutgoingOperationIndex: transaction.operationLogGetNextEntryLocalIndex(peerId: peerId, tag: OperationLogTags.SecretOutgoing), topProcessedCanonicalIncomingOperationIndex: nil) + updatedState = updatedState.withUpdatedEmbeddedState(.sequenceBasedLayer(sequenceBasedLayerState)) + updatedState = addSecretChatOutgoingOperation(transaction: transaction, peerId: peerId, operation: .reportLayerSupport(layer: .layer101, actionGloballyUniqueId: arc4random64(), layerSupport: 101), state: updatedState) + } else if layerSupport >= 73 { let sequenceBasedLayerState = SecretChatSequenceBasedLayerState(layerNegotiationState: SecretChatLayerNegotiationState(activeLayer: .layer73, locallyRequestedLayer: 73, remotelyRequestedLayer: layerSupport), rekeyState: nil, baseIncomingOperationIndex: entry.tagLocalIndex, baseOutgoingOperationIndex: transaction.operationLogGetNextEntryLocalIndex(peerId: peerId, tag: OperationLogTags.SecretOutgoing), topProcessedCanonicalIncomingOperationIndex: nil) updatedState = updatedState.withUpdatedEmbeddedState(.sequenceBasedLayer(sequenceBasedLayerState)) updatedState = addSecretChatOutgoingOperation(transaction: transaction, peerId: peerId, operation: .reportLayerSupport(layer: .layer73, actionGloballyUniqueId: arc4random64(), layerSupport: 73), state: updatedState) @@ -455,6 +475,42 @@ extension SecretChatServiceAction { } } +extension SecretChatServiceAction { + init?(_ apiMessage: SecretApi101.DecryptedMessage) { + switch apiMessage { + case .decryptedMessage: + return nil + case let .decryptedMessageService(_, action): + switch action { + case let .decryptedMessageActionDeleteMessages(randomIds): + self = .deleteMessages(globallyUniqueIds: randomIds) + case .decryptedMessageActionFlushHistory: + self = .clearHistory + case let .decryptedMessageActionNotifyLayer(layer): + self = .reportLayerSupport(layer) + case let .decryptedMessageActionReadMessages(randomIds): + self = .markMessagesContentAsConsumed(globallyUniqueIds: randomIds) + case .decryptedMessageActionScreenshotMessages: + return nil + case let .decryptedMessageActionSetMessageTTL(ttlSeconds): + self = .setMessageAutoremoveTimeout(ttlSeconds) + case let .decryptedMessageActionResend(startSeqNo, endSeqNo): + self = .resendOperations(fromSeq: startSeqNo, toSeq: endSeqNo) + case let .decryptedMessageActionRequestKey(exchangeId, gA): + self = .rekeyAction(.pfsRequestKey(rekeySessionId: exchangeId, gA: MemoryBuffer(gA))) + case let .decryptedMessageActionAcceptKey(exchangeId, gB, keyFingerprint): + self = .rekeyAction(.pfsAcceptKey(rekeySessionId: exchangeId, gB: MemoryBuffer(gB), keyFingerprint: keyFingerprint)) + case let .decryptedMessageActionCommitKey(exchangeId, keyFingerprint): + self = .rekeyAction(.pfsCommitKey(rekeySessionId: exchangeId, keyFingerprint: keyFingerprint)) + case let .decryptedMessageActionAbortKey(exchangeId): + self = .rekeyAction(.pfsAbortSession(rekeySessionId: exchangeId)) + case .decryptedMessageActionNoop: + return nil + } + } + } +} + extension StoreMessage { convenience init?(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32, timestamp: Int32, apiMessage: SecretApi8.DecryptedMessage, file: SecretChatFileReference?) { switch apiMessage { @@ -549,6 +605,43 @@ extension TelegramMediaFileAttribute { } } +extension TelegramMediaFileAttribute { + init?(_ apiAttribute: SecretApi101.DocumentAttribute) { + switch apiAttribute { + case .documentAttributeAnimated: + self = .Animated + case let .documentAttributeAudio(flags, duration, title, performer, waveform): + let isVoice = (flags & (1 << 10)) != 0 + var waveformBuffer: MemoryBuffer? + if let waveform = waveform { + let memory = malloc(waveform.size)! + memcpy(memory, waveform.data, waveform.size) + waveformBuffer = MemoryBuffer(memory: memory, capacity: waveform.size, length: waveform.size, freeWhenDone: true) + } + self = .Audio(isVoice: isVoice, duration: Int(duration), title: title, performer: performer, waveform: waveformBuffer) + case let .documentAttributeFilename(fileName): + self = .FileName(fileName: fileName) + case let .documentAttributeImageSize(w, h): + self = .ImageSize(size: CGSize(width: CGFloat(w), height: CGFloat(h))) + case let .documentAttributeSticker(alt, stickerset): + let packReference: StickerPackReference? + switch stickerset { + case .inputStickerSetEmpty: + packReference = nil + case let .inputStickerSetShortName(shortName): + packReference = .name(shortName) + } + self = .Sticker(displayText: alt, packReference: packReference, maskData: nil) + case let .documentAttributeVideo(flags, duration, w, h): + var videoFlags: TelegramMediaVideoFlags = [] + if (flags & (1 << 0)) != 0 { + videoFlags.insert(.instantRoundVideo) + } + self = .Video(duration: Int(duration), size: CGSize(width: CGFloat(w), height: CGFloat(h)), flags: videoFlags) + } + } +} + private func parseEntities(_ entities: [SecretApi46.MessageEntity]?) -> TextEntitiesMessageAttribute { var result: [MessageTextEntity] = [] if let entities = entities { @@ -986,3 +1079,237 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32 } } } + +private func parseEntities(_ entities: [SecretApi101.MessageEntity]) -> TextEntitiesMessageAttribute { + var result: [MessageTextEntity] = [] + for entity in entities { + switch entity { + case let .messageEntityMention(offset, length): + result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Mention)) + case let .messageEntityHashtag(offset, length): + result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Hashtag)) + case let .messageEntityBotCommand(offset, length): + result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .BotCommand)) + case let .messageEntityUrl(offset, length): + result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Url)) + case let .messageEntityEmail(offset, length): + result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Email)) + case let .messageEntityBold(offset, length): + result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Bold)) + case let .messageEntityItalic(offset, length): + result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Italic)) + case let .messageEntityCode(offset, length): + result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Code)) + case let .messageEntityPre(offset, length, _): + result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Pre)) + case let .messageEntityTextUrl(offset, length, url): + result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .TextUrl(url: url))) + case let .messageEntityStrike(offset, length): + result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Strikethrough)) + case let .messageEntityUnderline(offset, length): + result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .Underline)) + case let .messageEntityBlockquote(offset, length): + result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .BlockQuote)) + case .messageEntityUnknown: + break + } + } + return TextEntitiesMessageAttribute(entities: result) +} + +private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32, timestamp: Int32, apiMessage: SecretApi101.DecryptedMessage, file: SecretChatFileReference?, messageIdForGloballyUniqueMessageId: (Int64) -> MessageId?) -> (StoreMessage, [(MediaResource, Data)])? { + switch apiMessage { + case let .decryptedMessage(_, randomId, ttl, message, media, entities, viaBotName, replyToRandomId, groupedId): + var text = message + var parsedMedia: [Media] = [] + var attributes: [MessageAttribute] = [] + var resources: [(MediaResource, Data)] = [] + + if let entitiesAttribute = entities.flatMap(parseEntities) { + attributes.append(entitiesAttribute) + } + + if let viaBotName = viaBotName, !viaBotName.isEmpty { + attributes.append(InlineBotMessageAttribute(peerId: nil, title: viaBotName)) + } + + if let media = media { + switch media { + case let .decryptedMessageMediaPhoto(thumb, thumbW, thumbH, w, h, size, key, iv, caption): + if !caption.isEmpty { + text = caption + } + if let file = file { + var representations: [TelegramMediaImageRepresentation] = [] + if thumb.size != 0 { + let resource = LocalFileMediaResource(fileId: arc4random64()) + representations.append(TelegramMediaImageRepresentation(dimensions: CGSize(width: CGFloat(thumbW), height: CGFloat(thumbH)), resource: resource)) + resources.append((resource, thumb.makeData())) + } + representations.append(TelegramMediaImageRepresentation(dimensions: CGSize(width: CGFloat(w), height: CGFloat(h)), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size))) + let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil) + parsedMedia.append(image) + } + case let .decryptedMessageMediaAudio(duration, mimeType, size, key, iv): + if let file = file { + let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: [TelegramMediaFileAttribute.Audio(isVoice: true, duration: Int(duration), title: nil, performer: nil, waveform: nil)]) + parsedMedia.append(fileMedia) + attributes.append(ConsumableContentMessageAttribute(consumed: false)) + } + case let .decryptedMessageMediaDocument(thumb, thumbW, thumbH, mimeType, size, key, iv, decryptedAttributes, caption): + if !caption.isEmpty { + text = caption + } + if let file = file { + var parsedAttributes: [TelegramMediaFileAttribute] = [] + for attribute in decryptedAttributes { + if let parsedAttribute = TelegramMediaFileAttribute(attribute) { + parsedAttributes.append(parsedAttribute) + } + } + var previewRepresentations: [TelegramMediaImageRepresentation] = [] + if thumb.size != 0 { + let resource = LocalFileMediaResource(fileId: arc4random64()) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: CGSize(width: CGFloat(thumbW), height: CGFloat(thumbH)), resource: resource)) + resources.append((resource, thumb.makeData())) + } + let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: previewRepresentations, immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: parsedAttributes) + parsedMedia.append(fileMedia) + + loop: for attr in parsedAttributes { + switch attr { + case let .Video(_, _, flags): + if flags.contains(.instantRoundVideo) { + attributes.append(ConsumableContentMessageAttribute(consumed: false)) + } + break loop + case let .Audio(isVoice, _, _, _, _): + if isVoice { + attributes.append(ConsumableContentMessageAttribute(consumed: false)) + } + default: + break + } + } + } + case let .decryptedMessageMediaVideo(thumb, thumbW, thumbH, duration, mimeType, w, h, size, key, iv, caption): + if !caption.isEmpty { + text = caption + } + if let file = file { + let parsedAttributes: [TelegramMediaFileAttribute] = [.Video(duration: Int(duration), size: CGSize(width: CGFloat(w), height: CGFloat(h)), flags: []), .FileName(fileName: "video.mov")] + var previewRepresentations: [TelegramMediaImageRepresentation] = [] + if thumb.size != 0 { + let resource = LocalFileMediaResource(fileId: arc4random64()) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: CGSize(width: CGFloat(thumbW), height: CGFloat(thumbH)), resource: resource)) + resources.append((resource, thumb.makeData())) + } + let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: previewRepresentations, immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: parsedAttributes) + parsedMedia.append(fileMedia) + } + case let .decryptedMessageMediaExternalDocument(id, accessHash, date, mimeType, size, thumb, dcId, attributes): + var parsedAttributes: [TelegramMediaFileAttribute] = [] + for attribute in attributes { + if let parsedAttribute = TelegramMediaFileAttribute(attribute) { + parsedAttributes.append(parsedAttribute) + } + } + var previewRepresentations: [TelegramMediaImageRepresentation] = [] + switch thumb { + case let .photoSize(_, location, w, h, size): + switch location { + case let .fileLocation(dcId, volumeId, localId, secret): + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: CGSize(width: CGFloat(w), height: CGFloat(h)), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int(size), fileReference: nil))) + case .fileLocationUnavailable: + break + } + case let .photoCachedSize(_, location, w, h, bytes): + if bytes.size > 0 { + switch location { + case let .fileLocation(dcId, volumeId, localId, secret): + let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: bytes.size, fileReference: nil) + resources.append((resource, bytes.makeData())) + previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: CGSize(width: CGFloat(w), height: CGFloat(h)), resource: resource)) + case .fileLocationUnavailable: + break + } + } + default: + break + } + let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: id), partialReference: nil, resource: CloudDocumentMediaResource(datacenterId: Int(dcId), fileId: id, accessHash: accessHash, size: Int(size), fileReference: nil, fileName: nil), previewRepresentations: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: parsedAttributes) + parsedMedia.append(fileMedia) + case let .decryptedMessageMediaWebPage(url): + parsedMedia.append(TelegramMediaWebpage(webpageId: MediaId(namespace: Namespaces.Media.LocalWebpage, id: arc4random64()), content: .Pending(0, url))) + case let .decryptedMessageMediaGeoPoint(lat, long): + parsedMedia.append(TelegramMediaMap(latitude: lat, longitude: long, geoPlace: nil, venue: nil, liveBroadcastingTimeout: nil)) + case let .decryptedMessageMediaContact(phoneNumber, firstName, lastName, userId): + parsedMedia.append(TelegramMediaContact(firstName: firstName, lastName: lastName, phoneNumber: phoneNumber, peerId: userId == 0 ? nil : PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), vCardData: nil)) + case let .decryptedMessageMediaVenue(lat, long, title, address, provider, venueId): + parsedMedia.append(TelegramMediaMap(latitude: lat, longitude: long, geoPlace: nil, venue: MapVenue(title: title, address: address, provider: provider, id: venueId, type: nil), liveBroadcastingTimeout: nil)) + case .decryptedMessageMediaEmpty: + break + } + } + + if ttl > 0 { + attributes.append(AutoremoveTimeoutMessageAttribute(timeout: ttl, countdownBeginTime: nil)) + } + + var groupingKey: Int64? + if let groupedId = groupedId { + inner: for media in parsedMedia { + if let _ = media as? TelegramMediaImage { + groupingKey = groupedId + break inner + } else if let _ = media as? TelegramMediaFile { + groupingKey = groupedId + break inner + } + } + } + + if let replyToRandomId = replyToRandomId, let replyMessageId = messageIdForGloballyUniqueMessageId(replyToRandomId) { + attributes.append(ReplyMessageAttribute(messageId: replyMessageId)) + } + + var entitiesAttribute: TextEntitiesMessageAttribute? + for attribute in attributes { + if let attribute = attribute as? TextEntitiesMessageAttribute { + entitiesAttribute = attribute + break + } + } + + let (tags, globalTags) = tagsForStoreMessage(incoming: true, attributes: attributes, media: parsedMedia, textEntities: entitiesAttribute?.entities) + + return (StoreMessage(id: MessageId(peerId: peerId, namespace: Namespaces.Message.SecretIncoming, id: tagLocalIndex), globallyUniqueId: randomId, groupingKey: groupingKey, timestamp: timestamp, flags: [.Incoming], tags: tags, globalTags: globalTags, localTags: [], forwardInfo: nil, authorId: authorId, text: text, attributes: attributes, media: parsedMedia), resources) + case let .decryptedMessageService(randomId, action): + switch action { + case .decryptedMessageActionDeleteMessages: + return nil + case .decryptedMessageActionFlushHistory: + return nil + case .decryptedMessageActionNotifyLayer: + return nil + case .decryptedMessageActionReadMessages: + return nil + case .decryptedMessageActionScreenshotMessages: + return (StoreMessage(id: MessageId(peerId: peerId, namespace: Namespaces.Message.SecretIncoming, id: tagLocalIndex), globallyUniqueId: randomId, groupingKey: nil, timestamp: timestamp, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, authorId: authorId, text: "", attributes: [], media: [TelegramMediaAction(action: .historyScreenshot)]), []) + case let .decryptedMessageActionSetMessageTTL(ttlSeconds): + return (StoreMessage(id: MessageId(peerId: peerId, namespace: Namespaces.Message.SecretIncoming, id: tagLocalIndex), globallyUniqueId: randomId, groupingKey: nil, timestamp: timestamp, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, authorId: authorId, text: "", attributes: [], media: [TelegramMediaAction(action: .messageAutoremoveTimeoutUpdated(ttlSeconds))]), []) + case .decryptedMessageActionResend: + return nil + case .decryptedMessageActionRequestKey: + return nil + case .decryptedMessageActionAcceptKey: + return nil + case .decryptedMessageActionCommitKey: + return nil + case .decryptedMessageActionAbortKey: + return nil + case .decryptedMessageActionNoop: + return nil + } + } +} diff --git a/submodules/TelegramCore/TelegramCore/SecretChatLayerNegotiation.swift b/submodules/TelegramCore/TelegramCore/SecretChatLayerNegotiation.swift index 2078aecaf6..d7bc4c10be 100644 --- a/submodules/TelegramCore/TelegramCore/SecretChatLayerNegotiation.swift +++ b/submodules/TelegramCore/TelegramCore/SecretChatLayerNegotiation.swift @@ -7,7 +7,7 @@ import Foundation import SwiftSignalKit #endif -private let topSupportedLayer: SecretChatSequenceBasedLayer = .layer73 +private let topSupportedLayer: SecretChatSequenceBasedLayer = .layer101 func secretChatCommonSupportedLayer(remoteLayer: Int32) -> SecretChatSequenceBasedLayer { switch remoteLayer { @@ -15,6 +15,8 @@ func secretChatCommonSupportedLayer(remoteLayer: Int32) -> SecretChatSequenceBas return .layer46 case 73: return .layer73 + case 101: + return .layer101 default: return topSupportedLayer } diff --git a/submodules/TelegramCore/TelegramCore/SecretChatOutgoingOperation.swift b/submodules/TelegramCore/TelegramCore/SecretChatOutgoingOperation.swift index 1c91ef2d9c..69b54688b9 100644 --- a/submodules/TelegramCore/TelegramCore/SecretChatOutgoingOperation.swift +++ b/submodules/TelegramCore/TelegramCore/SecretChatOutgoingOperation.swift @@ -81,6 +81,7 @@ struct SecretChatOutgoingFile: PostboxCoding { public enum SecretChatSequenceBasedLayer: Int32 { case layer46 = 46 case layer73 = 73 + case layer101 = 101 var secretChatLayer: SecretChatLayer { switch self { @@ -88,6 +89,8 @@ public enum SecretChatSequenceBasedLayer: Int32 { return .layer46 case .layer73: return .layer73 + case .layer101: + return .layer101 } } } diff --git a/submodules/TelegramCore/TelegramCore/SecretChatState.swift b/submodules/TelegramCore/TelegramCore/SecretChatState.swift index 4fca04dae7..3d5f1aacb0 100644 --- a/submodules/TelegramCore/TelegramCore/SecretChatState.swift +++ b/submodules/TelegramCore/TelegramCore/SecretChatState.swift @@ -14,6 +14,7 @@ enum SecretChatLayer: Int32 { case layer8 = 8 case layer46 = 46 case layer73 = 73 + case layer101 = 101 } public struct SecretChatKeySha1Fingerprint: PostboxCoding, Equatable { diff --git a/submodules/TelegramCore/TelegramCore/Serialization.swift b/submodules/TelegramCore/TelegramCore/Serialization.swift index 81e2594098..1f517bb8ab 100644 --- a/submodules/TelegramCore/TelegramCore/Serialization.swift +++ b/submodules/TelegramCore/TelegramCore/Serialization.swift @@ -216,7 +216,7 @@ public class BoxedMessage: NSObject { public class Serialization: NSObject, MTSerialization { public func currentLayer() -> UInt { - return 102 + return 101 } public func parseMessage(_ data: Data!) -> Any! {