mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Merge pull request #4468 from citra-emu/multiplayer-v4/main
Multiplayer version 4
This commit is contained in:
		
						commit
						eabc9727d8
					
				
					 60 changed files with 2395 additions and 308 deletions
				
			
		|  | @ -29,6 +29,21 @@ AnnounceMultiplayerSession::AnnounceMultiplayerSession() { | |||
| #endif | ||||
| } | ||||
| 
 | ||||
| void AnnounceMultiplayerSession::Register() { | ||||
|     std::shared_ptr<Network::Room> room = Network::GetRoom().lock(); | ||||
|     if (!room) { | ||||
|         return; | ||||
|     } | ||||
|     if (room->GetState() != Network::Room::State::Open) { | ||||
|         return; | ||||
|     } | ||||
|     UpdateBackendData(room); | ||||
|     std::string result = backend->Register(); | ||||
|     LOG_INFO(WebService, "Room has been registered"); | ||||
|     room->SetVerifyUID(result); | ||||
|     registered = true; | ||||
| } | ||||
| 
 | ||||
| void AnnounceMultiplayerSession::Start() { | ||||
|     if (announce_multiplayer_thread) { | ||||
|         Stop(); | ||||
|  | @ -44,6 +59,7 @@ void AnnounceMultiplayerSession::Stop() { | |||
|         announce_multiplayer_thread->join(); | ||||
|         announce_multiplayer_thread.reset(); | ||||
|         backend->Delete(); | ||||
|         registered = false; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -64,7 +80,24 @@ 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() { | ||||
|     if (!registered) { | ||||
|         Register(); | ||||
|     } | ||||
|     auto update_time = std::chrono::steady_clock::now(); | ||||
|     std::future<Common::WebResult> future; | ||||
|     while (!shutdown_event.WaitUntil(update_time)) { | ||||
|  | @ -76,24 +109,19 @@ void AnnounceMultiplayerSession::AnnounceMultiplayerLoop() { | |||
|         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); | ||||
|         } | ||||
|         Common::WebResult result = backend->Announce(); | ||||
|         UpdateBackendData(room); | ||||
|         Common::WebResult result = backend->Update(); | ||||
|         if (result.result_code != Common::WebResult::Code::Success) { | ||||
|             std::lock_guard<std::mutex> lock(callback_mutex); | ||||
|             for (auto callback : error_callbacks) { | ||||
|                 (*callback)(result); | ||||
|             } | ||||
|         } | ||||
|         if (result.result_string == "404") { | ||||
|             registered = false; | ||||
|             // Needs to register the room again
 | ||||
|             Register(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <atomic> | ||||
| #include <functional> | ||||
| #include <memory> | ||||
| #include <mutex> | ||||
|  | @ -13,6 +14,10 @@ | |||
| #include "common/common_types.h" | ||||
| #include "common/thread.h" | ||||
| 
 | ||||
| namespace Network { | ||||
| class Room; | ||||
| } | ||||
| 
 | ||||
| namespace Core { | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -39,6 +44,9 @@ public: | |||
|      */ | ||||
|     void UnbindErrorCallback(CallbackHandle handle); | ||||
| 
 | ||||
|     /// Registers a room to web services
 | ||||
|     void Register(); | ||||
| 
 | ||||
|     /**
 | ||||
|      * Starts the announce of a room to web services | ||||
|      */ | ||||
|  | @ -65,6 +73,9 @@ private: | |||
|     /// 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(); | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -734,4 +734,21 @@ void InstallInterfaces(Core::System& system) { | |||
|     std::make_shared<CFG_NOR>()->InstallAsService(service_manager); | ||||
| } | ||||
| 
 | ||||
| std::string GetConsoleIdHash(Core::System& system) { | ||||
|     u64_le console_id{}; | ||||
|     std::array<u8, sizeof(console_id)> buffer; | ||||
|     if (system.IsPoweredOn()) { | ||||
|         auto cfg = GetModule(system); | ||||
|         ASSERT_MSG(cfg, "CFG Module missing!"); | ||||
|         console_id = cfg->GetConsoleUniqueId(); | ||||
|     } else { | ||||
|         console_id = std::make_unique<Service::CFG::Module>()->GetConsoleUniqueId(); | ||||
|     } | ||||
|     std::memcpy(buffer.data(), &console_id, sizeof(console_id)); | ||||
| 
 | ||||
|     std::array<u8, CryptoPP::SHA256::DIGESTSIZE> hash; | ||||
|     CryptoPP::SHA256().CalculateDigest(hash.data(), buffer.data(), sizeof(buffer)); | ||||
|     return fmt::format("{:02x}", fmt::join(hash.begin(), hash.end(), "")); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::CFG
 | ||||
|  |  | |||
|  | @ -415,4 +415,7 @@ std::shared_ptr<Module> GetModule(Core::System& system); | |||
| 
 | ||||
| void InstallInterfaces(Core::System& system); | ||||
| 
 | ||||
| /// Convenience function for getting a SHA256 hash of the Console ID
 | ||||
| std::string GetConsoleIdHash(Core::System& system); | ||||
| 
 | ||||
| } // namespace Service::CFG
 | ||||
|  |  | |||
|  | @ -140,7 +140,9 @@ std::list<Network::WifiPacket> GetReceivedBeacons(const MacAddress& sender) { | |||
| /// Sends a WifiPacket to the room we're currently connected to.
 | ||||
| void SendPacket(Network::WifiPacket& packet) { | ||||
|     if (auto room_member = Network::GetRoomMember().lock()) { | ||||
|         if (room_member->GetState() == Network::RoomMember::State::Joined) { | ||||
|         if (room_member->GetState() == Network::RoomMember::State::Joined || | ||||
|             room_member->GetState() == Network::RoomMember::State::Moderator) { | ||||
| 
 | ||||
|             packet.transmitter_address = room_member->GetMacAddress(); | ||||
|             room_member->SendWifiPacket(packet); | ||||
|         } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue