From 36051204cc24eafa96aef97f5bbe323d473227ac Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Fri, 19 Apr 2019 22:55:49 +0800 Subject: [PATCH] core, web_service: Check for error when registering rooms The `Register()` function can now handle error results and the error will be passed immediately to the Qt frontend, instead of being ignored silently and failing later with a "Room is not registered". --- src/citra_qt/multiplayer/host_room.cpp | 18 ++++++++++- src/citra_qt/multiplayer/state.cpp | 13 +++----- src/common/announce_multiplayer_room.h | 9 +++--- src/core/announce_multiplayer_session.cpp | 39 ++++++++++++++++------- src/core/announce_multiplayer_session.h | 7 ++-- src/web_service/announce_room_json.cpp | 12 +++---- src/web_service/announce_room_json.h | 2 +- 7 files changed, 67 insertions(+), 33 deletions(-) diff --git a/src/citra_qt/multiplayer/host_room.cpp b/src/citra_qt/multiplayer/host_room.cpp index 2dbc74d6c..2a815fa2c 100644 --- a/src/citra_qt/multiplayer/host_room.cpp +++ b/src/citra_qt/multiplayer/host_room.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -148,7 +149,22 @@ void HostRoomWindow::Host() { if (is_public) { if (auto session = announce_multiplayer_session.lock()) { // Register the room first to ensure verify_UID is present when we connect - session->Register(); + Common::WebResult result = session->Register(); + if (result.result_code != Common::WebResult::Code::Success) { + QMessageBox::warning( + this, tr("Error"), + tr("Failed to announce the room to the public lobby. In order to host a " + "room publicly, you must have a valid Citra account configured in " + "Emulation -> Configure -> Web. If you do not want to publish a room in " + "the public lobby, then select Unlisted instead.\nDebug Message: ") + + QString::fromStdString(result.result_string), + QMessageBox::Ok); + ui->host->setEnabled(true); + if (auto room = Network::GetRoom().lock()) { + room->Destroy(); + } + return; + } session->Start(); } else { LOG_ERROR(Network, "Starting announce session failed"); diff --git a/src/citra_qt/multiplayer/state.cpp b/src/citra_qt/multiplayer/state.cpp index 121d76b90..809bcddca 100644 --- a/src/citra_qt/multiplayer/state.cpp +++ b/src/citra_qt/multiplayer/state.cpp @@ -174,14 +174,11 @@ void MultiplayerState::OnNetworkError(const Network::RoomMember::Error& error) { void MultiplayerState::OnAnnounceFailed(const Common::WebResult& result) { announce_multiplayer_session->Stop(); - QMessageBox::warning( - this, tr("Error"), - tr("Failed to announce the room to the public lobby. In order to host a room publicly, you " - "must have a valid Citra account configured in Emulation -> Configure -> Web. If you do " - "not want to publish a room in the public lobby, then select Unlisted instead.\n" - "Debug Message: ") + - QString::fromStdString(result.result_string), - QMessageBox::Ok); + QMessageBox::warning(this, tr("Error"), + tr("Failed to update the room information. Please check your Internet " + "connection and try hosting the room again.\nDebug Message: ") + + QString::fromStdString(result.result_string), + QMessageBox::Ok); } void MultiplayerState::UpdateThemedIcons() { diff --git a/src/common/announce_multiplayer_room.h b/src/common/announce_multiplayer_room.h index f0cf79386..b6e94b7a2 100644 --- a/src/common/announce_multiplayer_room.h +++ b/src/common/announce_multiplayer_room.h @@ -83,9 +83,10 @@ public: /** * Registers the data in the announce service - * @result A global Guid of the room which may be used for verification + * @result The result of the register attempt. When the result code is Success, A global Guid of + * the room which may be used for verification will be in the result's returned_data. */ - virtual std::string Register() = 0; + virtual Common::WebResult Register() = 0; /** * Empties the stored players @@ -121,8 +122,8 @@ public: Common::WebResult Update() override { return Common::WebResult{Common::WebResult::Code::NoWebservice, "WebService is missing"}; } - std::string Register() override { - return ""; + Common::WebResult Register() override { + return Common::WebResult{Common::WebResult::Code::NoWebservice, "WebService is missing"}; } void ClearPlayers() override {} RoomList GetRoomList() override { diff --git a/src/core/announce_multiplayer_session.cpp b/src/core/announce_multiplayer_session.cpp index afe522c25..90293ec92 100644 --- a/src/core/announce_multiplayer_session.cpp +++ b/src/core/announce_multiplayer_session.cpp @@ -29,19 +29,23 @@ AnnounceMultiplayerSession::AnnounceMultiplayerSession() { #endif } -void AnnounceMultiplayerSession::Register() { +Common::WebResult AnnounceMultiplayerSession::Register() { std::shared_ptr room = Network::GetRoom().lock(); if (!room) { - return; + return Common::WebResult{Common::WebResult::Code::LibError, "Network is not initialized"}; } if (room->GetState() != Network::Room::State::Open) { - return; + return Common::WebResult{Common::WebResult::Code::LibError, "Room is not open"}; } UpdateBackendData(room); - std::string result = backend->Register(); + Common::WebResult result = backend->Register(); + if (result.result_code != Common::WebResult::Code::Success) { + return result; + } LOG_INFO(WebService, "Room has been registered"); - room->SetVerifyUID(result); + room->SetVerifyUID(result.returned_data); registered = true; + return Common::WebResult{Common::WebResult::Code::Success}; } void AnnounceMultiplayerSession::Start() { @@ -95,9 +99,22 @@ void AnnounceMultiplayerSession::UpdateBackendData(std::shared_ptr lock(callback_mutex); + for (auto callback : error_callbacks) { + (*callback)(result); + } + }; + if (!registered) { - Register(); + Common::WebResult result = Register(); + if (result.result_code != Common::WebResult::Code::Success) { + ErrorCallback(result); + return; + } } + auto update_time = std::chrono::steady_clock::now(); std::future future; while (!shutdown_event.WaitUntil(update_time)) { @@ -112,15 +129,15 @@ void AnnounceMultiplayerSession::AnnounceMultiplayerLoop() { UpdateBackendData(room); Common::WebResult result = backend->Update(); if (result.result_code != Common::WebResult::Code::Success) { - std::lock_guard lock(callback_mutex); - for (auto callback : error_callbacks) { - (*callback)(result); - } + ErrorCallback(result); } if (result.result_string == "404") { registered = false; // Needs to register the room again - Register(); + Common::WebResult result = Register(); + if (result.result_code != Common::WebResult::Code::Success) { + ErrorCallback(result); + } } } } diff --git a/src/core/announce_multiplayer_session.h b/src/core/announce_multiplayer_session.h index 79b30fb24..07e09a448 100644 --- a/src/core/announce_multiplayer_session.h +++ b/src/core/announce_multiplayer_session.h @@ -44,8 +44,11 @@ public: */ void UnbindErrorCallback(CallbackHandle handle); - /// Registers a room to web services - void Register(); + /** + * Registers a room to web services + * @return The result of the registration attempt. + */ + Common::WebResult Register(); /** * Starts the announce of a room to web services diff --git a/src/web_service/announce_room_json.cpp b/src/web_service/announce_room_json.cpp index 2d2601256..44d0b0578 100644 --- a/src/web_service/announce_room_json.cpp +++ b/src/web_service/announce_room_json.cpp @@ -117,16 +117,16 @@ Common::WebResult RoomJson::Update() { return client.PostJson(fmt::format("/lobby/{}", room_id), json.dump(), false); } -std::string RoomJson::Register() { +Common::WebResult RoomJson::Register() { nlohmann::json json = room; - auto reply = client.PostJson("/lobby", json.dump(), false).returned_data; - if (reply.empty()) { - return ""; + auto result = client.PostJson("/lobby", json.dump(), false); + if (result.result_code != Common::WebResult::Code::Success) { + return result; } - auto reply_json = nlohmann::json::parse(reply); + auto reply_json = nlohmann::json::parse(result.returned_data); room = reply_json.get(); room_id = reply_json.at("id").get(); - return room.verify_UID; + return Common::WebResult{Common::WebResult::Code::Success, "", room.verify_UID}; } void RoomJson::ClearPlayers() { diff --git a/src/web_service/announce_room_json.h b/src/web_service/announce_room_json.h index 16d630863..b87af60eb 100644 --- a/src/web_service/announce_room_json.h +++ b/src/web_service/announce_room_json.h @@ -29,7 +29,7 @@ public: const AnnounceMultiplayerRoom::MacAddress& mac_address, const u64 game_id, const std::string& game_name) override; Common::WebResult Update() override; - std::string Register() override; + Common::WebResult Register() override; void ClearPlayers() override; AnnounceMultiplayerRoom::RoomList GetRoomList() override; void Delete() override;