mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Merge pull request #3069 from B3n30/announce_room_webservice
Announce room webservice
This commit is contained in:
		
						commit
						3c03da12c8
					
				
					 15 changed files with 584 additions and 20 deletions
				
			
		|  | @ -1,5 +1,7 @@ | |||
| add_library(core STATIC | ||||
|     3ds.h | ||||
|     announce_multiplayer_session.cpp | ||||
|     announce_multiplayer_session.h | ||||
|     arm/arm_interface.h | ||||
|     arm/dyncom/arm_dyncom.cpp | ||||
|     arm/dyncom/arm_dyncom.h | ||||
|  |  | |||
							
								
								
									
										108
									
								
								src/core/announce_multiplayer_session.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								src/core/announce_multiplayer_session.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,108 @@ | |||
| // Copyright 2017 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <chrono> | ||||
| #include <vector> | ||||
| #include "announce_multiplayer_session.h" | ||||
| #include "common/announce_multiplayer_room.h" | ||||
| #include "common/assert.h" | ||||
| #include "core/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() { | ||||
| #ifdef ENABLE_WEB_SERVICE | ||||
|     backend = std::make_unique<WebService::RoomJson>( | ||||
|         Settings::values.announce_multiplayer_room_endpoint_url, Settings::values.citra_username, | ||||
|         Settings::values.citra_token); | ||||
| #else | ||||
|     backend = std::make_unique<AnnounceMultiplayerRoom::NullBackend>(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| 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(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| AnnounceMultiplayerSession::CallbackHandle AnnounceMultiplayerSession::BindErrorCallback( | ||||
|     std::function<void(const Common::WebResult&)> function) { | ||||
|     std::lock_guard<std::mutex> 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<std::mutex> lock(callback_mutex); | ||||
|     error_callbacks.erase(handle); | ||||
| } | ||||
| 
 | ||||
| AnnounceMultiplayerSession::~AnnounceMultiplayerSession() { | ||||
|     Stop(); | ||||
| } | ||||
| 
 | ||||
| void AnnounceMultiplayerSession::AnnounceMultiplayerLoop() { | ||||
|     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; | ||||
|         } | ||||
|         Network::RoomInformation room_information = room->GetRoomInformation(); | ||||
|         std::vector<Network::Room::Member> memberlist = room->GetRoomMemberList(); | ||||
|         backend->SetRoomInformation( | ||||
|             room_information.uid, room_information.name, 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.nickname, member.mac_address, member.game_info.id, | ||||
|                                member.game_info.name); | ||||
|         } | ||||
|         future = backend->Announce(); | ||||
|         if (future.valid()) { | ||||
|             Common::WebResult result = future.get(); | ||||
|             if (result.result_code != Common::WebResult::Code::Success) { | ||||
|                 std::lock_guard<std::mutex> lock(callback_mutex); | ||||
|                 for (auto callback : error_callbacks) { | ||||
|                     (*callback)(result); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| std::future<AnnounceMultiplayerRoom::RoomList> AnnounceMultiplayerSession::GetRoomList( | ||||
|     std::function<void()> func) { | ||||
|     return backend->GetRoomList(func); | ||||
| } | ||||
| 
 | ||||
| } // namespace Core
 | ||||
							
								
								
									
										71
									
								
								src/core/announce_multiplayer_session.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/core/announce_multiplayer_session.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,71 @@ | |||
| // Copyright 2017 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #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 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 : 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); | ||||
| 
 | ||||
|     /**
 | ||||
|      * 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 | ||||
|      */ | ||||
|     std::future<AnnounceMultiplayerRoom::RoomList> GetRoomList(std::function<void()> func); | ||||
| 
 | ||||
| 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; | ||||
| 
 | ||||
|     void AnnounceMultiplayerLoop(); | ||||
| }; | ||||
| 
 | ||||
| } // namespace Core
 | ||||
|  | @ -139,6 +139,7 @@ struct Values { | |||
|     bool enable_telemetry; | ||||
|     std::string telemetry_endpoint_url; | ||||
|     std::string verify_endpoint_url; | ||||
|     std::string announce_multiplayer_room_endpoint_url; | ||||
|     std::string citra_username; | ||||
|     std::string citra_token; | ||||
| } extern values; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue