stickers_dice_pack.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "chat_helpers/stickers_dice_pack.h"
  8. #include "main/main_session.h"
  9. #include "chat_helpers/stickers_lottie.h"
  10. #include "data/data_session.h"
  11. #include "data/data_document.h"
  12. #include "base/unixtime.h"
  13. #include "apiwrap.h"
  14. #include <QtCore/QFile>
  15. #include <QtCore/QFileInfo>
  16. namespace Stickers {
  17. const QString DicePacks::kDiceString = QString::fromUtf8("\xF0\x9F\x8E\xB2");
  18. const QString DicePacks::kDartString = QString::fromUtf8("\xF0\x9F\x8E\xAF");
  19. const QString DicePacks::kSlotString = QString::fromUtf8("\xF0\x9F\x8E\xB0");
  20. const QString DicePacks::kFballString = QString::fromUtf8("\xE2\x9A\xBD");
  21. const QString DicePacks::kBballString = QString::fromUtf8("\xF0\x9F\x8F\x80");
  22. const QString DicePacks::kPartyPopper = QString::fromUtf8("\xf0\x9f\x8e\x89");
  23. DicePack::DicePack(not_null<Main::Session*> session, const QString &emoji)
  24. : _session(session)
  25. , _emoji(emoji) {
  26. }
  27. DicePack::~DicePack() = default;
  28. DocumentData *DicePack::lookup(int value) {
  29. if (!_requestId && _emoji != DicePacks::kPartyPopper) {
  30. load();
  31. }
  32. tryGenerateLocalZero();
  33. const auto i = _map.find(value);
  34. return (i != end(_map)) ? i->second.get() : nullptr;
  35. }
  36. void DicePack::load() {
  37. if (_requestId) {
  38. return;
  39. }
  40. _requestId = _session->api().request(MTPmessages_GetStickerSet(
  41. MTP_inputStickerSetDice(MTP_string(_emoji)),
  42. MTP_int(0) // hash
  43. )).done([=](const MTPmessages_StickerSet &result) {
  44. result.match([&](const MTPDmessages_stickerSet &data) {
  45. applySet(data);
  46. }, [](const MTPDmessages_stickerSetNotModified &) {
  47. LOG(("API Error: Unexpected messages.stickerSetNotModified."));
  48. });
  49. }).fail([=] {
  50. _requestId = 0;
  51. }).send();
  52. }
  53. void DicePack::applySet(const MTPDmessages_stickerSet &data) {
  54. const auto isSlotMachine = DicePacks::IsSlot(_emoji);
  55. auto index = 0;
  56. auto documents = base::flat_map<DocumentId, not_null<DocumentData*>>();
  57. for (const auto &sticker : data.vdocuments().v) {
  58. const auto document = _session->data().processDocument(sticker);
  59. if (document->sticker()) {
  60. if (isSlotMachine) {
  61. _map.emplace(index++, document);
  62. } else {
  63. documents.emplace(document->id, document);
  64. }
  65. }
  66. }
  67. if (isSlotMachine) {
  68. return;
  69. }
  70. for (const auto &pack : data.vpacks().v) {
  71. pack.match([&](const MTPDstickerPack &data) {
  72. const auto emoji = qs(data.vemoticon());
  73. if (emoji.isEmpty()) {
  74. return;
  75. }
  76. const auto ch = int(emoji[0].unicode());
  77. const auto index = (ch == '#') ? 0 : (ch + 1 - '1');
  78. if (index < 0 || index > 6) {
  79. return;
  80. }
  81. for (const auto &id : data.vdocuments().v) {
  82. if (const auto document = documents.take(id.v)) {
  83. _map.emplace(index, *document);
  84. }
  85. }
  86. });
  87. }
  88. }
  89. void DicePack::tryGenerateLocalZero() {
  90. if (!_map.empty()) {
  91. return;
  92. }
  93. const auto generateLocal = [&](int index, const QString &name) {
  94. _map.emplace(
  95. index,
  96. ChatHelpers::GenerateLocalTgsSticker(_session, name));
  97. };
  98. if (_emoji == DicePacks::kDiceString) {
  99. generateLocal(0, u"dice_idle"_q);
  100. } else if (_emoji == DicePacks::kDartString) {
  101. generateLocal(0, u"dart_idle"_q);
  102. } else if (_emoji == DicePacks::kBballString) {
  103. generateLocal(0, u"bball_idle"_q);
  104. } else if (_emoji == DicePacks::kFballString) {
  105. generateLocal(0, u"fball_idle"_q);
  106. } else if (_emoji == DicePacks::kSlotString) {
  107. generateLocal(0, u"slot_back"_q);
  108. generateLocal(2, u"slot_pull"_q);
  109. generateLocal(8, u"slot_0_idle"_q);
  110. generateLocal(14, u"slot_1_idle"_q);
  111. generateLocal(20, u"slot_2_idle"_q);
  112. } else if (_emoji == DicePacks::kPartyPopper) {
  113. generateLocal(0, u"winners"_q);
  114. }
  115. }
  116. DicePacks::DicePacks(not_null<Main::Session*> session)
  117. : _session(session) {
  118. }
  119. DocumentData *DicePacks::lookup(const QString &emoji, int value) {
  120. const auto key = emoji.endsWith(QChar(0xFE0F))
  121. ? emoji.mid(0, emoji.size() - 1)
  122. : emoji;
  123. const auto i = _packs.find(key);
  124. if (i != end(_packs)) {
  125. return i->second->lookup(value);
  126. }
  127. return _packs.emplace(
  128. key,
  129. std::make_unique<DicePack>(_session, key)
  130. ).first->second->lookup(value);
  131. }
  132. } // namespace Stickers