diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b08f217e..48b524f03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -444,6 +444,7 @@ set(TDLIB_SOURCE td/telegram/PollManager.cpp td/telegram/QueryCombiner.cpp td/telegram/ReplyMarkup.cpp + td/telegram/RestrictionReason.cpp td/telegram/SecretChatActor.cpp td/telegram/SecretChatDb.cpp td/telegram/SecretChatsManager.cpp @@ -617,6 +618,7 @@ set(TDLIB_SOURCE td/telegram/QueryCombiner.h td/telegram/ReplyMarkup.h td/telegram/RequestActor.h + td/telegram/RestrictionReason.h td/telegram/SecretChatActor.h td/telegram/SecretChatId.h td/telegram/SecretChatDb.h diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index f7b260d27..6081a3dc8 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -299,8 +299,7 @@ chatLocation location:location address:string = ChatLocation; //@is_contact The user is a contact of the current user //@is_mutual_contact The user is a contact of the current user and the current user is a contact of the user //@is_verified True, if the user is verified @is_support True, if the user is Telegram support account -//@restriction_reason If non-empty, it contains the reason why access to this user must be restricted. The format of the string is "{type}: {description}". -//-{type} contains the type of the restriction and at least one of the suffixes "-all", "-ios", "-android", or "-wp", which describe the platforms on which access should be restricted. (For example, "terms-ios-android". {description} contains a human-readable description of the restriction, which can be shown to the user) +//@restriction_reason If non-empty, it contains a human-readable description of the reason why access to this user must be restricted //@is_scam True, if many users reported this user as a scam //@have_access If false, the user is inaccessible, and the only information known about the user is inside this class. It can't be passed to any method except GetUser @type Type of the user @language_code IETF language tag of the user's language; only available to bots user id:int32 first_name:string last_name:string username:string phone_number:string status:UserStatus profile_photo:profilePhoto is_contact:Bool is_mutual_contact:Bool is_verified:Bool is_support:Bool restriction_reason:string is_scam:Bool have_access:Bool type:UserType language_code:string = User; @@ -454,8 +453,7 @@ basicGroupFullInfo description:string creator_user_id:int32 members:vector &&user_ptr, bool is_deleted = (flags & USER_FLAG_IS_DELETED) != 0; bool can_join_groups = (flags & USER_FLAG_IS_PRIVATE_BOT) == 0; bool can_read_all_group_messages = (flags & USER_FLAG_IS_BOT_WITH_PRIVACY_DISABLED) != 0; - string restriction_reason; // = std::move(user->restriction_reason_); + auto restriction_reasons = get_restriction_reasons(std::move(user->restriction_reason_)); bool is_scam = (flags & USER_FLAG_IS_SCAM) != 0; bool is_inline_bot = (flags & USER_FLAG_IS_INLINE_BOT) != 0; string inline_query_placeholder = user->bot_inline_placeholder_; @@ -6369,7 +6383,7 @@ void ContactsManager::on_get_user(tl_object_ptr &&user_ptr, int32 bot_info_version = has_bot_info_version ? user->bot_info_version_ : -1; if (is_verified != u->is_verified || is_support != u->is_support || is_bot != u->is_bot || can_join_groups != u->can_join_groups || can_read_all_group_messages != u->can_read_all_group_messages || - restriction_reason != u->restriction_reason || is_scam != u->is_scam || is_inline_bot != u->is_inline_bot || + restriction_reasons != u->restriction_reasons || is_scam != u->is_scam || is_inline_bot != u->is_inline_bot || inline_query_placeholder != u->inline_query_placeholder || need_location_bot != u->need_location_bot) { LOG_IF(ERROR, is_bot != u->is_bot && !is_deleted && !u->is_deleted && u->is_received) << "User.is_bot has changed for " << user_id << "/" << u->username << " from " << source << " from " @@ -6379,7 +6393,7 @@ void ContactsManager::on_get_user(tl_object_ptr &&user_ptr, u->is_bot = is_bot; u->can_join_groups = can_join_groups; u->can_read_all_group_messages = can_read_all_group_messages; - u->restriction_reason = std::move(restriction_reason); + u->restriction_reasons = std::move(restriction_reasons); u->is_scam = is_scam; u->is_inline_bot = is_inline_bot; u->inline_query_placeholder = std::move(inline_query_placeholder); @@ -12180,7 +12194,7 @@ void ContactsManager::on_chat_update(telegram_api::channel &channel, const char bool is_slow_mode_enabled = (channel.flags_ & CHANNEL_FLAG_IS_SLOW_MODE_ENABLED) != 0; bool is_megagroup = (channel.flags_ & CHANNEL_FLAG_IS_MEGAGROUP) != 0; bool is_verified = (channel.flags_ & CHANNEL_FLAG_IS_VERIFIED) != 0; - string restriction_reason; // = std::move(channel.restriction_reason_); + auto restriction_reasons = get_restriction_reasons(std::move(channel.restriction_reason_)); bool is_scam = (channel.flags_ & CHANNEL_FLAG_IS_SCAM) != 0; int32 participant_count = (channel.flags_ & CHANNEL_FLAG_HAS_PARTICIPANT_COUNT) != 0 ? channel.participants_count_ : 0; @@ -12273,14 +12287,14 @@ void ContactsManager::on_chat_update(telegram_api::channel &channel, const char if (c->has_linked_channel != has_linked_channel || c->has_location != has_location || c->sign_messages != sign_messages || c->is_megagroup != is_megagroup || c->is_verified != is_verified || - c->restriction_reason != restriction_reason || c->is_scam != is_scam) { + c->restriction_reasons != restriction_reasons || c->is_scam != is_scam) { c->has_linked_channel = has_linked_channel; c->has_location = has_location; c->sign_messages = sign_messages; c->is_slow_mode_enabled = is_slow_mode_enabled; c->is_megagroup = is_megagroup; c->is_verified = is_verified; - c->restriction_reason = std::move(restriction_reason); + c->restriction_reasons = std::move(restriction_reasons); c->is_scam = is_scam; c->is_changed = true; @@ -12337,7 +12351,6 @@ void ContactsManager::on_chat_update(telegram_api::channelForbidden &channel, co bool is_slow_mode_enabled = false; bool is_megagroup = (channel.flags_ & CHANNEL_FLAG_IS_MEGAGROUP) != 0; bool is_verified = false; - string restriction_reason; bool is_scam = false; { @@ -12358,7 +12371,7 @@ void ContactsManager::on_chat_update(telegram_api::channelForbidden &channel, co if (c->has_linked_channel != has_linked_channel || c->has_location != has_location || c->sign_messages != sign_messages || c->is_slow_mode_enabled != is_slow_mode_enabled || - c->is_megagroup != is_megagroup || c->is_verified != is_verified || c->restriction_reason != restriction_reason || + c->is_megagroup != is_megagroup || c->is_verified != is_verified || !c->restriction_reasons.empty() || c->is_scam != is_scam) { c->has_linked_channel = has_linked_channel; c->has_location = has_location; @@ -12366,7 +12379,7 @@ void ContactsManager::on_chat_update(telegram_api::channelForbidden &channel, co c->is_slow_mode_enabled = is_slow_mode_enabled; c->is_megagroup = is_megagroup; c->is_verified = is_verified; - c->restriction_reason = std::move(restriction_reason); + c->restriction_reasons.clear(); c->is_scam = is_scam; c->is_changed = true; @@ -12478,11 +12491,11 @@ tl_object_ptr ContactsManager::get_user_object(UserId user_id, con type = make_tl_object(); } - return make_tl_object(user_id.get(), u->first_name, u->last_name, u->username, u->phone_number, - get_user_status_object(user_id, u), - get_profile_photo_object(td_->file_manager_.get(), &u->photo), u->is_contact, - u->is_mutual_contact, u->is_verified, u->is_support, u->restriction_reason, - u->is_scam, u->is_received, std::move(type), u->language_code); + return make_tl_object( + user_id.get(), u->first_name, u->last_name, u->username, u->phone_number, get_user_status_object(user_id, u), + get_profile_photo_object(td_->file_manager_.get(), &u->photo), u->is_contact, u->is_mutual_contact, + u->is_verified, u->is_support, get_restriction_reason_description(u->restriction_reasons), u->is_scam, + u->is_received, std::move(type), u->language_code); } vector ContactsManager::get_user_ids_object(const vector &user_ids) const { @@ -12580,7 +12593,7 @@ tl_object_ptr ContactsManager::get_supergroup_object(Channel return td_api::make_object( channel_id.get(), c->username, c->date, get_channel_status(c).get_chat_member_status_object(), c->participant_count, c->has_linked_channel, c->has_location, c->sign_messages, c->is_slow_mode_enabled, - !c->is_megagroup, c->is_verified, c->restriction_reason, c->is_scam); + !c->is_megagroup, c->is_verified, get_restriction_reason_description(c->restriction_reasons), c->is_scam); } tl_object_ptr ContactsManager::get_supergroup_full_info_object(ChannelId channel_id) const { diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index fcec18326..139e0dfbf 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -24,6 +24,7 @@ #include "td/telegram/Photo.h" #include "td/telegram/PublicDialogType.h" #include "td/telegram/QueryCombiner.h" +#include "td/telegram/RestrictionReason.h" #include "td/telegram/SecretChatId.h" #include "td/telegram/StickerSetId.h" #include "td/telegram/UserId.h" @@ -517,7 +518,7 @@ class ContactsManager : public Actor { ProfilePhoto photo; - string restriction_reason; + vector restriction_reasons; string inline_query_placeholder; int32 bot_info_version = -1; @@ -691,7 +692,7 @@ class ContactsManager : public Actor { DialogPhoto photo; FileSourceId photo_source_id; string username; - string restriction_reason; + vector restriction_reasons; DialogParticipantStatus status = DialogParticipantStatus::Banned(0); RestrictedRights default_permissions{false, false, false, false, false, false, false, false, false, false, false}; int32 date = 0; diff --git a/td/telegram/DialogParticipant.cpp b/td/telegram/DialogParticipant.cpp index 360b8d835..ca9430fcc 100644 --- a/td/telegram/DialogParticipant.cpp +++ b/td/telegram/DialogParticipant.cpp @@ -231,7 +231,7 @@ DialogParticipantStatus DialogParticipantStatus::apply_restrictions(RestrictedRi } break; case Type::Banned: - // banned can do nothing, even restirctions allows them to do that + // banned can do nothing, even restrictions allows them to do that break; default: UNREACHABLE(); diff --git a/td/telegram/RestrictionReason.cpp b/td/telegram/RestrictionReason.cpp new file mode 100644 index 000000000..081bd4b81 --- /dev/null +++ b/td/telegram/RestrictionReason.cpp @@ -0,0 +1,83 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/RestrictionReason.h" + +#include "td/telegram/ConfigShared.h" +#include "td/telegram/Global.h" + +#include "td/utils/common.h" +#include "td/utils/misc.h" + +#include + +namespace td { + +string get_restriction_reason_description(const vector &restriction_reasons) { + if (restriction_reasons.empty()) { + return string(); + } + auto platform = [] { + if (G()->shared_config().get_option_boolean("ignore_platform_restrictions")) { + return Slice(); + } + +#if TD_ANDROID + return Slice("android"); +#elif TD_WINDOWS + return Slice("ms"); +#elif TD_DARWIN + return Slice("ios"); +#else + return Slice(); +#endif + }(); + + if (!platform.empty()) { + for (auto &restriction_reason : restriction_reasons) { + if (restriction_reason.platform_ == platform) { + return restriction_reason.description_; + } + } + } + + for (auto &restriction_reason : restriction_reasons) { + if (restriction_reason.platform_ == "all") { + return restriction_reason.description_; + } + } + + return string(); +} + +vector get_restriction_reasons(Slice legacy_restriction_reason) { + Slice type; + Slice description; + std::tie(type, description) = split(legacy_restriction_reason, ':'); + auto parts = full_split(type, '-'); + description = trim(description); + + vector result; + if (parts.size() <= 1) { + return result; + } + for (size_t i = 1; i < parts.size(); i++) { + result.emplace_back(parts[i].str(), parts[0].str(), description.str()); + } + return result; +} + +vector get_restriction_reasons( + vector> &&restriction_reasons) { + return transform(std::move(restriction_reasons), + [](telegram_api::object_ptr &&restriction_reason) { + return RestrictionReason(std::move(restriction_reason->platform_), + std::move(restriction_reason->reason_), + std::move(restriction_reason->text_)); + }); +} + +} // namespace td diff --git a/td/telegram/RestrictionReason.h b/td/telegram/RestrictionReason.h new file mode 100644 index 000000000..68464bed9 --- /dev/null +++ b/td/telegram/RestrictionReason.h @@ -0,0 +1,70 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/Slice.h" +#include "td/utils/StringBuilder.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +class RestrictionReason { + string platform_; + string reason_; + string description_; + + friend StringBuilder &operator<<(StringBuilder &string_builder, const RestrictionReason &reason) { + return string_builder << "RestrictionReason[" << reason.platform_ << ", " << reason.reason_ << ", " + << reason.description_ << "]"; + } + + friend bool operator==(const RestrictionReason &lhs, const RestrictionReason &rhs) { + return lhs.platform_ == rhs.platform_ && lhs.reason_ == rhs.reason_ && lhs.description_ == rhs.description_; + } + + friend string get_restriction_reason_description(const vector &restriction_reasons); + + public: + RestrictionReason() = default; + + RestrictionReason(string &&platform, string &&reason, string &&description) + : platform_(std::move(platform)), reason_(std::move(reason)), description_(std::move(description)) { + if (description_.empty()) { + description_ = reason_; + } + } + + template + void store(StorerT &storer) const { + td::store(platform_, storer); + td::store(reason_, storer); + td::store(description_, storer); + } + + template + void parse(ParserT &parser) { + td::parse(platform_, parser); + td::parse(reason_, parser); + td::parse(description_, parser); + } +}; + +inline bool operator!=(const RestrictionReason &lhs, const RestrictionReason &rhs) { + return !(lhs == rhs); +} + +string get_restriction_reason_description(const vector &restriction_reasons); + +vector get_restriction_reasons(Slice legacy_restriction_reason); + +vector get_restriction_reasons( + vector> &&restriction_reasons); + +} // namespace td diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 94ffa486d..3106d1707 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6978,10 +6978,13 @@ void Td::on_request(uint64 id, td_api::setOption &request) { } break; case 'i': + if (set_boolean_option("ignore_background_updates")) { + return; + } if (set_boolean_option("ignore_inline_thumbnails")) { return; } - if (set_boolean_option("ignore_background_updates")) { + if (set_boolean_option("ignore_platform_restrictions")) { return; } if (set_boolean_option("is_emulator")) {