yuzu_room: Remove dependency on core
This commit is contained in:
parent
d1ef4b2b86
commit
b904652d69
11 changed files with 13 additions and 9 deletions
|
@ -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()
|
||||
|
|
164
src/network/announce_multiplayer_session.cpp
Normal file
164
src/network/announce_multiplayer_session.cpp
Normal file
|
@ -0,0 +1,164 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <chrono>
|
||||
#include <future>
|
||||
#include <vector>
|
||||
#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<WebService::RoomJson>(Settings::values.web_api_url.GetValue(),
|
||||
Settings::values.yuzu_username.GetValue(),
|
||||
Settings::values.yuzu_token.GetValue());
|
||||
#else
|
||||
backend = std::make_unique<AnnounceMultiplayerRoom::NullBackend>();
|
||||
#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<std::thread>(&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<void(const WebService::WebResult&)> function) {
|
||||
std::lock_guard lock(callback_mutex);
|
||||
auto handle = std::make_shared<std::function<void(const WebService::WebResult&)>>(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<Network::Room> room) {
|
||||
Network::RoomInformation room_information = room->GetRoomInformation();
|
||||
std::vector<AnnounceMultiplayerRoom::Member> 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<WebService::WebResult> 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<WebService::RoomJson>(Settings::values.web_api_url.GetValue(),
|
||||
Settings::values.yuzu_username.GetValue(),
|
||||
Settings::values.yuzu_token.GetValue());
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace Core
|
98
src/network/announce_multiplayer_session.h
Normal file
98
src/network/announce_multiplayer_session.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <thread>
|
||||
#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<std::function<void(const WebService::WebResult&)>>;
|
||||
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<void(const WebService::WebResult&)> 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<Network::Room> room);
|
||||
void AnnounceMultiplayerLoop();
|
||||
|
||||
Common::Event shutdown_event;
|
||||
std::mutex callback_mutex;
|
||||
std::set<CallbackHandle> error_callbacks;
|
||||
std::unique_ptr<std::thread> announce_multiplayer_thread;
|
||||
|
||||
/// Backend interface that logs fields
|
||||
std::unique_ptr<AnnounceMultiplayerRoom::Backend> backend;
|
||||
|
||||
std::atomic_bool registered = false; ///< Whether the room has been registered
|
||||
|
||||
Network::RoomNetwork& room_network;
|
||||
};
|
||||
|
||||
} // namespace Core
|
Loading…
Add table
Add a link
Reference in a new issue