From b904652d69fb3d3bf1918a7dd7f04bc049c9f460 Mon Sep 17 00:00:00 2001 From: FearlessTobi Date: Tue, 16 Aug 2022 23:13:05 +0200 Subject: yuzu_room: Remove dependency on core --- src/core/CMakeLists.txt | 2 - src/core/announce_multiplayer_session.cpp | 164 --------------------------- src/core/announce_multiplayer_session.h | 98 ---------------- src/dedicated_room/CMakeLists.txt | 2 +- src/dedicated_room/yuzu_room.cpp | 2 +- src/network/CMakeLists.txt | 6 + src/network/announce_multiplayer_session.cpp | 164 +++++++++++++++++++++++++++ src/network/announce_multiplayer_session.h | 98 ++++++++++++++++ src/yuzu/multiplayer/chat_room.cpp | 2 +- src/yuzu/multiplayer/client_room.cpp | 2 +- src/yuzu/multiplayer/host_room.cpp | 2 +- src/yuzu/multiplayer/lobby.h | 2 +- src/yuzu/multiplayer/state.h | 2 +- 13 files changed, 275 insertions(+), 271 deletions(-) delete mode 100644 src/core/announce_multiplayer_session.cpp delete mode 100644 src/core/announce_multiplayer_session.h create mode 100644 src/network/announce_multiplayer_session.cpp create mode 100644 src/network/announce_multiplayer_session.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 8db9a3c65..25b39c52b 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -2,8 +2,6 @@ # SPDX-License-Identifier: GPL-2.0-or-later add_library(core STATIC - announce_multiplayer_session.cpp - announce_multiplayer_session.h arm/arm_interface.h arm/arm_interface.cpp arm/dynarmic/arm_dynarmic_32.cpp diff --git a/src/core/announce_multiplayer_session.cpp b/src/core/announce_multiplayer_session.cpp deleted file mode 100644 index 6737ce85a..000000000 --- a/src/core/announce_multiplayer_session.cpp +++ /dev/null @@ -1,164 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include -#include -#include "announce_multiplayer_session.h" -#include "common/announce_multiplayer_room.h" -#include "common/assert.h" -#include "common/settings.h" -#include "network/network.h" - -#ifdef ENABLE_WEB_SERVICE -#include "web_service/announce_room_json.h" -#endif - -namespace Core { - -// Time between room is announced to web_service -static constexpr std::chrono::seconds announce_time_interval(15); - -AnnounceMultiplayerSession::AnnounceMultiplayerSession(Network::RoomNetwork& room_network_) - : room_network{room_network_} { -#ifdef ENABLE_WEB_SERVICE - backend = std::make_unique(Settings::values.web_api_url.GetValue(), - Settings::values.yuzu_username.GetValue(), - Settings::values.yuzu_token.GetValue()); -#else - backend = std::make_unique(); -#endif -} - -WebService::WebResult AnnounceMultiplayerSession::Register() { - auto room = room_network.GetRoom().lock(); - if (!room) { - return WebService::WebResult{WebService::WebResult::Code::LibError, - "Network is not initialized", ""}; - } - if (room->GetState() != Network::Room::State::Open) { - return WebService::WebResult{WebService::WebResult::Code::LibError, "Room is not open", ""}; - } - UpdateBackendData(room); - WebService::WebResult result = backend->Register(); - if (result.result_code != WebService::WebResult::Code::Success) { - return result; - } - LOG_INFO(WebService, "Room has been registered"); - room->SetVerifyUID(result.returned_data); - registered = true; - return WebService::WebResult{WebService::WebResult::Code::Success, "", ""}; -} - -void AnnounceMultiplayerSession::Start() { - if (announce_multiplayer_thread) { - Stop(); - } - shutdown_event.Reset(); - announce_multiplayer_thread = - std::make_unique(&AnnounceMultiplayerSession::AnnounceMultiplayerLoop, this); -} - -void AnnounceMultiplayerSession::Stop() { - if (announce_multiplayer_thread) { - shutdown_event.Set(); - announce_multiplayer_thread->join(); - announce_multiplayer_thread.reset(); - backend->Delete(); - registered = false; - } -} - -AnnounceMultiplayerSession::CallbackHandle AnnounceMultiplayerSession::BindErrorCallback( - std::function function) { - std::lock_guard lock(callback_mutex); - auto handle = std::make_shared>(function); - error_callbacks.insert(handle); - return handle; -} - -void AnnounceMultiplayerSession::UnbindErrorCallback(CallbackHandle handle) { - std::lock_guard lock(callback_mutex); - error_callbacks.erase(handle); -} - -AnnounceMultiplayerSession::~AnnounceMultiplayerSession() { - Stop(); -} - -void AnnounceMultiplayerSession::UpdateBackendData(std::shared_ptr room) { - Network::RoomInformation room_information = room->GetRoomInformation(); - std::vector memberlist = room->GetRoomMemberList(); - backend->SetRoomInformation(room_information.name, room_information.description, - room_information.port, room_information.member_slots, - Network::network_version, room->HasPassword(), - room_information.preferred_game); - backend->ClearPlayers(); - for (const auto& member : memberlist) { - backend->AddPlayer(member); - } -} - -void AnnounceMultiplayerSession::AnnounceMultiplayerLoop() { - // Invokes all current bound error callbacks. - const auto ErrorCallback = [this](WebService::WebResult result) { - std::lock_guard lock(callback_mutex); - for (auto callback : error_callbacks) { - (*callback)(result); - } - }; - - if (!registered) { - WebService::WebResult result = Register(); - if (result.result_code != WebService::WebResult::Code::Success) { - ErrorCallback(result); - return; - } - } - - auto update_time = std::chrono::steady_clock::now(); - std::future future; - while (!shutdown_event.WaitUntil(update_time)) { - update_time += announce_time_interval; - auto room = room_network.GetRoom().lock(); - if (!room) { - break; - } - if (room->GetState() != Network::Room::State::Open) { - break; - } - UpdateBackendData(room); - WebService::WebResult result = backend->Update(); - if (result.result_code != WebService::WebResult::Code::Success) { - ErrorCallback(result); - } - if (result.result_string == "404") { - registered = false; - // Needs to register the room again - WebService::WebResult register_result = Register(); - if (register_result.result_code != WebService::WebResult::Code::Success) { - ErrorCallback(register_result); - } - } - } -} - -AnnounceMultiplayerRoom::RoomList AnnounceMultiplayerSession::GetRoomList() { - return backend->GetRoomList(); -} - -bool AnnounceMultiplayerSession::IsRunning() const { - return announce_multiplayer_thread != nullptr; -} - -void AnnounceMultiplayerSession::UpdateCredentials() { - ASSERT_MSG(!IsRunning(), "Credentials can only be updated when session is not running"); - -#ifdef ENABLE_WEB_SERVICE - backend = std::make_unique(Settings::values.web_api_url.GetValue(), - Settings::values.yuzu_username.GetValue(), - Settings::values.yuzu_token.GetValue()); -#endif -} - -} // namespace Core diff --git a/src/core/announce_multiplayer_session.h b/src/core/announce_multiplayer_session.h deleted file mode 100644 index db790f7d2..000000000 --- a/src/core/announce_multiplayer_session.h +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include -#include -#include -#include -#include "common/announce_multiplayer_room.h" -#include "common/common_types.h" -#include "common/thread.h" - -namespace Network { -class Room; -class RoomNetwork; -} // namespace Network - -namespace Core { - -/** - * Instruments AnnounceMultiplayerRoom::Backend. - * Creates a thread that regularly updates the room information and submits them - * An async get of room information is also possible - */ -class AnnounceMultiplayerSession { -public: - using CallbackHandle = std::shared_ptr>; - AnnounceMultiplayerSession(Network::RoomNetwork& room_network_); - ~AnnounceMultiplayerSession(); - - /** - * Allows to bind a function that will get called if the announce encounters an error - * @param function The function that gets called - * @return A handle that can be used the unbind the function - */ - CallbackHandle BindErrorCallback(std::function function); - - /** - * Unbind a function from the error callbacks - * @param handle The handle for the function that should get unbind - */ - void UnbindErrorCallback(CallbackHandle handle); - - /** - * Registers a room to web services - * @return The result of the registration attempt. - */ - WebService::WebResult Register(); - - /** - * Starts the announce of a room to web services - */ - void Start(); - - /** - * Stops the announce to web services - */ - void Stop(); - - /** - * Returns a list of all room information the backend got - * @param func A function that gets executed when the async get finished, e.g. a signal - * @return a list of rooms received from the web service - */ - AnnounceMultiplayerRoom::RoomList GetRoomList(); - - /** - * Whether the announce session is still running - */ - bool IsRunning() const; - - /** - * Recreates the backend, updating the credentials. - * This can only be used when the announce session is not running. - */ - void UpdateCredentials(); - -private: - void UpdateBackendData(std::shared_ptr room); - void AnnounceMultiplayerLoop(); - - Common::Event shutdown_event; - std::mutex callback_mutex; - std::set error_callbacks; - std::unique_ptr announce_multiplayer_thread; - - /// Backend interface that logs fields - std::unique_ptr backend; - - std::atomic_bool registered = false; ///< Whether the room has been registered - - Network::RoomNetwork& room_network; -}; - -} // namespace Core diff --git a/src/dedicated_room/CMakeLists.txt b/src/dedicated_room/CMakeLists.txt index b674b915b..737aedbe4 100644 --- a/src/dedicated_room/CMakeLists.txt +++ b/src/dedicated_room/CMakeLists.txt @@ -10,7 +10,7 @@ add_executable(yuzu-room create_target_directory_groups(yuzu-room) -target_link_libraries(yuzu-room PRIVATE common core network) +target_link_libraries(yuzu-room PRIVATE common network) if (ENABLE_WEB_SERVICE) target_compile_definitions(yuzu-room PRIVATE -DENABLE_WEB_SERVICE) target_link_libraries(yuzu-room PRIVATE web_service) diff --git a/src/dedicated_room/yuzu_room.cpp b/src/dedicated_room/yuzu_room.cpp index 482e772fb..7c1a75de3 100644 --- a/src/dedicated_room/yuzu_room.cpp +++ b/src/dedicated_room/yuzu_room.cpp @@ -27,8 +27,8 @@ #include "common/scm_rev.h" #include "common/settings.h" #include "common/string_util.h" -#include "core/announce_multiplayer_session.h" #include "core/core.h" +#include "network/announce_multiplayer_session.h" #include "network/network.h" #include "network/room.h" #include "network/verify_user.h" diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 312f79b68..6f8ca4b90 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -2,6 +2,8 @@ # SPDX-License-Identifier: GPL-3.0-or-later add_library(network STATIC + announce_multiplayer_session.cpp + announce_multiplayer_session.h network.cpp network.h packet.cpp @@ -17,3 +19,7 @@ add_library(network STATIC create_target_directory_groups(network) target_link_libraries(network PRIVATE common enet Boost::boost) +if (ENABLE_WEB_SERVICE) + target_compile_definitions(network PRIVATE -DENABLE_WEB_SERVICE) + target_link_libraries(network PRIVATE web_service) +endif() diff --git a/src/network/announce_multiplayer_session.cpp b/src/network/announce_multiplayer_session.cpp new file mode 100644 index 000000000..6737ce85a --- /dev/null +++ b/src/network/announce_multiplayer_session.cpp @@ -0,0 +1,164 @@ +// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include "announce_multiplayer_session.h" +#include "common/announce_multiplayer_room.h" +#include "common/assert.h" +#include "common/settings.h" +#include "network/network.h" + +#ifdef ENABLE_WEB_SERVICE +#include "web_service/announce_room_json.h" +#endif + +namespace Core { + +// Time between room is announced to web_service +static constexpr std::chrono::seconds announce_time_interval(15); + +AnnounceMultiplayerSession::AnnounceMultiplayerSession(Network::RoomNetwork& room_network_) + : room_network{room_network_} { +#ifdef ENABLE_WEB_SERVICE + backend = std::make_unique(Settings::values.web_api_url.GetValue(), + Settings::values.yuzu_username.GetValue(), + Settings::values.yuzu_token.GetValue()); +#else + backend = std::make_unique(); +#endif +} + +WebService::WebResult AnnounceMultiplayerSession::Register() { + auto room = room_network.GetRoom().lock(); + if (!room) { + return WebService::WebResult{WebService::WebResult::Code::LibError, + "Network is not initialized", ""}; + } + if (room->GetState() != Network::Room::State::Open) { + return WebService::WebResult{WebService::WebResult::Code::LibError, "Room is not open", ""}; + } + UpdateBackendData(room); + WebService::WebResult result = backend->Register(); + if (result.result_code != WebService::WebResult::Code::Success) { + return result; + } + LOG_INFO(WebService, "Room has been registered"); + room->SetVerifyUID(result.returned_data); + registered = true; + return WebService::WebResult{WebService::WebResult::Code::Success, "", ""}; +} + +void AnnounceMultiplayerSession::Start() { + if (announce_multiplayer_thread) { + Stop(); + } + shutdown_event.Reset(); + announce_multiplayer_thread = + std::make_unique(&AnnounceMultiplayerSession::AnnounceMultiplayerLoop, this); +} + +void AnnounceMultiplayerSession::Stop() { + if (announce_multiplayer_thread) { + shutdown_event.Set(); + announce_multiplayer_thread->join(); + announce_multiplayer_thread.reset(); + backend->Delete(); + registered = false; + } +} + +AnnounceMultiplayerSession::CallbackHandle AnnounceMultiplayerSession::BindErrorCallback( + std::function function) { + std::lock_guard lock(callback_mutex); + auto handle = std::make_shared>(function); + error_callbacks.insert(handle); + return handle; +} + +void AnnounceMultiplayerSession::UnbindErrorCallback(CallbackHandle handle) { + std::lock_guard lock(callback_mutex); + error_callbacks.erase(handle); +} + +AnnounceMultiplayerSession::~AnnounceMultiplayerSession() { + Stop(); +} + +void AnnounceMultiplayerSession::UpdateBackendData(std::shared_ptr room) { + Network::RoomInformation room_information = room->GetRoomInformation(); + std::vector memberlist = room->GetRoomMemberList(); + backend->SetRoomInformation(room_information.name, room_information.description, + room_information.port, room_information.member_slots, + Network::network_version, room->HasPassword(), + room_information.preferred_game); + backend->ClearPlayers(); + for (const auto& member : memberlist) { + backend->AddPlayer(member); + } +} + +void AnnounceMultiplayerSession::AnnounceMultiplayerLoop() { + // Invokes all current bound error callbacks. + const auto ErrorCallback = [this](WebService::WebResult result) { + std::lock_guard lock(callback_mutex); + for (auto callback : error_callbacks) { + (*callback)(result); + } + }; + + if (!registered) { + WebService::WebResult result = Register(); + if (result.result_code != WebService::WebResult::Code::Success) { + ErrorCallback(result); + return; + } + } + + auto update_time = std::chrono::steady_clock::now(); + std::future future; + while (!shutdown_event.WaitUntil(update_time)) { + update_time += announce_time_interval; + auto room = room_network.GetRoom().lock(); + if (!room) { + break; + } + if (room->GetState() != Network::Room::State::Open) { + break; + } + UpdateBackendData(room); + WebService::WebResult result = backend->Update(); + if (result.result_code != WebService::WebResult::Code::Success) { + ErrorCallback(result); + } + if (result.result_string == "404") { + registered = false; + // Needs to register the room again + WebService::WebResult register_result = Register(); + if (register_result.result_code != WebService::WebResult::Code::Success) { + ErrorCallback(register_result); + } + } + } +} + +AnnounceMultiplayerRoom::RoomList AnnounceMultiplayerSession::GetRoomList() { + return backend->GetRoomList(); +} + +bool AnnounceMultiplayerSession::IsRunning() const { + return announce_multiplayer_thread != nullptr; +} + +void AnnounceMultiplayerSession::UpdateCredentials() { + ASSERT_MSG(!IsRunning(), "Credentials can only be updated when session is not running"); + +#ifdef ENABLE_WEB_SERVICE + backend = std::make_unique(Settings::values.web_api_url.GetValue(), + Settings::values.yuzu_username.GetValue(), + Settings::values.yuzu_token.GetValue()); +#endif +} + +} // namespace Core diff --git a/src/network/announce_multiplayer_session.h b/src/network/announce_multiplayer_session.h new file mode 100644 index 000000000..db790f7d2 --- /dev/null +++ b/src/network/announce_multiplayer_session.h @@ -0,0 +1,98 @@ +// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "common/announce_multiplayer_room.h" +#include "common/common_types.h" +#include "common/thread.h" + +namespace Network { +class Room; +class RoomNetwork; +} // namespace Network + +namespace Core { + +/** + * Instruments AnnounceMultiplayerRoom::Backend. + * Creates a thread that regularly updates the room information and submits them + * An async get of room information is also possible + */ +class AnnounceMultiplayerSession { +public: + using CallbackHandle = std::shared_ptr>; + AnnounceMultiplayerSession(Network::RoomNetwork& room_network_); + ~AnnounceMultiplayerSession(); + + /** + * Allows to bind a function that will get called if the announce encounters an error + * @param function The function that gets called + * @return A handle that can be used the unbind the function + */ + CallbackHandle BindErrorCallback(std::function function); + + /** + * Unbind a function from the error callbacks + * @param handle The handle for the function that should get unbind + */ + void UnbindErrorCallback(CallbackHandle handle); + + /** + * Registers a room to web services + * @return The result of the registration attempt. + */ + WebService::WebResult Register(); + + /** + * Starts the announce of a room to web services + */ + void Start(); + + /** + * Stops the announce to web services + */ + void Stop(); + + /** + * Returns a list of all room information the backend got + * @param func A function that gets executed when the async get finished, e.g. a signal + * @return a list of rooms received from the web service + */ + AnnounceMultiplayerRoom::RoomList GetRoomList(); + + /** + * Whether the announce session is still running + */ + bool IsRunning() const; + + /** + * Recreates the backend, updating the credentials. + * This can only be used when the announce session is not running. + */ + void UpdateCredentials(); + +private: + void UpdateBackendData(std::shared_ptr room); + void AnnounceMultiplayerLoop(); + + Common::Event shutdown_event; + std::mutex callback_mutex; + std::set error_callbacks; + std::unique_ptr announce_multiplayer_thread; + + /// Backend interface that logs fields + std::unique_ptr backend; + + std::atomic_bool registered = false; ///< Whether the room has been registered + + Network::RoomNetwork& room_network; +}; + +} // namespace Core diff --git a/src/yuzu/multiplayer/chat_room.cpp b/src/yuzu/multiplayer/chat_room.cpp index 1968a3c75..51ece1f21 100644 --- a/src/yuzu/multiplayer/chat_room.cpp +++ b/src/yuzu/multiplayer/chat_room.cpp @@ -16,7 +16,7 @@ #include #include #include "common/logging/log.h" -#include "core/announce_multiplayer_session.h" +#include "network/announce_multiplayer_session.h" #include "ui_chat_room.h" #include "yuzu/game_list_p.h" #include "yuzu/multiplayer/chat_room.h" diff --git a/src/yuzu/multiplayer/client_room.cpp b/src/yuzu/multiplayer/client_room.cpp index 86baafbf0..b34a8d004 100644 --- a/src/yuzu/multiplayer/client_room.cpp +++ b/src/yuzu/multiplayer/client_room.cpp @@ -10,7 +10,7 @@ #include #include #include "common/logging/log.h" -#include "core/announce_multiplayer_session.h" +#include "network/announce_multiplayer_session.h" #include "ui_client_room.h" #include "yuzu/game_list_p.h" #include "yuzu/multiplayer/client_room.h" diff --git a/src/yuzu/multiplayer/host_room.cpp b/src/yuzu/multiplayer/host_room.cpp index d70a9a3c8..8e7a81291 100644 --- a/src/yuzu/multiplayer/host_room.cpp +++ b/src/yuzu/multiplayer/host_room.cpp @@ -12,7 +12,7 @@ #include #include "common/logging/log.h" #include "common/settings.h" -#include "core/announce_multiplayer_session.h" +#include "network/announce_multiplayer_session.h" #include "ui_host_room.h" #include "yuzu/game_list_p.h" #include "yuzu/main.h" diff --git a/src/yuzu/multiplayer/lobby.h b/src/yuzu/multiplayer/lobby.h index 82744ca94..02cc766e4 100644 --- a/src/yuzu/multiplayer/lobby.h +++ b/src/yuzu/multiplayer/lobby.h @@ -9,7 +9,7 @@ #include #include #include "common/announce_multiplayer_room.h" -#include "core/announce_multiplayer_session.h" +#include "network/announce_multiplayer_session.h" #include "network/network.h" #include "yuzu/multiplayer/validation.h" diff --git a/src/yuzu/multiplayer/state.h b/src/yuzu/multiplayer/state.h index 9c60712d5..23960414e 100644 --- a/src/yuzu/multiplayer/state.h +++ b/src/yuzu/multiplayer/state.h @@ -4,7 +4,7 @@ #pragma once #include -#include "core/announce_multiplayer_session.h" +#include "network/announce_multiplayer_session.h" #include "network/network.h" class QStandardItemModel; -- cgit v1.2.3