Merge pull request #4468 from citra-emu/multiplayer-v4/main

Multiplayer version 4
This commit is contained in:
Pengfei Zhu 2018-12-22 09:45:28 +08:00 committed by GitHub
commit eabc9727d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 2395 additions and 308 deletions

View file

@ -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();
}
}
}

View file

@ -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();
};

View file

@ -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

View file

@ -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

View file

@ -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);
}