mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	remove dedicated_room dependence on core
This commit is contained in:
		
							parent
							
								
									fa0cb52a5d
								
							
						
					
					
						commit
						28188f13f5
					
				
					 15 changed files with 25 additions and 27 deletions
				
			
		|  | @ -1,4 +1,6 @@ | |||
| add_library(network STATIC | ||||
|     announce_multiplayer_session.cpp | ||||
|     announce_multiplayer_session.h | ||||
|     network.cpp | ||||
|     network.h | ||||
|     network_settings.cpp | ||||
|  |  | |||
							
								
								
									
										164
									
								
								src/network/announce_multiplayer_session.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								src/network/announce_multiplayer_session.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,164 @@ | |||
| // Copyright 2017 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <chrono> | ||||
| #include <future> | ||||
| #include <vector> | ||||
| #include "announce_multiplayer_session.h" | ||||
| #include "common/announce_multiplayer_room.h" | ||||
| #include "common/assert.h" | ||||
| #include "network/network.h" | ||||
| #include "network/network_settings.h" | ||||
| 
 | ||||
| #ifdef ENABLE_WEB_SERVICE | ||||
| #include "web_service/announce_room_json.h" | ||||
| #endif | ||||
| 
 | ||||
| namespace Network { | ||||
| 
 | ||||
| // Time between room is announced to web_service
 | ||||
| static constexpr std::chrono::seconds announce_time_interval(15); | ||||
| 
 | ||||
| AnnounceMultiplayerSession::AnnounceMultiplayerSession() { | ||||
| #ifdef ENABLE_WEB_SERVICE | ||||
|     backend = std::make_unique<WebService::RoomJson>(NetSettings::values.web_api_url, | ||||
|                                                      NetSettings::values.citra_username, | ||||
|                                                      NetSettings::values.citra_token); | ||||
| #else | ||||
|     backend = std::make_unique<AnnounceMultiplayerRoom::NullBackend>(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| Common::WebResult AnnounceMultiplayerSession::Register() { | ||||
|     std::shared_ptr<Network::Room> room = Network::GetRoom().lock(); | ||||
|     if (!room) { | ||||
|         return Common::WebResult{Common::WebResult::Code::LibError, "Network is not initialized"}; | ||||
|     } | ||||
|     if (room->GetState() != Network::Room::State::Open) { | ||||
|         return Common::WebResult{Common::WebResult::Code::LibError, "Room is not open"}; | ||||
|     } | ||||
|     UpdateBackendData(room); | ||||
|     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.returned_data); | ||||
|     registered = true; | ||||
|     return Common::WebResult{Common::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 Common::WebResult&)> function) { | ||||
|     std::lock_guard lock(callback_mutex); | ||||
|     auto handle = std::make_shared<std::function<void(const Common::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<Network::Room::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, room_information.preferred_game_id); | ||||
|     backend->ClearPlayers(); | ||||
|     for (const auto& member : memberlist) { | ||||
|         backend->AddPlayer(member.username, member.nickname, member.avatar_url, member.mac_address, | ||||
|                            member.game_info.id, member.game_info.name); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void AnnounceMultiplayerSession::AnnounceMultiplayerLoop() { | ||||
|     // Invokes all current bound error callbacks.
 | ||||
|     const auto ErrorCallback = [this](Common::WebResult result) { | ||||
|         std::lock_guard<std::mutex> lock(callback_mutex); | ||||
|         for (auto callback : error_callbacks) { | ||||
|             (*callback)(result); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     if (!registered) { | ||||
|         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<Common::WebResult> future; | ||||
|     while (!shutdown_event.WaitUntil(update_time)) { | ||||
|         update_time += announce_time_interval; | ||||
|         std::shared_ptr<Network::Room> room = Network::GetRoom().lock(); | ||||
|         if (!room) { | ||||
|             break; | ||||
|         } | ||||
|         if (room->GetState() != Network::Room::State::Open) { | ||||
|             break; | ||||
|         } | ||||
|         UpdateBackendData(room); | ||||
|         Common::WebResult result = backend->Update(); | ||||
|         if (result.result_code != Common::WebResult::Code::Success) { | ||||
|             ErrorCallback(result); | ||||
|         } | ||||
|         if (result.result_string == "404") { | ||||
|             registered = false; | ||||
|             // Needs to register the room again
 | ||||
|             Common::WebResult result = Register(); | ||||
|             if (result.result_code != Common::WebResult::Code::Success) { | ||||
|                 ErrorCallback(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>(NetSettings::values.web_api_url, | ||||
|                                                      NetSettings::values.citra_username, | ||||
|                                                      NetSettings::values.citra_token); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| } // namespace Network
 | ||||
							
								
								
									
										94
									
								
								src/network/announce_multiplayer_session.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/network/announce_multiplayer_session.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,94 @@ | |||
| // Copyright 2017 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #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; | ||||
| 
 | ||||
| /**
 | ||||
|  * 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 : NonCopyable { | ||||
| public: | ||||
|     using CallbackHandle = std::shared_ptr<std::function<void(const Common::WebResult&)>>; | ||||
|     AnnounceMultiplayerSession(); | ||||
|     ~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 Common::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. | ||||
|      */ | ||||
|     Common::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: | ||||
|     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
 | ||||
| 
 | ||||
|     void UpdateBackendData(std::shared_ptr<Network::Room> room); | ||||
|     void AnnounceMultiplayerLoop(); | ||||
| }; | ||||
| 
 | ||||
| } // namespace Network
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue