From 49f7a56f112fb5bd75c5b58597bd5d1e18da00fb Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 4 Dec 2020 01:56:27 +0300 Subject: [PATCH] Save joined group call synchronization source. --- td/generate/scheme/td_api.tl | 8 ++-- td/generate/scheme/td_api.tlo | Bin 189492 -> 189428 bytes td/telegram/GroupCallManager.cpp | 62 +++++++++++++++++++++++++++---- td/telegram/GroupCallManager.h | 6 ++- td/telegram/Td.cpp | 7 ++-- td/telegram/Td.h | 2 +- td/telegram/cli.cpp | 6 +-- 7 files changed, 70 insertions(+), 21 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index eae0ab4f4..5096b0444 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -4348,11 +4348,11 @@ inviteGroupCallMembers group_call_id:int32 user_ids:vector = Ok; //@group_call_id Group call identifier @user_id User identifier @is_muted Pass true if the user must be muted and false otherwise toggleGroupCallMemberIsMuted group_call_id:int32 user_id:int32 is_muted:Bool = Ok; -//@description Checks group call source for validness. If the method returns an error with a message "GROUP_CALL_JOIN_MISSING", the call needs to be rejoined @group_call_id Group call identifier @source Caller synchronization source identifier -checkGroupCallSource group_call_id:int32 source:int32 = Ok; +//@description Checks whether a group call is still joined. Should be called after connection with the server has been lost. Returns an error with a message "GROUP_CALL_JOIN_MISSING" for non-joined calls @group_call_id Group call identifier +checkGroupCallIsJoined group_call_id:int32 = Ok; -//@description Leaves a group call @group_call_id Group call identifier @source Caller synchronization source identifier -leaveGroupCall group_call_id:int32 source:int32 = Ok; +//@description Leaves a group call @group_call_id Group call identifier +leaveGroupCall group_call_id:int32 = Ok; //@description Discards a group call. Requires can_manage_calls rights in the corresponding chat @group_call_id Group call identifier discardGroupCall group_call_id:int32 = Ok; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 24fab4a2f4a938c7d8519bd9bdf1234ac14d11e5..82d99404622e3559cea68e876a23574dafe4a054 100644 GIT binary patch delta 213 zcmdmTg8R#H?hQ}0Sr)iNS2w@V-u^<{9 delta 209 zcmexzoO{a&?hQ}0St?bJsyDyT-u^F}WnOEHyqkF(+q|zvOhuZH({1CT!=~&e&rNW=> promise; }; @@ -522,6 +525,7 @@ void GroupCallManager::join_group_call(GroupCallId group_call_id, auto &request = pending_join_requests_[input_group_call_id]; request = make_unique(); request->generation = generation; + request->source = source; request->promise = std::move(promise); auto query_promise = @@ -625,6 +629,10 @@ void GroupCallManager::on_join_group_call_response(InputGroupCallId input_group_ LOG(ERROR) << "Failed to parse join response JSON object: " << result.error().message(); it->second->promise.set_error(Status::Error(500, "Receive invalid join group call response payload")); } else { + auto group_call = get_group_call(input_group_call_id); + CHECK(group_call != nullptr); + group_call->is_joined = true; + group_call->source = it->second->source; it->second->promise.set_value(result.move_as_ok()); } pending_join_requests_.erase(it); @@ -685,14 +693,51 @@ void GroupCallManager::toggle_group_call_member_is_muted(GroupCallId group_call_ td_->create_handler(std::move(promise))->send(input_group_call_id, user_id, is_muted); } -void GroupCallManager::check_group_call_source(GroupCallId group_call_id, int32 source, Promise &&promise) { +void GroupCallManager::check_group_call_is_joined(GroupCallId group_call_id, Promise &&promise) { TRY_RESULT_PROMISE(promise, input_group_call_id, get_input_group_call_id(group_call_id)); - td_->create_handler(std::move(promise))->send(input_group_call_id, source); + + auto *group_call = get_group_call(input_group_call_id); + if (group_call == nullptr || !group_call->is_inited || !group_call->is_active || !group_call->is_joined) { + return promise.set_error(Status::Error(400, "GROUP_CALL_JOIN_MISSING")); + } + auto source = group_call->source; + + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), input_group_call_id, source, + promise = std::move(promise)](Result &&result) mutable { + if (result.is_error() && result.error().message() == "GROUP_CALL_JOIN_MISSING") { + send_closure(actor_id, &GroupCallManager::on_group_call_left, input_group_call_id, source); + } + promise.set_result(std::move(result)); + }); + td_->create_handler(std::move(query_promise))->send(input_group_call_id, source); } -void GroupCallManager::leave_group_call(GroupCallId group_call_id, int32 source, Promise &&promise) { +void GroupCallManager::leave_group_call(GroupCallId group_call_id, Promise &&promise) { TRY_RESULT_PROMISE(promise, input_group_call_id, get_input_group_call_id(group_call_id)); - td_->create_handler(std::move(promise))->send(input_group_call_id, source); + + auto *group_call = get_group_call(input_group_call_id); + if (group_call == nullptr || !group_call->is_inited || !group_call->is_active || !group_call->is_joined) { + return promise.set_error(Status::Error(400, "GROUP_CALL_JOIN_MISSING")); + } + auto source = group_call->source; + + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), input_group_call_id, source, + promise = std::move(promise)](Result &&result) mutable { + if (result.is_ok()) { + send_closure(actor_id, &GroupCallManager::on_group_call_left, input_group_call_id, source); + } + promise.set_result(std::move(result)); + }); + td_->create_handler(std::move(query_promise))->send(input_group_call_id, source); +} + +void GroupCallManager::on_group_call_left(InputGroupCallId input_group_call_id, int32 source) { + auto *group_call = get_group_call(input_group_call_id); + CHECK(group_call != nullptr && group_call->is_inited); + if (group_call->is_joined && group_call->source == source) { + group_call->is_joined = false; + group_call->source = 0; + } } void GroupCallManager::discard_group_call(GroupCallId group_call_id, Promise &&promise) { @@ -715,6 +760,7 @@ InputGroupCallId GroupCallManager::update_group_call(const tl_object_ptrget_id()) { case telegram_api::groupCall::ID: { auto group_call = static_cast(group_call_ptr.get()); @@ -725,7 +771,7 @@ InputGroupCallId GroupCallManager::update_group_call(const tl_object_ptrparticipants_count_; call.version = group_call->version_; if (group_call->params_ != nullptr) { - on_join_group_call_response(call_id, std::move(group_call->params_->data_)); + join_params = std::move(group_call->params_->data_); } break; } @@ -753,7 +799,7 @@ InputGroupCallId GroupCallManager::update_group_call(const tl_object_ptris_active) { // never update ended calls } else if (!call.is_active) { - // always update to an ended call + // always update to an ended call, droping also is_joined flag *group_call = std::move(call); need_update = true; } else { @@ -772,10 +818,12 @@ InputGroupCallId GroupCallManager::update_group_call(const tl_object_ptrtd(), &Td::send_update, get_update_group_call_object(group_call)); } - return call_id; } diff --git a/td/telegram/GroupCallManager.h b/td/telegram/GroupCallManager.h index 9661cc0bd..2a125ba05 100644 --- a/td/telegram/GroupCallManager.h +++ b/td/telegram/GroupCallManager.h @@ -49,9 +49,9 @@ class GroupCallManager : public Actor { void toggle_group_call_member_is_muted(GroupCallId group_call_id, UserId user_id, bool is_muted, Promise &&promise); - void check_group_call_source(GroupCallId group_call_id, int32 source, Promise &&promise); + void check_group_call_is_joined(GroupCallId group_call_id, Promise &&promise); - void leave_group_call(GroupCallId group_call_id, int32 source, Promise &&promise); + void leave_group_call(GroupCallId group_call_id, Promise &&promise); void discard_group_call(GroupCallId group_call_id, Promise &&promise); @@ -85,6 +85,8 @@ class GroupCallManager : public Actor { void finish_join_group_call(InputGroupCallId input_group_call_id, uint64 generation, Status error); + void on_group_call_left(InputGroupCallId input_group_call_id, int32 source); + InputGroupCallId update_group_call(const tl_object_ptr &group_call_ptr); static Result> get_group_call_join_response_object( diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 839c29483..98c9cf7cf 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6084,19 +6084,18 @@ void Td::on_request(uint64 id, const td_api::toggleGroupCallMemberIsMuted &reque request.is_muted_, std::move(promise)); } -void Td::on_request(uint64 id, const td_api::checkGroupCallSource &request) { +void Td::on_request(uint64 id, const td_api::checkGroupCallIsJoined &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->check_group_call_source(GroupCallId(request.group_call_id_), request.source_, - std::move(promise)); + group_call_manager_->check_group_call_is_joined(GroupCallId(request.group_call_id_), std::move(promise)); } void Td::on_request(uint64 id, const td_api::leaveGroupCall &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->leave_group_call(GroupCallId(request.group_call_id_), request.source_, std::move(promise)); + group_call_manager_->leave_group_call(GroupCallId(request.group_call_id_), std::move(promise)); } void Td::on_request(uint64 id, const td_api::discardGroupCall &request) { diff --git a/td/telegram/Td.h b/td/telegram/Td.h index b675bd536..4052064af 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -704,7 +704,7 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, const td_api::toggleGroupCallMemberIsMuted &request); - void on_request(uint64 id, const td_api::checkGroupCallSource &request); + void on_request(uint64 id, const td_api::checkGroupCallIsJoined &request); void on_request(uint64 id, const td_api::leaveGroupCall &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index e4b6f8df0..e2f1604ab 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2867,10 +2867,10 @@ class CliClient final : public Actor { std::tie(user_id, is_muted) = split(args); send_request(td_api::make_object(as_group_call_id(group_call_id), as_user_id(user_id), as_bool(is_muted))); - } else if (op == "cgcs") { - send_request(td_api::make_object(as_group_call_id(args), 123)); + } else if (op == "cgcij") { + send_request(td_api::make_object(as_group_call_id(args))); } else if (op == "lgc") { - send_request(td_api::make_object(as_group_call_id(args), 123)); + send_request(td_api::make_object(as_group_call_id(args))); } else if (op == "dgc") { send_request(td_api::make_object(as_group_call_id(args))); } else if (op == "gcil") {