// This is the source code of AyuGram for Desktop. // // We do not and cannot prevent the use of our code, // but be respectful and credit the original author. // // Copyright @Radolyn, 2025 #include "ayu_mapper.h" #include "apiwrap.h" #include "api/api_text_entities.h" #include "history/history.h" #include "history/history_item.h" #include "history/history_item_components.h" #include "main/main_session.h" #include "mtproto/connection_abstract.h" #include "mtproto/details/mtproto_dump_to_text.h" namespace AyuMapper { constexpr auto kMessageFlagUnread = 0x00000001; constexpr auto kMessageFlagOut = 0x00000002; constexpr auto kMessageFlagForwarded = 0x00000004; constexpr auto kMessageFlagReply = 0x00000008; constexpr auto kMessageFlagMention = 0x00000010; constexpr auto kMessageFlagContentUnread = 0x00000020; constexpr auto kMessageFlagHasMarkup = 0x00000040; constexpr auto kMessageFlagHasEntities = 0x00000080; constexpr auto kMessageFlagHasFromId = 0x00000100; constexpr auto kMessageFlagHasMedia = 0x00000200; constexpr auto kMessageFlagHasViews = 0x00000400; constexpr auto kMessageFlagHasBotId = 0x00000800; constexpr auto kMessageFlagIsSilent = 0x00001000; constexpr auto kMessageFlagIsPost = 0x00004000; constexpr auto kMessageFlagEdited = 0x00008000; constexpr auto kMessageFlagHasPostAuthor = 0x00010000; constexpr auto kMessageFlagIsGrouped = 0x00020000; constexpr auto kMessageFlagFromScheduled = 0x00040000; constexpr auto kMessageFlagHasReactions = 0x00100000; constexpr auto kMessageFlagHideEdit = 0x00200000; constexpr auto kMessageFlagRestricted = 0x00400000; constexpr auto kMessageFlagHasReplies = 0x00800000; constexpr auto kMessageFlagIsPinned = 0x01000000; constexpr auto kMessageFlagHasTTL = 0x02000000; constexpr auto kMessageFlagInvertMedia = 0x08000000; constexpr auto kMessageFlagHasSavedPeer = 0x10000000; template std::vector serializeObject(MTPObject object) { mtpBuffer buffer; object.write(buffer); auto from = reinterpret_cast(buffer.data()); const auto end = from + buffer.size() * sizeof(mtpBuffer); std::vector entities(from, end); return entities; } template MTPObject deserializeObject(std::vector serialized) { gsl::span span(serialized.data(), serialized.size()); auto from = reinterpret_cast(span.data()); const auto end = from + span.size() / sizeof(mtpPrime); MTPObject data; if (!data.read(from, end)) { LOG(("AyuMapper: Failed to deserialize object")); } return data; } std::pair> serializeTextWithEntities(not_null item) { if (item->emptyText()) { return std::make_pair("", std::vector()); } auto textWithEntities = item->originalText(); std::vector entities; if (!textWithEntities.entities.empty()) { const auto mtpEntities = Api::EntitiesToMTP( &item->history()->session(), textWithEntities.entities, Api::ConvertOption::WithLocal); entities = serializeObject(mtpEntities); } return std::make_pair(textWithEntities.text.toStdString(), entities); } MTPVector deserializeTextWithEntities(std::vector serialized) { return deserializeObject>(serialized); } int mapItemFlagsToMTPFlags(not_null item) { int flags = 0; const auto thread = item->topic() ? reinterpret_cast(item->topic()) : item->history(); if (item->unread(thread)) { flags |= kMessageFlagUnread; } if (item->out()) { flags |= kMessageFlagOut; } if (item->Get()) { flags |= kMessageFlagForwarded; } if (item->Get()) { flags |= kMessageFlagReply; } if (item->mentionsMe()) { flags |= kMessageFlagMention; } if (item->isUnreadMedia()) { flags |= kMessageFlagContentUnread; } if (item->definesReplyKeyboard()) { flags |= kMessageFlagHasMarkup; } if (!item->originalText().entities.empty()) { flags |= kMessageFlagHasEntities; } if (item->displayFrom()) { // todo: maybe wrong flags |= kMessageFlagHasFromId; } if (item->media()) { flags |= kMessageFlagHasMedia; } if (item->hasViews()) { flags |= kMessageFlagHasViews; } if (item->viaBot()) { flags |= kMessageFlagHasBotId; } if (item->isSilent()) { flags |= kMessageFlagIsSilent; } if (item->isPost()) { flags |= kMessageFlagIsPost; } if (item->Get()) { flags |= kMessageFlagEdited; } if (item->Get()) { flags |= kMessageFlagHasPostAuthor; } if (item->groupId()) { flags |= kMessageFlagIsGrouped; } if (item->isScheduled()) { flags |= kMessageFlagFromScheduled; } if (!item->reactions().empty()) { flags |= kMessageFlagHasReactions; } if (item->hideEditedBadge()) { flags |= kMessageFlagHideEdit; } if (item->hasPossibleRestrictions()) { flags |= kMessageFlagRestricted; } if (item->repliesCount() > 0) { flags |= kMessageFlagHasReplies; } if (item->isPinned()) { flags |= kMessageFlagIsPinned; } if (item->ttlDestroyAt() > 0) { flags |= kMessageFlagHasTTL; } if (item->invertMedia()) { flags |= kMessageFlagInvertMedia; } if (item->savedFromSender()) { // todo: maybe wrong flags |= kMessageFlagHasSavedPeer; } return flags; } }