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