Added the public lobby to android. (#125)

This is adapted from kleidis old PR to Azahar. Changes from it:
- Fixed inconsistent button styling in the dialog for connection
- Allowed to hide both empty and full rooms.
- Proper serving of preferred games
- Enables web service for android by default
- Better implementation of multiplayer.cpp that works with oop

Also fixes the room network class and turns it into a static namespace
in network

Signed-off-by: Aleksandr Popovich <alekpopo@pm.me>

Co-authored-by: swurl <swurl@swurl.xyz>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/125
Co-authored-by: Aleksandr Popovich <alekpopo@pm.me>
Co-committed-by: Aleksandr Popovich <alekpopo@pm.me>
This commit is contained in:
Aleksandr Popovich 2025-06-05 18:59:47 +00:00 committed by crueter
parent 7e13da47af
commit 76fa525592
99 changed files with 1470 additions and 498 deletions

View file

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright yuzu/Citra Emulator Project / Eden Emulator Project
// SPDX-FileCopyrightText: 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <array>
@ -111,7 +111,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
struct System::Impl {
explicit Impl(System& system)
: kernel{system}, fs_controller{system}, hid_core{}, room_network{}, cpu_manager{system},
: kernel{system}, fs_controller{system}, hid_core{}, cpu_manager{system},
reporter{system}, applet_manager{system}, frontend_applets{system}, profile_manager{} {}
u64 program_id;
@ -421,7 +421,7 @@ struct System::Impl {
}
LoadOverrides(program_id);
if (auto room_member = room_network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
Network::GameInfo game_info;
game_info.name = name;
game_info.id = params.program_id;
@ -466,7 +466,7 @@ struct System::Impl {
stop_event = {};
Network::RestartSocketOperations();
if (auto room_member = room_network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
Network::GameInfo game_info{};
room_member->SendGameInfo(game_info);
}
@ -520,7 +520,6 @@ struct System::Impl {
std::unique_ptr<Core::DeviceMemory> device_memory;
std::unique_ptr<AudioCore::AudioCore> audio_core;
Core::HID::HIDCore hid_core;
Network::RoomNetwork room_network;
CpuManager cpu_manager;
std::atomic_bool is_powered_on{};
@ -979,14 +978,6 @@ const Core::Debugger& System::GetDebugger() const {
return *impl->debugger;
}
Network::RoomNetwork& System::GetRoomNetwork() {
return impl->room_network;
}
const Network::RoomNetwork& System::GetRoomNetwork() const {
return impl->room_network;
}
Tools::RenderdocAPI& System::GetRenderdocAPI() {
return *impl->renderdoc_api;
}

View file

@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <cstddef>
@ -104,10 +107,6 @@ namespace Core::HID {
class HIDCore;
}
namespace Network {
class RoomNetwork;
}
namespace Tools {
class RenderdocAPI;
}
@ -380,12 +379,6 @@ public:
[[nodiscard]] Core::Debugger& GetDebugger();
[[nodiscard]] const Core::Debugger& GetDebugger() const;
/// Gets a mutable reference to the Room Network.
[[nodiscard]] Network::RoomNetwork& GetRoomNetwork();
/// Gets an immutable reference to the Room Network.
[[nodiscard]] const Network::RoomNetwork& GetRoomNetwork() const;
[[nodiscard]] Tools::RenderdocAPI& GetRenderdocAPI();
void SetExitLocked(bool locked);

View file

@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/ldn/lan_discovery.h"
#include "core/internal_network/network.h"
#include "core/internal_network/network_interface.h"
@ -33,9 +36,8 @@ void LanStation::OverrideInfo() {
node_info->is_connected = connected ? 1 : 0;
}
LANDiscovery::LANDiscovery(Network::RoomNetwork& room_network_)
: stations({{{1, this}, {2, this}, {3, this}, {4, this}, {5, this}, {6, this}, {7, this}}}),
room_network{room_network_} {}
LANDiscovery::LANDiscovery()
: stations({{{1, this}, {2, this}, {3, this}, {4, this}, {5, this}, {6, this}, {7, this}}}){}
LANDiscovery::~LANDiscovery() {
if (inited) {
@ -410,7 +412,7 @@ void LANDiscovery::OnNetworkInfoChanged() {
Network::IPv4Address LANDiscovery::GetLocalIp() const {
Network::IPv4Address local_ip{0xFF, 0xFF, 0xFF, 0xFF};
if (auto room_member = room_network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
if (room_member->IsConnected()) {
local_ip = room_member->GetFakeIpAddress();
}
@ -468,7 +470,7 @@ void LANDiscovery::SendBroadcast(Network::LDNPacketType type) {
}
void LANDiscovery::SendPacket(const Network::LDNPacket& packet) {
if (auto room_member = room_network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
if (room_member->IsConnected()) {
room_member->SendLdnPacket(packet);
}

View file

@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <array>
@ -47,7 +50,7 @@ class LANDiscovery {
public:
using LanEventFunc = std::function<void()>;
LANDiscovery(Network::RoomNetwork& room_network_);
LANDiscovery();
~LANDiscovery();
State GetState() const;
@ -127,7 +130,5 @@ protected:
std::optional<Ipv4Address> host_ip;
LanEventFunc lan_event;
Network::RoomNetwork& room_network;
};
} // namespace Service::LDN

View file

@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <memory>
#include "core/core.h"
@ -22,7 +25,7 @@ namespace Service::LDN {
IUserLocalCommunicationService::IUserLocalCommunicationService(Core::System& system_)
: ServiceFramework{system_, "IUserLocalCommunicationService"},
service_context{system, "IUserLocalCommunicationService"},
room_network{system_.GetRoomNetwork()}, lan_discovery{room_network} {
lan_discovery{} {
// clang-format off
static const FunctionInfo functions[] = {
{0, C<&IUserLocalCommunicationService::GetState>, "GetState"},
@ -65,7 +68,7 @@ IUserLocalCommunicationService::IUserLocalCommunicationService(Core::System& sys
IUserLocalCommunicationService::~IUserLocalCommunicationService() {
if (is_initialized) {
if (auto room_member = room_network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
room_member->Unbind(ldn_packet_received);
}
}
@ -103,7 +106,7 @@ Result IUserLocalCommunicationService::GetIpv4Address(Out<Ipv4Address> out_curre
*out_subnet_mask = {Network::TranslateIPv4(network_interface->subnet_mask)};
// When we're connected to a room, spoof the hosts IP address
if (auto room_member = room_network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
if (room_member->IsConnected()) {
*out_current_address = room_member->GetFakeIpAddress();
}
@ -280,7 +283,7 @@ Result IUserLocalCommunicationService::Initialize(ClientProcessId aruid) {
const auto network_interface = Network::GetSelectedNetworkInterface();
R_UNLESS(network_interface, ResultAirplaneModeEnabled);
if (auto room_member = room_network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
ldn_packet_received = room_member->BindOnLdnPacketReceived(
[this](const Network::LDNPacket& packet) { OnLDNPacketReceived(packet); });
} else {
@ -295,7 +298,7 @@ Result IUserLocalCommunicationService::Initialize(ClientProcessId aruid) {
Result IUserLocalCommunicationService::Finalize() {
LOG_INFO(Service_LDN, "called");
if (auto room_member = room_network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
room_member->Unbind(ldn_packet_received);
}

View file

@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
@ -13,10 +16,6 @@ namespace Core {
class System;
}
namespace Network {
class RoomNetwork;
}
namespace Service::LDN {
class IUserLocalCommunicationService final
@ -91,7 +90,6 @@ private:
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* state_change_event;
Network::RoomNetwork& room_network;
LANDiscovery lan_discovery;
// Callback identifier for the OnLDNPacketReceived event.

View file

@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/core.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/ipc_helpers.h"
@ -406,7 +409,7 @@ void IGeneralService::GetCurrentNetworkProfile(HLERequestContext& ctx) {
}();
// When we're connected to a room, spoof the hosts IP address
if (auto room_member = network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
if (room_member->IsConnected()) {
network_profile_data.ip_setting_data.ip_address_setting.ip_address =
room_member->GetFakeIpAddress();
@ -454,7 +457,7 @@ void IGeneralService::GetCurrentIpAddress(HLERequestContext& ctx) {
}
// When we're connected to a room, spoof the hosts IP address
if (auto room_member = network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
if (room_member->IsConnected()) {
ipv4 = room_member->GetFakeIpAddress();
}
@ -513,7 +516,7 @@ void IGeneralService::GetCurrentIpConfigInfo(HLERequestContext& ctx) {
}();
// When we're connected to a room, spoof the hosts IP address
if (auto room_member = network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
if (room_member->IsConnected()) {
ip_config_info.ip_address_setting.ip_address = room_member->GetFakeIpAddress();
}
@ -643,7 +646,7 @@ void IGeneralService::GetCurrentAccessPoint(HLERequestContext& ctx) {
}
IGeneralService::IGeneralService(Core::System& system_)
: ServiceFramework{system_, "IGeneralService"}, network{system_.GetRoomNetwork()} {
: ServiceFramework{system_, "IGeneralService"} {
// clang-format off
static const FunctionInfo functions[] = {
{1, &IGeneralService::GetClientId, "GetClientId"},

View file

@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/service.h"
@ -9,10 +12,6 @@ namespace Core {
class System;
}
namespace Network {
class RoomNetwork;
}
namespace Service::NIFM {
void LoopProcess(Core::System& system);
@ -42,8 +41,6 @@ private:
void ConfirmSystemAvailability(HLERequestContext& ctx);
void SetBackgroundRequestEnabled(HLERequestContext& ctx);
void GetCurrentAccessPoint(HLERequestContext& ctx);
Network::RoomNetwork& network;
};
} // namespace Service::NIFM

View file

@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <array>
#include <memory>
#include <utility>
@ -508,9 +511,9 @@ std::pair<s32, Errno> BSD::SocketImpl(Domain domain, Type type, Protocol protoco
LOG_INFO(Service, "New socket fd={}", fd);
auto room_member = room_network.GetRoomMember().lock();
auto room_member = Network::GetRoomMember().lock();
if (room_member && room_member->IsConnected()) {
descriptor.socket = std::make_shared<Network::ProxySocket>(room_network);
descriptor.socket = std::make_shared<Network::ProxySocket>();
} else {
descriptor.socket = std::make_shared<Network::Socket>();
}
@ -970,7 +973,7 @@ void BSD::OnProxyPacketReceived(const Network::ProxyPacket& packet) {
}
BSD::BSD(Core::System& system_, const char* name)
: ServiceFramework{system_, name}, room_network{system_.GetRoomNetwork()} {
: ServiceFramework{system_, name} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &BSD::RegisterClient, "RegisterClient"},
@ -1012,7 +1015,7 @@ BSD::BSD(Core::System& system_, const char* name)
RegisterHandlers(functions);
if (auto room_member = room_network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
proxy_packet_received = room_member->BindOnProxyPacketReceived(
[this](const Network::ProxyPacket& packet) { OnProxyPacketReceived(packet); });
} else {
@ -1021,7 +1024,7 @@ BSD::BSD(Core::System& system_, const char* name)
}
BSD::~BSD() {
if (auto room_member = room_network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
room_member->Unbind(proxy_packet_received);
}
}

View file

@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <memory>
@ -179,8 +182,6 @@ private:
std::array<std::optional<FileDescriptor>, MAX_FD> file_descriptors;
Network::RoomNetwork& room_network;
/// Callback to parse and handle a received wifi packet.
void OnProxyPacketReceived(const Network::ProxyPacket& packet);

View file

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright yuzu/Citra Emulator Project / Eden Emulator Project
// SPDX-FileCopyrightText: 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <algorithm>

View file

@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <chrono>
#include <thread>
@ -18,7 +21,7 @@
namespace Network {
ProxySocket::ProxySocket(RoomNetwork& room_network_) noexcept : room_network{room_network_} {}
ProxySocket::ProxySocket() noexcept {}
ProxySocket::~ProxySocket() {
if (fd == INVALID_SOCKET) {
@ -187,7 +190,7 @@ std::pair<s32, Errno> ProxySocket::Send(std::span<const u8> message, int flags)
}
void ProxySocket::SendPacket(ProxyPacket& packet) {
if (auto room_member = room_network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
if (room_member->IsConnected()) {
packet.data = Common::Compression::CompressDataZSTDDefault(packet.data.data(),
packet.data.size());
@ -205,7 +208,7 @@ std::pair<s32, Errno> ProxySocket::SendTo(u32 flags, std::span<const u8> message
return {static_cast<s32>(message.size()), Errno::SUCCESS};
}
if (auto room_member = room_network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
if (!room_member->IsConnected()) {
return {static_cast<s32>(message.size()), Errno::SUCCESS};
}
@ -222,7 +225,7 @@ std::pair<s32, Errno> ProxySocket::SendTo(u32 flags, std::span<const u8> message
// If the ip is all zeroes (INADDR_ANY) or if it matches the hosts ip address,
// replace it with a "fake" routing address
if (std::all_of(ip.begin(), ip.end(), [](u8 i) { return i == 0; }) || (ipv4 && ipv4 == ip)) {
if (auto room_member = room_network.GetRoomMember().lock()) {
if (auto room_member = Network::GetRoomMember().lock()) {
packet.local_endpoint.ip = room_member->GetFakeIpAddress();
}
}

View file

@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <mutex>
@ -14,11 +17,9 @@
namespace Network {
class RoomNetwork;
class ProxySocket : public SocketBase {
public:
explicit ProxySocket(RoomNetwork& room_network_) noexcept;
explicit ProxySocket() noexcept;
~ProxySocket() override;
void HandleProxyPacket(const ProxyPacket& packet) override;
@ -92,8 +93,6 @@ private:
Protocol protocol;
std::mutex packets_mutex;
RoomNetwork& room_network;
};
} // namespace Network