mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Fix joining a voice chat.
This commit is contained in:
parent
1291f1c80d
commit
67623072d6
4 changed files with 130 additions and 102 deletions
|
@ -713,98 +713,102 @@ void GroupCall::setMutedAndUpdate(MuteState mute) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GroupCall::handleUpdate(const MTPGroupCall &call) {
|
void GroupCall::handlePossibleCreateOrJoinResponse(
|
||||||
return call.match([&](const MTPDgroupCall &data) {
|
const MTPDupdateGroupCall &data) {
|
||||||
if (_acceptFields) {
|
data.vcall().match([&](const MTPDgroupCall &data) {
|
||||||
if (!_instance && !_id) {
|
handlePossibleCreateOrJoinResponse(data);
|
||||||
join(MTP_inputGroupCall(data.vid(), data.vaccess_hash()));
|
}, [](const MTPDgroupCallDiscarded &data) {
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void GroupCall::handlePossibleCreateOrJoinResponse(
|
||||||
|
const MTPDgroupCall &data) {
|
||||||
|
if (_acceptFields) {
|
||||||
|
if (!_instance && !_id) {
|
||||||
|
join(MTP_inputGroupCall(data.vid(), data.vaccess_hash()));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (_id != data.vid().v
|
||||||
|
|| _accessHash != data.vaccess_hash().v
|
||||||
|
|| !_instance) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto streamDcId = MTP::BareDcId(
|
||||||
|
data.vstream_dc_id().value_or_empty());
|
||||||
|
const auto params = data.vparams();
|
||||||
|
if (!params) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
params->match([&](const MTPDdataJSON &data) {
|
||||||
|
auto error = QJsonParseError{ 0, QJsonParseError::NoError };
|
||||||
|
const auto document = QJsonDocument::fromJson(
|
||||||
|
data.vdata().v,
|
||||||
|
&error);
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
LOG(("API Error: "
|
||||||
|
"Failed to parse group call params, error: %1."
|
||||||
|
).arg(error.errorString()));
|
||||||
return;
|
return;
|
||||||
} else if (_id != data.vid().v
|
} else if (!document.isObject()) {
|
||||||
|| _accessHash != data.vaccess_hash().v
|
LOG(("API Error: "
|
||||||
|| !_instance) {
|
"Not an object received in group call params."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto streamDcId = MTP::BareDcId(
|
|
||||||
data.vstream_dc_id().value_or_empty());
|
|
||||||
if (const auto params = data.vparams()) {
|
|
||||||
params->match([&](const MTPDdataJSON &data) {
|
|
||||||
auto error = QJsonParseError{ 0, QJsonParseError::NoError };
|
|
||||||
const auto document = QJsonDocument::fromJson(
|
|
||||||
data.vdata().v,
|
|
||||||
&error);
|
|
||||||
if (error.error != QJsonParseError::NoError) {
|
|
||||||
LOG(("API Error: "
|
|
||||||
"Failed to parse group call params, error: %1."
|
|
||||||
).arg(error.errorString()));
|
|
||||||
return;
|
|
||||||
} else if (!document.isObject()) {
|
|
||||||
LOG(("API Error: "
|
|
||||||
"Not an object received in group call params."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto guard = gsl::finally([&] {
|
const auto guard = gsl::finally([&] {
|
||||||
addParticipantsToInstance();
|
addParticipantsToInstance();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (document.object().value("stream").toBool()) {
|
if (document.object().value("stream").toBool()) {
|
||||||
if (!streamDcId) {
|
if (!streamDcId) {
|
||||||
LOG(("Api Error: Empty stream_dc_id in groupCall."));
|
LOG(("Api Error: Empty stream_dc_id in groupCall."));
|
||||||
}
|
}
|
||||||
_broadcastDcId = streamDcId
|
_broadcastDcId = streamDcId
|
||||||
? streamDcId
|
? streamDcId
|
||||||
: _peer->session().mtp().mainDcId();
|
: _peer->session().mtp().mainDcId();
|
||||||
setInstanceMode(InstanceMode::Stream);
|
setInstanceMode(InstanceMode::Stream);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto readString = [](
|
const auto readString = [](
|
||||||
const QJsonObject &object,
|
const QJsonObject &object,
|
||||||
const char *key) {
|
const char *key) {
|
||||||
return object.value(key).toString().toStdString();
|
return object.value(key).toString().toStdString();
|
||||||
};
|
};
|
||||||
const auto root = document.object().value("transport").toObject();
|
const auto root = document.object().value("transport").toObject();
|
||||||
auto payload = tgcalls::GroupJoinResponsePayload();
|
auto payload = tgcalls::GroupJoinResponsePayload();
|
||||||
payload.ufrag = readString(root, "ufrag");
|
payload.ufrag = readString(root, "ufrag");
|
||||||
payload.pwd = readString(root, "pwd");
|
payload.pwd = readString(root, "pwd");
|
||||||
const auto prints = root.value("fingerprints").toArray();
|
const auto prints = root.value("fingerprints").toArray();
|
||||||
const auto candidates = root.value("candidates").toArray();
|
const auto candidates = root.value("candidates").toArray();
|
||||||
for (const auto &print : prints) {
|
for (const auto &print : prints) {
|
||||||
const auto object = print.toObject();
|
const auto object = print.toObject();
|
||||||
payload.fingerprints.push_back(tgcalls::GroupJoinPayloadFingerprint{
|
payload.fingerprints.push_back(tgcalls::GroupJoinPayloadFingerprint{
|
||||||
.hash = readString(object, "hash"),
|
.hash = readString(object, "hash"),
|
||||||
.setup = readString(object, "setup"),
|
.setup = readString(object, "setup"),
|
||||||
.fingerprint = readString(object, "fingerprint"),
|
.fingerprint = readString(object, "fingerprint"),
|
||||||
});
|
|
||||||
}
|
|
||||||
for (const auto &candidate : candidates) {
|
|
||||||
const auto object = candidate.toObject();
|
|
||||||
payload.candidates.push_back(tgcalls::GroupJoinResponseCandidate{
|
|
||||||
.port = readString(object, "port"),
|
|
||||||
.protocol = readString(object, "protocol"),
|
|
||||||
.network = readString(object, "network"),
|
|
||||||
.generation = readString(object, "generation"),
|
|
||||||
.id = readString(object, "id"),
|
|
||||||
.component = readString(object, "component"),
|
|
||||||
.foundation = readString(object, "foundation"),
|
|
||||||
.priority = readString(object, "priority"),
|
|
||||||
.ip = readString(object, "ip"),
|
|
||||||
.type = readString(object, "type"),
|
|
||||||
.tcpType = readString(object, "tcpType"),
|
|
||||||
.relAddr = readString(object, "relAddr"),
|
|
||||||
.relPort = readString(object, "relPort"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
setInstanceMode(InstanceMode::Rtc);
|
|
||||||
_instance->setJoinResponsePayload(payload, {});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [&](const MTPDgroupCallDiscarded &data) {
|
for (const auto &candidate : candidates) {
|
||||||
if (data.vid().v == _id) {
|
const auto object = candidate.toObject();
|
||||||
_mySsrc = 0;
|
payload.candidates.push_back(tgcalls::GroupJoinResponseCandidate{
|
||||||
hangup();
|
.port = readString(object, "port"),
|
||||||
|
.protocol = readString(object, "protocol"),
|
||||||
|
.network = readString(object, "network"),
|
||||||
|
.generation = readString(object, "generation"),
|
||||||
|
.id = readString(object, "id"),
|
||||||
|
.component = readString(object, "component"),
|
||||||
|
.foundation = readString(object, "foundation"),
|
||||||
|
.priority = readString(object, "priority"),
|
||||||
|
.ip = readString(object, "ip"),
|
||||||
|
.type = readString(object, "type"),
|
||||||
|
.tcpType = readString(object, "tcpType"),
|
||||||
|
.relAddr = readString(object, "relAddr"),
|
||||||
|
.relPort = readString(object, "relPort"),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
setInstanceMode(InstanceMode::Rtc);
|
||||||
|
_instance->setJoinResponsePayload(payload, {});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -849,7 +853,33 @@ void GroupCall::addPreparedParticipantsDelayed() {
|
||||||
crl::on_main(this, [=] { addPreparedParticipants(); });
|
crl::on_main(this, [=] { addPreparedParticipants(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GroupCall::handleUpdate(const MTPUpdate &update) {
|
||||||
|
update.match([&](const MTPDupdateGroupCall &data) {
|
||||||
|
handleUpdate(data);
|
||||||
|
}, [&](const MTPDupdateGroupCallParticipants &data) {
|
||||||
|
handleUpdate(data);
|
||||||
|
}, [](const auto &) {
|
||||||
|
Unexpected("Type in Instance::applyGroupCallUpdateChecked.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void GroupCall::handleUpdate(const MTPDupdateGroupCall &data) {
|
||||||
|
data.vcall().match([](const MTPDgroupCall &) {
|
||||||
|
}, [&](const MTPDgroupCallDiscarded &data) {
|
||||||
|
if (data.vid().v == _id) {
|
||||||
|
_mySsrc = 0;
|
||||||
|
hangup();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void GroupCall::handleUpdate(const MTPDupdateGroupCallParticipants &data) {
|
void GroupCall::handleUpdate(const MTPDupdateGroupCallParticipants &data) {
|
||||||
|
const auto callId = data.vcall().match([](const auto &data) {
|
||||||
|
return data.vid().v;
|
||||||
|
});
|
||||||
|
if (_id != callId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto state = _state.current();
|
const auto state = _state.current();
|
||||||
if (state != State::Joined && state != State::Connecting) {
|
if (state != State::Joined && state != State::Connecting) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -116,8 +116,8 @@ public:
|
||||||
void rejoinAs(Group::JoinInfo info);
|
void rejoinAs(Group::JoinInfo info);
|
||||||
void rejoinWithHash(const QString &hash);
|
void rejoinWithHash(const QString &hash);
|
||||||
void join(const MTPInputGroupCall &inputCall);
|
void join(const MTPInputGroupCall &inputCall);
|
||||||
void handleUpdate(const MTPGroupCall &call);
|
void handleUpdate(const MTPUpdate &update);
|
||||||
void handleUpdate(const MTPDupdateGroupCallParticipants &data);
|
void handlePossibleCreateOrJoinResponse(const MTPDupdateGroupCall &data);
|
||||||
void changeTitle(const QString &title);
|
void changeTitle(const QString &title);
|
||||||
void toggleRecording(bool enabled, const QString &title);
|
void toggleRecording(bool enabled, const QString &title);
|
||||||
[[nodiscard]] bool recordingStoppedByMe() const {
|
[[nodiscard]] bool recordingStoppedByMe() const {
|
||||||
|
@ -227,6 +227,9 @@ private:
|
||||||
RaiseHand,
|
RaiseHand,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void handlePossibleCreateOrJoinResponse(const MTPDgroupCall &data);
|
||||||
|
void handleUpdate(const MTPDupdateGroupCall &data);
|
||||||
|
void handleUpdate(const MTPDupdateGroupCallParticipants &data);
|
||||||
void handleRequestError(const MTP::Error &error);
|
void handleRequestError(const MTP::Error &error);
|
||||||
void handleControllerError(const QString &error);
|
void handleControllerError(const QString &error);
|
||||||
void ensureControllerCreated();
|
void ensureControllerCreated();
|
||||||
|
|
|
@ -427,28 +427,23 @@ void Instance::handleGroupCallUpdate(
|
||||||
} else {
|
} else {
|
||||||
applyGroupCallUpdateChecked(session, update);
|
applyGroupCallUpdateChecked(session, update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_currentGroupCall
|
||||||
|
&& (&_currentGroupCall->peer()->session() == session)) {
|
||||||
|
update.match([&](const MTPDupdateGroupCall &data) {
|
||||||
|
_currentGroupCall->handlePossibleCreateOrJoinResponse(data);
|
||||||
|
}, [](const auto &) {
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::applyGroupCallUpdateChecked(
|
void Instance::applyGroupCallUpdateChecked(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
const MTPUpdate &update) {
|
const MTPUpdate &update) {
|
||||||
if (!_currentGroupCall
|
if (_currentGroupCall
|
||||||
|| (&_currentGroupCall->peer()->session() != session)) {
|
&& (&_currentGroupCall->peer()->session() == session)) {
|
||||||
return;
|
_currentGroupCall->handleUpdate(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
update.match([&](const MTPDupdateGroupCall &data) {
|
|
||||||
_currentGroupCall->handleUpdate(data.vcall());
|
|
||||||
}, [&](const MTPDupdateGroupCallParticipants &data) {
|
|
||||||
const auto callId = data.vcall().match([](const auto &data) {
|
|
||||||
return data.vid().v;
|
|
||||||
});
|
|
||||||
if (_currentGroupCall->id() == callId) {
|
|
||||||
_currentGroupCall->handleUpdate(data);
|
|
||||||
}
|
|
||||||
}, [](const auto &) {
|
|
||||||
Unexpected("Type in Instance::applyGroupCallUpdateChecked.");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::handleSignalingData(
|
void Instance::handleSignalingData(
|
||||||
|
|
|
@ -137,7 +137,7 @@ private:
|
||||||
mtpRequestId _reloadRequestId = 0;
|
mtpRequestId _reloadRequestId = 0;
|
||||||
rpl::variable<QString> _title;
|
rpl::variable<QString> _title;
|
||||||
|
|
||||||
base::flat_map<std::pair<int,bool>, MTPUpdate> _queuedUpdates;
|
base::flat_multi_map<std::pair<int,bool>, MTPUpdate> _queuedUpdates;
|
||||||
base::Timer _reloadByQueuedUpdatesTimer;
|
base::Timer _reloadByQueuedUpdatesTimer;
|
||||||
|
|
||||||
std::vector<Participant> _participants;
|
std::vector<Participant> _participants;
|
||||||
|
|
Loading…
Add table
Reference in a new issue