diff --git a/.gitignore b/.gitignore index fbadb208be..bb1849dacc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # SPDX-FileCopyrightText: 2013 Citra Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + # Build directory [Bb]uild*/ doc-build/ @@ -36,3 +39,7 @@ CMakeSettings.json # Windows global filetypes Thumbs.db +# Artifacts +eden-windows-msvc +artifacts +*.AppImage* diff --git a/CMakeLists.txt b/CMakeLists.txt index 5144dc028a..c979238ce3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 cmake_minimum_required(VERSION 3.22) diff --git a/CMakeModules/DownloadExternals.cmake b/CMakeModules/DownloadExternals.cmake index adc658d74f..2b44249726 100644 --- a/CMakeModules/DownloadExternals.cmake +++ b/CMakeModules/DownloadExternals.cmake @@ -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 # This function downloads a binary library package from our external repo. diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts index 6c5592c1f5..de5d891f01 100644 --- a/src/android/app/build.gradle.kts +++ b/src/android/app/build.gradle.kts @@ -1,4 +1,7 @@ -// SPDX-FileCopyrightText: Copyright yuzu/Citra Emulator Project / Eden Emulator Project +// SPDX-FileCopyrightText: Copyright yuzu/Citra 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 import android.annotation.SuppressLint @@ -162,7 +165,7 @@ android { arguments( "-DENABLE_QT=0", // Don't use QT "-DENABLE_SDL2=0", // Don't use SDL - "-DENABLE_WEB_SERVICE=0", // Don't use telemetry + "-DENABLE_WEB_SERVICE=1", // Enable web service "-DANDROID_ARM_NEON=true", // cryptopp requires Neon to work "-DYUZU_USE_BUNDLED_VCPKG=ON", "-DYUZU_USE_BUNDLED_FFMPEG=ON", @@ -176,9 +179,9 @@ android { } } -tasks.create("ktlintReset") { - delete(File(buildDir.path + File.separator + "intermediates/ktLint")) -} +tasks.register("ktlintReset", fun Delete.() { + delete(File(layout.buildDirectory.toString() + File.separator + "intermediates/ktLint")) +}) val showFormatHelp = { logger.lifecycle( diff --git a/src/android/app/src/main/AndroidManifest.xml b/src/android/app/src/main/AndroidManifest.xml index 0a43b13e1c..e4885e5126 100644 --- a/src/android/app/src/main/AndroidManifest.xml +++ b/src/android/app/src/main/AndroidManifest.xml @@ -3,6 +3,9 @@ + Web Token + Web token used for creating public lobbies. It is a 48-character string containing only lowercase a-z. + Network + WIP: Frameskip Toggle frame skipping to improve performance by reducing the number of rendered frames. This feature is still being worked on and will be enabled in future releases. diff --git a/src/common/android/android_common.cpp b/src/common/android/android_common.cpp index 0df2dd7b35..a1cf081695 100644 --- a/src/common/android/android_common.cpp +++ b/src/common/android/android_common.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -// 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 "android_common.h" diff --git a/src/common/android/android_common.h b/src/common/android/android_common.h index 05e2c2515b..a16add3bdf 100644 --- a/src/common/android/android_common.h +++ b/src/common/android/android_common.h @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -// SPDX-FileCopyrightText: Copyright yuzu/Citra Emulator Project / Eden Emulator Project +// SPDX-FileCopyrightText: 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #pragma once diff --git a/src/common/android/id_cache.cpp b/src/common/android/id_cache.cpp index 649fafca09..2625e55c35 100644 --- a/src/common/android/id_cache.cpp +++ b/src/common/android/id_cache.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -// 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 @@ -94,10 +94,10 @@ static jmethodID s_yuzu_input_device_get_supports_vibration; static jmethodID s_yuzu_input_device_vibrate; static jmethodID s_yuzu_input_device_get_axes; static jmethodID s_yuzu_input_device_has_keys; + static jmethodID s_add_netplay_message; static jmethodID s_clear_chat; - static constexpr jint JNI_VERSION = JNI_VERSION_1_6; namespace Common::Android { @@ -405,7 +405,6 @@ jmethodID ClearChat() { return s_clear_chat; } - #ifdef __cplusplus extern "C" { #endif @@ -605,7 +604,7 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) { // UnInitialize applets SoftwareKeyboard::CleanupJNI(env); - NetworkShutdown(); + AndroidMultiplayer::NetworkShutdown(); } #ifdef __cplusplus diff --git a/src/common/android/id_cache.h b/src/common/android/id_cache.h index 0b64bbc866..cbfbf36be8 100644 --- a/src/common/android/id_cache.h +++ b/src/common/android/id_cache.h @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileCopyrightText: Copyright yuzu/Citra Emulator Project / Eden Emulator Project +// SPDX-FileCopyrightText: 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #pragma once diff --git a/src/common/android/multiplayer/multiplayer.cpp b/src/common/android/multiplayer/multiplayer.cpp index 41d46d71b3..fe6408fced 100644 --- a/src/common/android/multiplayer/multiplayer.cpp +++ b/src/common/android/multiplayer/multiplayer.cpp @@ -1,8 +1,4 @@ -// Copyright 2024 Mandarine Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -// 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 "common/android/id_cache.h" @@ -19,35 +15,38 @@ #include namespace IDCache = Common::Android; -Network::RoomNetwork* room_network; -void AddNetPlayMessage(jint type, jstring msg) { +AndroidMultiplayer::AndroidMultiplayer(Core::System& system_, + std::shared_ptr session) + : system{system_}, announce_multiplayer_session(session) {} + +AndroidMultiplayer::~AndroidMultiplayer() = default; + +void AndroidMultiplayer::AddNetPlayMessage(jint type, jstring msg) { IDCache::GetEnvForThread()->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetAddNetPlayMessage(), type, msg); } -void AddNetPlayMessage(int type, const std::string& msg) { +void AndroidMultiplayer::AddNetPlayMessage(int type, const std::string& msg) { JNIEnv* env = IDCache::GetEnvForThread(); AddNetPlayMessage(type, Common::Android::ToJString(env, msg)); } -void ClearChat() { +void AndroidMultiplayer::ClearChat() { IDCache::GetEnvForThread()->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::ClearChat()); } - -bool NetworkInit(Network::RoomNetwork* room_network_) { - room_network = room_network_; - bool result = room_network->Init(); +bool AndroidMultiplayer::NetworkInit() { + bool result = Network::Init(); if (!result) { return false; } - if (auto member = room_network->GetRoomMember().lock()) { + if (auto member = Network::GetRoomMember().lock()) { // register the network structs to use in slots and signals - member->BindOnStateChanged([](const Network::RoomMember::State& state) { + member->BindOnStateChanged([this](const Network::RoomMember::State& state) { if (state == Network::RoomMember::State::Joined || state == Network::RoomMember::State::Moderator) { NetPlayStatus status; @@ -65,7 +64,7 @@ bool NetworkInit(Network::RoomNetwork* room_network_) { AddNetPlayMessage(static_cast(status), msg); } }); - member->BindOnError([](const Network::RoomMember::Error& error) { + member->BindOnError([this](const Network::RoomMember::Error& error) { NetPlayStatus status; std::string msg; switch (error) { @@ -108,7 +107,7 @@ bool NetworkInit(Network::RoomNetwork* room_network_) { } AddNetPlayMessage(static_cast(status), msg); }); - member->BindOnStatusMessageReceived([](const Network::StatusMessageEntry& status_message) { + member->BindOnStatusMessageReceived([this](const Network::StatusMessageEntry& status_message) { NetPlayStatus status = NetPlayStatus::NO_ERROR; std::string msg(status_message.nickname); switch (status_message.type) { @@ -130,7 +129,7 @@ bool NetworkInit(Network::RoomNetwork* room_network_) { } AddNetPlayMessage(static_cast(status), msg); }); - member->BindOnChatMessageReceived([](const Network::ChatEntry& chat) { + member->BindOnChatMessageReceived([this](const Network::ChatEntry& chat) { NetPlayStatus status = NetPlayStatus::CHAT_MESSAGE; std::string msg(chat.nickname); msg += ": "; @@ -141,13 +140,11 @@ bool NetworkInit(Network::RoomNetwork* room_network_) { return true; } -NetPlayStatus NetPlayCreateRoom(const std::string& ipaddress, int port, - const std::string& username, const std::string& password, +NetPlayStatus AndroidMultiplayer::NetPlayCreateRoom(const std::string& ipaddress, int port, + const std::string& username, const std::string &preferredGameName, + const u64 &preferredGameId, const std::string& password, const std::string& room_name, int max_players) { - - __android_log_print(ANDROID_LOG_INFO, "NetPlay", "NetPlayCreateRoom called with ipaddress: %s, port: %d, username: %s, room_name: %s, max_players: %d", ipaddress.c_str(), port, username.c_str(), room_name.c_str(), max_players); - - auto member = room_network->GetRoomMember().lock(); + auto member = Network::GetRoomMember().lock(); if (!member) { return NetPlayStatus::NETWORK_ERROR; } @@ -156,7 +153,7 @@ NetPlayStatus NetPlayCreateRoom(const std::string& ipaddress, int port, return NetPlayStatus::ALREADY_IN_ROOM; } - auto room = room_network->GetRoom().lock(); + auto room = Network::GetRoom().lock(); if (!room) { return NetPlayStatus::NETWORK_ERROR; } @@ -167,14 +164,14 @@ NetPlayStatus NetPlayCreateRoom(const std::string& ipaddress, int port, // Placeholder game info const AnnounceMultiplayerRoom::GameInfo game{ - .name = "Default Game", - .id = 0, // Default program ID + .name = preferredGameName, + .id = preferredGameId, }; port = (port == 0) ? Network::DefaultRoomPort : static_cast(port); if (!room->Create(room_name, "", ipaddress, static_cast(port), password, - static_cast(std::min(max_players, 16)), username, game, nullptr, {})) { + static_cast(std::min(max_players, 16)), username, game, std::make_unique(), {})) { return NetPlayStatus::CREATE_ROOM_ERROR; } @@ -197,9 +194,9 @@ NetPlayStatus NetPlayCreateRoom(const std::string& ipaddress, int port, return NetPlayStatus::CREATE_ROOM_ERROR; } -NetPlayStatus NetPlayJoinRoom(const std::string& ipaddress, int port, +NetPlayStatus AndroidMultiplayer::NetPlayJoinRoom(const std::string& ipaddress, int port, const std::string& username, const std::string& password) { - auto member = room_network->GetRoomMember().lock(); + auto member = Network::GetRoomMember().lock(); if (!member) { return NetPlayStatus::NETWORK_ERROR; } @@ -229,8 +226,8 @@ NetPlayStatus NetPlayJoinRoom(const std::string& ipaddress, int port, return NetPlayStatus::WRONG_PASSWORD; } -void NetPlaySendMessage(const std::string& msg) { - if (auto room = room_network->GetRoomMember().lock()) { +void AndroidMultiplayer::NetPlaySendMessage(const std::string& msg) { + if (auto room = Network::GetRoomMember().lock()) { if (room->GetState() != Network::RoomMember::State::Joined && room->GetState() != Network::RoomMember::State::Moderator) { @@ -240,8 +237,8 @@ void NetPlaySendMessage(const std::string& msg) { } } -void NetPlayKickUser(const std::string& username) { - if (auto room = room_network->GetRoomMember().lock()) { +void AndroidMultiplayer::NetPlayKickUser(const std::string& username) { + if (auto room = Network::GetRoomMember().lock()) { auto members = room->GetMemberInformation(); auto it = std::find_if(members.begin(), members.end(), [&username](const Network::RoomMember::MemberInformation& member) { @@ -253,8 +250,8 @@ void NetPlayKickUser(const std::string& username) { } } -void NetPlayBanUser(const std::string& username) { - if (auto room = room_network->GetRoomMember().lock()) { +void AndroidMultiplayer::NetPlayBanUser(const std::string& username) { + if (auto room = Network::GetRoomMember().lock()) { auto members = room->GetMemberInformation(); auto it = std::find_if(members.begin(), members.end(), [&username](const Network::RoomMember::MemberInformation& member) { @@ -266,15 +263,15 @@ void NetPlayBanUser(const std::string& username) { } } -void NetPlayUnbanUser(const std::string& username) { - if (auto room = room_network->GetRoomMember().lock()) { +void AndroidMultiplayer::NetPlayUnbanUser(const std::string& username) { + if (auto room = Network::GetRoomMember().lock()) { room->SendModerationRequest(Network::RoomMessageTypes::IdModUnban, username); } } -std::vector NetPlayRoomInfo() { +std::vector AndroidMultiplayer::NetPlayRoomInfo() { std::vector info_list; - if (auto room = room_network->GetRoomMember().lock()) { + if (auto room = Network::GetRoomMember().lock()) { auto members = room->GetMemberInformation(); if (!members.empty()) { // name and max players @@ -289,8 +286,8 @@ std::vector NetPlayRoomInfo() { return info_list; } -bool NetPlayIsJoined() { - auto member = room_network->GetRoomMember().lock(); +bool AndroidMultiplayer::NetPlayIsJoined() { + auto member = Network::GetRoomMember().lock(); if (!member) { return false; } @@ -299,17 +296,17 @@ bool NetPlayIsJoined() { member->GetState() == Network::RoomMember::State::Moderator); } -bool NetPlayIsHostedRoom() { - if (auto room = room_network->GetRoom().lock()) { +bool AndroidMultiplayer::NetPlayIsHostedRoom() { + if (auto room = Network::GetRoom().lock()) { return room->GetState() == Network::Room::State::Open; } return false; } -void NetPlayLeaveRoom() { - if (auto room = room_network->GetRoom().lock()) { +void AndroidMultiplayer::NetPlayLeaveRoom() { + if (auto room = Network::GetRoom().lock()) { // if you are in a room, leave it - if (auto member = room_network->GetRoomMember().lock()) { + if (auto member = Network::GetRoomMember().lock()) { member->Leave(); } @@ -322,21 +319,52 @@ void NetPlayLeaveRoom() { } } -void NetworkShutdown() { - room_network->Shutdown(); +void AndroidMultiplayer::NetworkShutdown() { + Network::Shutdown(); } -bool NetPlayIsModerator() { - auto member = room_network->GetRoomMember().lock(); +bool AndroidMultiplayer::NetPlayIsModerator() { + auto member = Network::GetRoomMember().lock(); if (!member) { return false; } return member->GetState() == Network::RoomMember::State::Moderator; } -std::vector NetPlayGetBanList() { +std::vector AndroidMultiplayer::NetPlayGetPublicRooms() { + std::vector room_list; + + if (auto session = announce_multiplayer_session.lock()) { + auto rooms = session->GetRoomList(); + for (const auto &room: rooms) { + room_list.push_back(room.information.name + "|" + + (room.has_password ? "1" : "0") + "|" + + std::to_string(room.information.member_slots) + "|" + + room.ip + "|" + + std::to_string(room.information.port) + "|" + + room.information.description + "|" + + room.information.host_username + "|" + + std::to_string(room.information.preferred_game.id) + "|" + + room.information.preferred_game.name + "|" + + room.information.preferred_game.version); + + for (const auto &member: room.members) { + room_list.push_back("MEMBER|" + room.information.name + "|" + + member.username + "|" + + member.nickname + "|" + + std::to_string(member.game.id) + "|" + + member.game.name); + } + } + + } + return room_list; + +} + +std::vector AndroidMultiplayer::NetPlayGetBanList() { std::vector ban_list; - if (auto room = room_network->GetRoom().lock()) { + if (auto room = Network::GetRoom().lock()) { auto [username_bans, ip_bans] = room->GetBanList(); // Add username bans diff --git a/src/common/android/multiplayer/multiplayer.h b/src/common/android/multiplayer/multiplayer.h index 4f32c514e0..591d3be8fd 100644 --- a/src/common/android/multiplayer/multiplayer.h +++ b/src/common/android/multiplayer/multiplayer.h @@ -1,8 +1,4 @@ -// Copyright 2024 Mandarine Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -// SPDX-FileCopyrightText: Copyright yuzu/Citra Emulator Project / Eden Emulator Project +// SPDX-FileCopyrightText: 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #pragma once @@ -12,6 +8,12 @@ #include #include +#include + +namespace Core { + class System; + class AnnounceMultiplayerSession; +} enum class NetPlayStatus : s32 { NO_ERROR, @@ -48,21 +50,53 @@ enum class NetPlayStatus : s32 { CHAT_MESSAGE, }; -bool NetworkInit(Network::RoomNetwork* room_network); -NetPlayStatus NetPlayCreateRoom(const std::string& ipaddress, int port, - const std::string& username, const std::string& password, - const std::string& room_name, int max_players); -NetPlayStatus NetPlayJoinRoom(const std::string& ipaddress, int port, - const std::string& username, const std::string& password); -std::vector NetPlayRoomInfo(); -bool NetPlayIsJoined(); -bool NetPlayIsHostedRoom(); -bool NetPlayIsModerator(); -void NetPlaySendMessage(const std::string& msg); -void NetPlayKickUser(const std::string& username); -void NetPlayBanUser(const std::string& username); -void NetPlayLeaveRoom(); -std::string NetPlayGetConsoleId(); -void NetworkShutdown(); -std::vector NetPlayGetBanList(); -void NetPlayUnbanUser(const std::string& username); +class AndroidMultiplayer { +public: + explicit AndroidMultiplayer(Core::System& system, + std::shared_ptr session); + ~AndroidMultiplayer(); + + bool NetworkInit(); + + void AddNetPlayMessage(int status, const std::string& msg); + void AddNetPlayMessage(jint type, jstring msg); + + void ClearChat(); + + NetPlayStatus NetPlayCreateRoom(const std::string &ipaddress, int port, + const std::string &username, const std::string &preferredGameName, + const u64 &preferredGameId, const std::string &password, + const std::string &room_name, int max_players); + + NetPlayStatus NetPlayJoinRoom(const std::string &ipaddress, int port, + const std::string &username, const std::string &password); + + std::vector NetPlayRoomInfo(); + + bool NetPlayIsJoined(); + + bool NetPlayIsHostedRoom(); + + bool NetPlayIsModerator(); + + void NetPlaySendMessage(const std::string &msg); + + void NetPlayKickUser(const std::string &username); + + void NetPlayBanUser(const std::string &username); + + void NetPlayLeaveRoom(); + + static void NetworkShutdown(); + + std::vector NetPlayGetBanList(); + + void NetPlayUnbanUser(const std::string &username); + + std::vector NetPlayGetPublicRooms(); + +private: + Core::System& system; + static std::unique_ptr CreateVerifyBackend(bool use_validation) ; + std::weak_ptr announce_multiplayer_session; +}; diff --git a/src/common/announce_multiplayer_room.h b/src/common/announce_multiplayer_room.h index 6f7ccfa7f0..419890481a 100644 --- a/src/common/announce_multiplayer_room.h +++ b/src/common/announce_multiplayer_room.h @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -// SPDX-FileCopyrightText: Copyright yuzu/Citra Emulator Project / Eden Emulator Project +// SPDX-FileCopyrightText: 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #pragma once diff --git a/src/core/core.cpp b/src/core/core.cpp index 61b8182c08..0058c09b6e 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -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 @@ -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 device_memory; std::unique_ptr 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; } diff --git a/src/core/core.h b/src/core/core.h index 0cc1108b80..99b1c5641f 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -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 @@ -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); diff --git a/src/core/hle/service/ldn/lan_discovery.cpp b/src/core/hle/service/ldn/lan_discovery.cpp index b9db19618a..7d677e6664 100644 --- a/src/core/hle/service/ldn/lan_discovery.cpp +++ b/src/core/hle/service/ldn/lan_discovery.cpp @@ -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); } diff --git a/src/core/hle/service/ldn/lan_discovery.h b/src/core/hle/service/ldn/lan_discovery.h index 8f7a8dfc45..0d15583172 100644 --- a/src/core/hle/service/ldn/lan_discovery.h +++ b/src/core/hle/service/ldn/lan_discovery.h @@ -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 @@ -47,7 +50,7 @@ class LANDiscovery { public: using LanEventFunc = std::function; - LANDiscovery(Network::RoomNetwork& room_network_); + LANDiscovery(); ~LANDiscovery(); State GetState() const; @@ -127,7 +130,5 @@ protected: std::optional host_ip; LanEventFunc lan_event; - - Network::RoomNetwork& room_network; }; } // namespace Service::LDN diff --git a/src/core/hle/service/ldn/user_local_communication_service.cpp b/src/core/hle/service/ldn/user_local_communication_service.cpp index f28368962f..69170a879d 100644 --- a/src/core/hle/service/ldn/user_local_communication_service.cpp +++ b/src/core/hle/service/ldn/user_local_communication_service.cpp @@ -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 #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 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); } diff --git a/src/core/hle/service/ldn/user_local_communication_service.h b/src/core/hle/service/ldn/user_local_communication_service.h index 6698d10d22..55320fbc91 100644 --- a/src/core/hle/service/ldn/user_local_communication_service.h +++ b/src/core/hle/service/ldn/user_local_communication_service.h @@ -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. diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index d758e9aa3d..bb6e719cb0 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp @@ -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"}, diff --git a/src/core/hle/service/nifm/nifm.h b/src/core/hle/service/nifm/nifm.h index 4682a4a273..7071fa90d7 100644 --- a/src/core/hle/service/nifm/nifm.h +++ b/src/core/hle/service/nifm/nifm.h @@ -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 diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index ef03203349..4be70e0559 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -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 #include #include @@ -508,9 +511,9 @@ std::pair 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(room_network); + descriptor.socket = std::make_shared(); } else { descriptor.socket = std::make_shared(); } @@ -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); } } diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h index 4f69d382c9..ed6b576a65 100644 --- a/src/core/hle/service/sockets/bsd.h +++ b/src/core/hle/service/sockets/bsd.h @@ -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 @@ -179,8 +182,6 @@ private: std::array, MAX_FD> file_descriptors; - Network::RoomNetwork& room_network; - /// Callback to parse and handle a received wifi packet. void OnProxyPacketReceived(const Network::ProxyPacket& packet); diff --git a/src/core/internal_network/network_interface.cpp b/src/core/internal_network/network_interface.cpp index 3d99bdf5ce..0f5ef0741f 100644 --- a/src/core/internal_network/network_interface.cpp +++ b/src/core/internal_network/network_interface.cpp @@ -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 diff --git a/src/core/internal_network/socket_proxy.cpp b/src/core/internal_network/socket_proxy.cpp index ce0dee9705..eba1e28c5e 100644 --- a/src/core/internal_network/socket_proxy.cpp +++ b/src/core/internal_network/socket_proxy.cpp @@ -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 #include @@ -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 ProxySocket::Send(std::span 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 ProxySocket::SendTo(u32 flags, std::span message return {static_cast(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(message.size()), Errno::SUCCESS}; } @@ -222,7 +225,7 @@ std::pair ProxySocket::SendTo(u32 flags, std::span 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(); } } diff --git a/src/core/internal_network/socket_proxy.h b/src/core/internal_network/socket_proxy.h index 70500cf4a2..93cf0757af 100644 --- a/src/core/internal_network/socket_proxy.h +++ b/src/core/internal_network/socket_proxy.h @@ -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 @@ -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 diff --git a/src/dedicated_room/yuzu_room.cpp b/src/dedicated_room/yuzu_room.cpp index f02407780f..afba0ad4c8 100644 --- a/src/dedicated_room/yuzu_room.cpp +++ b/src/dedicated_room/yuzu_room.cpp @@ -4,7 +4,7 @@ // SPDX-FileCopyrightText: Copyright yuzu/Citra Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileCopyrightText: 2025 eden Emulator Project +// SPDX-FileCopyrightText: 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #include @@ -55,22 +55,22 @@ static void PrintHelp(const char* argv0) { LOG_INFO(Network, "Usage: {}" " [options] \n" - "--room-name The name of the room\n" - "--room-description The room description\n" - "--bind-address The bind address for the room\n" - "--port The port used for the room\n" - "--max_members The maximum number of players for this room\n" - "--password The password for the room\n" - "--preferred-game The preferred game for this room\n" - "--preferred-game-id The preferred game-id for this room\n" - "--username The username used for announce\n" - "--token The token used for announce\n" - "--web-api-url yuzu Web API url\n" - "--ban-list-file The file for storing the room ban list\n" - "--log-file The file for storing the room log\n" - "--enable-yuzu-mods Allow yuzu Community Moderators to moderate on your room\n" - "-h, --help Display this help and exit\n" - "-v, --version Output version information and exit\n", + "-n, --room-name The name of the room\n" + "-d, --room-description The room description\n" + "-s, --bind-address The bind address for the room\n" + "-p, --port The port used for the room\n" + "-m, --max-members The maximum number of players for this room\n" + "-w, --password The password for the room\n" + "-g, --preferred-game The preferred game for this room\n" + "-i, --preferred-game-id The preferred game-id for this room\n" + "-u, --username The username used for announce\n" + "-t, --token The token used for announce\n" + "-a, --web-api-url yuzu Web API url\n" + "-b, --ban-list-file The file for storing the room ban list\n" + "-l, --log-file The file for storing the room log\n" + "-e, --enable-mods Allow Community Moderators to moderate on your room\n" + "-h, --help Display this help and exit\n" + "-v, --version Output version information and exit\n", argv0); } @@ -209,19 +209,18 @@ void LaunchRoom(int argc, char** argv, bool called_by_option) std::string token; std::string web_api_url; std::string ban_list_file; - std::string log_file = "yuzu-room.log"; + std::string log_file = "eden-room.log"; std::string bind_address; u64 preferred_game_id = 0; u32 port = Network::DefaultRoomPort; u32 max_members = 16; - // TODO(alekpop): Implement this into main executable, for --room and a few others. static struct option long_options[] = { {"room-name", required_argument, 0, 'n'}, {"room-description", required_argument, 0, 'd'}, {"bind-address", required_argument, 0, 's'}, {"port", required_argument, 0, 'p'}, - {"max_members", required_argument, 0, 'm'}, + {"max-members", required_argument, 0, 'm'}, {"password", required_argument, 0, 'w'}, {"preferred-game", required_argument, 0, 'g'}, {"preferred-game-id", required_argument, 0, 'i'}, @@ -230,7 +229,7 @@ void LaunchRoom(int argc, char** argv, bool called_by_option) {"web-api-url", required_argument, 0, 'a'}, {"ban-list-file", required_argument, 0, 'b'}, {"log-file", required_argument, 0, 'l'}, - {"enable-yuzu-mods", no_argument, 0, 'e'}, + {"enable-mods", no_argument, 0, 'e'}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'v'}, // Entry option @@ -243,7 +242,9 @@ void LaunchRoom(int argc, char** argv, bool called_by_option) while (optind < argc) { int arg = getopt_long(argc, argv, "n:d:s:p:m:w:g:u:t:a:i:l:hv", long_options, &option_index); if (arg != -1) { - switch (static_cast(arg)) { + char carg = static_cast(arg); + + switch (carg) { case 'n': room_name.assign(optarg); break; @@ -289,6 +290,8 @@ void LaunchRoom(int argc, char** argv, bool called_by_option) case 'v': PrintVersion(); std::exit(0); + default: + break; } } } @@ -373,9 +376,8 @@ void LaunchRoom(int argc, char** argv, bool called_by_option) verify_backend = std::make_unique(); } - Network::RoomNetwork network{}; - network.Init(); - if (auto room = network.GetRoom().lock()) { + Network::Init(); + if (auto room = Network::GetRoom().lock()) { AnnounceMultiplayerRoom::GameInfo preferred_game_info{.name = preferred_game, .id = preferred_game_id}; if (!room->Create(room_name, room_description, bind_address, static_cast(port), @@ -385,7 +387,7 @@ void LaunchRoom(int argc, char** argv, bool called_by_option) std::exit(-1); } LOG_INFO(Network, "Room is open. Close with Q+Enter..."); - auto announce_session = std::make_unique(network); + auto announce_session = std::make_unique(); if (announce) { announce_session->Start(); } @@ -407,7 +409,7 @@ void LaunchRoom(int argc, char** argv, bool called_by_option) } room->Destroy(); } - network.Shutdown(); + Network::Shutdown(); detached_tasks.WaitForAllTasks(); std::exit(0); } diff --git a/src/network/announce_multiplayer_session.cpp b/src/network/announce_multiplayer_session.cpp index 6737ce85ad..35082cbd31 100644 --- a/src/network/announce_multiplayer_session.cpp +++ b/src/network/announce_multiplayer_session.cpp @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra 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 #include #include @@ -19,8 +22,7 @@ namespace Core { // Time between room is announced to web_service static constexpr std::chrono::seconds announce_time_interval(15); -AnnounceMultiplayerSession::AnnounceMultiplayerSession(Network::RoomNetwork& room_network_) - : room_network{room_network_} { +AnnounceMultiplayerSession::AnnounceMultiplayerSession() { #ifdef ENABLE_WEB_SERVICE backend = std::make_unique(Settings::values.web_api_url.GetValue(), Settings::values.yuzu_username.GetValue(), @@ -31,7 +33,7 @@ AnnounceMultiplayerSession::AnnounceMultiplayerSession(Network::RoomNetwork& roo } WebService::WebResult AnnounceMultiplayerSession::Register() { - auto room = room_network.GetRoom().lock(); + auto room = Network::GetRoom().lock(); if (!room) { return WebService::WebResult{WebService::WebResult::Code::LibError, "Network is not initialized", ""}; @@ -120,7 +122,7 @@ void AnnounceMultiplayerSession::AnnounceMultiplayerLoop() { std::future future; while (!shutdown_event.WaitUntil(update_time)) { update_time += announce_time_interval; - auto room = room_network.GetRoom().lock(); + auto room = Network::GetRoom().lock(); if (!room) { break; } diff --git a/src/network/announce_multiplayer_session.h b/src/network/announce_multiplayer_session.h index db790f7d2d..9d9673d97a 100644 --- a/src/network/announce_multiplayer_session.h +++ b/src/network/announce_multiplayer_session.h @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra 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 @@ -15,7 +18,6 @@ namespace Network { class Room; -class RoomNetwork; } // namespace Network namespace Core { @@ -28,7 +30,8 @@ namespace Core { class AnnounceMultiplayerSession { public: using CallbackHandle = std::shared_ptr>; - AnnounceMultiplayerSession(Network::RoomNetwork& room_network_); + + AnnounceMultiplayerSession(); ~AnnounceMultiplayerSession(); /** @@ -91,8 +94,6 @@ private: std::unique_ptr backend; std::atomic_bool registered = false; ///< Whether the room has been registered - - Network::RoomNetwork& room_network; }; } // namespace Core diff --git a/src/network/network.cpp b/src/network/network.cpp index 6652a186bb..0314b51d2c 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra 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 "common/assert.h" #include "common/logging/log.h" #include "enet/enet.h" @@ -8,40 +11,38 @@ namespace Network { -RoomNetwork::RoomNetwork() { - m_room = std::make_shared(); - m_room_member = std::make_shared(); -} +static std::shared_ptr g_room_member; ///< RoomMember (Client) for network games +static std::shared_ptr g_room; ///< Room (Server) for network games -bool RoomNetwork::Init() { +bool Init() { if (enet_initialize() != 0) { LOG_ERROR(Network, "Error initializing ENet"); return false; } - m_room = std::make_shared(); - m_room_member = std::make_shared(); + g_room = std::make_shared(); + g_room_member = std::make_shared(); LOG_DEBUG(Network, "initialized OK"); return true; } -std::weak_ptr RoomNetwork::GetRoom() { - return m_room; +std::weak_ptr GetRoom() { + return g_room; } -std::weak_ptr RoomNetwork::GetRoomMember() { - return m_room_member; +std::weak_ptr GetRoomMember() { + return g_room_member; } -void RoomNetwork::Shutdown() { - if (m_room_member) { - if (m_room_member->IsConnected()) - m_room_member->Leave(); - m_room_member.reset(); +void Shutdown() { + if (g_room_member) { + if (g_room_member->IsConnected()) + g_room_member->Leave(); + g_room_member.reset(); } - if (m_room) { - if (m_room->GetState() == Room::State::Open) - m_room->Destroy(); - m_room.reset(); + if (g_room) { + if (g_room->GetState() == Room::State::Open) + g_room->Destroy(); + g_room.reset(); } enet_deinitialize(); LOG_DEBUG(Network, "shutdown OK"); diff --git a/src/network/network.h b/src/network/network.h index e4de207b27..1e1a19a3b9 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra 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 @@ -9,25 +12,16 @@ namespace Network { -class RoomNetwork { -public: - RoomNetwork(); +/// Initializes and registers the network device, the room, and the room member. +bool Init(); - /// Initializes and registers the network device, the room, and the room member. - bool Init(); +/// Returns a pointer to the room handle +std::weak_ptr GetRoom(); - /// Returns a pointer to the room handle - std::weak_ptr GetRoom(); +/// Returns a pointer to the room member handle +std::weak_ptr GetRoomMember(); - /// Returns a pointer to the room member handle - std::weak_ptr GetRoomMember(); - - /// Unregisters the network device, the room, and the room member and shut them down. - void Shutdown(); - -private: - std::shared_ptr m_room_member; ///< RoomMember (Client) for network games - std::shared_ptr m_room; ///< Room (Server) for network games -}; +/// Unregisters the network device, the room, and the room member and shut them down. +void Shutdown(); } // namespace Network diff --git a/src/network/room.cpp b/src/network/room.cpp index 49d7ed3313..a4acdad859 100644 --- a/src/network/room.cpp +++ b/src/network/room.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -// SPDX-FileCopyrightText: Copyright yuzu/Citra Emulator Project / Eden Emulator Project +// SPDX-FileCopyrightText: 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/network/room.h b/src/network/room.h index 780629ada3..a2ae792431 100644 --- a/src/network/room.h +++ b/src/network/room.h @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -// SPDX-FileCopyrightText: Copyright yuzu/Citra Emulator Project / Eden Emulator Project +// SPDX-FileCopyrightText: 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 440ef3c46d..1319511989 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -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 set(CMAKE_AUTOMOC ON) diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 8d773753c1..fb75096a7c 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -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 diff --git a/src/yuzu/configuration/configure_touch_from_button.cpp b/src/yuzu/configuration/configure_touch_from_button.cpp index a6c0cd6c77..dd8a75ef8e 100644 --- a/src/yuzu/configuration/configure_touch_from_button.cpp +++ b/src/yuzu/configuration/configure_touch_from_button.cpp @@ -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 diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp index 8c3bbf1af4..67221d2485 100644 --- a/src/yuzu/configuration/configure_ui.cpp +++ b/src/yuzu/configuration/configure_ui.cpp @@ -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 "yuzu/configuration/configure_ui.h" diff --git a/src/yuzu/configuration/configure_web.cpp b/src/yuzu/configuration/configure_web.cpp index a513e1c1b0..f7902fb773 100644 --- a/src/yuzu/configuration/configure_web.cpp +++ b/src/yuzu/configuration/configure_web.cpp @@ -9,30 +9,30 @@ #include "yuzu/configuration/configure_web.h" #include "yuzu/uisettings.h" -static constexpr char token_delimiter{':'}; +// static constexpr char token_delimiter{':'}; -static std::string GenerateDisplayToken(const std::string& username, const std::string& token) { - if (username.empty() || token.empty()) { - return {}; - } +// static std::string GenerateDisplayToken(const std::string& username, const std::string& token) { +// if (username.empty() || token.empty()) { +// return {}; +// } - const std::string unencoded_display_token{username + token_delimiter + token}; - QByteArray b{unencoded_display_token.c_str()}; - QByteArray b64 = b.toBase64(); - return b64.toStdString(); -} +// const std::string unencoded_display_token{username + token_delimiter + token}; +// QByteArray b{unencoded_display_token.c_str()}; +// QByteArray b64 = b.toBase64(); +// return b64.toStdString(); +// } -static std::string UsernameFromDisplayToken(const std::string& display_token) { - const std::string unencoded_display_token{ - QByteArray::fromBase64(display_token.c_str()).toStdString()}; - return unencoded_display_token.substr(0, unencoded_display_token.find(token_delimiter)); -} +// static std::string UsernameFromDisplayToken(const std::string& display_token) { +// const std::string unencoded_display_token{ +// QByteArray::fromBase64(display_token.c_str()).toStdString()}; +// return unencoded_display_token.substr(0, unencoded_display_token.find(token_delimiter)); +// } -static std::string TokenFromDisplayToken(const std::string& display_token) { - const std::string unencoded_display_token{ - QByteArray::fromBase64(display_token.c_str()).toStdString()}; - return unencoded_display_token.substr(unencoded_display_token.find(token_delimiter) + 1); -} +// static std::string TokenFromDisplayToken(const std::string& display_token) { +// const std::string unencoded_display_token{ +// QByteArray::fromBase64(display_token.c_str()).toStdString()}; +// return unencoded_display_token.substr(unencoded_display_token.find(token_delimiter) + 1); +// } ConfigureWeb::ConfigureWeb(QWidget* parent) : QWidget(parent), ui(std::make_unique()) { @@ -66,7 +66,7 @@ void ConfigureWeb::RetranslateUI() { "color:#039be5;\">Sign up")); ui->web_token_info_link->setText( - tr("What is my token?")); } @@ -76,14 +76,10 @@ void ConfigureWeb::SetConfiguration() { ui->web_signup_link->setOpenExternalLinks(true); ui->web_token_info_link->setOpenExternalLinks(true); - if (Settings::values.yuzu_username.GetValue().empty()) { - ui->username->setText(tr("Unspecified")); - } else { - ui->username->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue())); - } - - ui->edit_token->setText(QString::fromStdString(GenerateDisplayToken( - Settings::values.yuzu_username.GetValue(), Settings::values.yuzu_token.GetValue()))); + ui->edit_username->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue())); + ui->edit_token->setText(QString::fromStdString(Settings::values.yuzu_token.GetValue())); + // ui->edit_token->setText(QString::fromStdString(GenerateDisplayToken( + // Settings::values.yuzu_username.GetValue(), Settings::values.yuzu_token.GetValue()))); // Connect after setting the values, to avoid calling OnLoginChanged now connect(ui->edit_token, &QLineEdit::textChanged, this, &ConfigureWeb::OnLoginChanged); @@ -95,15 +91,8 @@ void ConfigureWeb::SetConfiguration() { void ConfigureWeb::ApplyConfiguration() { UISettings::values.enable_discord_presence = ui->toggle_discordrpc->isChecked(); - if (user_verified) { - Settings::values.yuzu_username = - UsernameFromDisplayToken(ui->edit_token->text().toStdString()); - Settings::values.yuzu_token = TokenFromDisplayToken(ui->edit_token->text().toStdString()); - } else { - QMessageBox::warning( - this, tr("Token not verified"), - tr("Token was not verified. The change to your token has not been saved.")); - } + Settings::values.yuzu_username = ui->edit_username->text().toStdString(); + Settings::values.yuzu_token = ui->edit_token->text().toStdString(); } void ConfigureWeb::OnLoginChanged() { @@ -124,30 +113,34 @@ void ConfigureWeb::OnLoginChanged() { } void ConfigureWeb::VerifyLogin() { - ui->button_verify_login->setDisabled(true); - ui->button_verify_login->setText(tr("Verifying...")); - ui->label_token_verified->setPixmap(QIcon::fromTheme(QStringLiteral("sync")).pixmap(16)); - ui->label_token_verified->setToolTip(tr("Verifying...")); + QMessageBox::warning(this, + tr("Warning"), + tr("Verification is currently nonfunctional, instead generate a random " + "48-character string with only lowercase a-z.")); + // ui->button_verify_login->setDisabled(true); + // ui->button_verify_login->setText(tr("Verifying...")); + // ui->label_token_verified->setPixmap(QIcon::fromTheme(QStringLiteral("sync")).pixmap(16)); + // ui->label_token_verified->setToolTip(tr("Verifying...")); } void ConfigureWeb::OnLoginVerified() { - ui->button_verify_login->setEnabled(true); - ui->button_verify_login->setText(tr("Verify")); - if (verify_watcher.result()) { - user_verified = true; + // ui->button_verify_login->setEnabled(true); + // ui->button_verify_login->setText(tr("Verify")); + // if (verify_watcher.result()) { + // user_verified = true; - ui->label_token_verified->setPixmap(QIcon::fromTheme(QStringLiteral("checked")).pixmap(16)); - ui->label_token_verified->setToolTip(tr("Verified", "Tooltip")); - ui->username->setText( - QString::fromStdString(UsernameFromDisplayToken(ui->edit_token->text().toStdString()))); - } else { - ui->label_token_verified->setPixmap(QIcon::fromTheme(QStringLiteral("failed")).pixmap(16)); - ui->label_token_verified->setToolTip(tr("Verification failed", "Tooltip")); - ui->username->setText(tr("Unspecified")); - QMessageBox::critical(this, tr("Verification failed"), - tr("Verification failed. Check that you have entered your token " - "correctly, and that your internet connection is working.")); - } + // ui->label_token_verified->setPixmap(QIcon::fromTheme(QStringLiteral("checked")).pixmap(16)); + // ui->label_token_verified->setToolTip(tr("Verified", "Tooltip")); + // ui->username->setText( + // QString::fromStdString(UsernameFromDisplayToken(ui->edit_token->text().toStdString()))); + // } else { + // ui->label_token_verified->setPixmap(QIcon::fromTheme(QStringLiteral("failed")).pixmap(16)); + // ui->label_token_verified->setToolTip(tr("Verification failed", "Tooltip")); + // ui->username->setText(tr("Unspecified")); + // QMessageBox::critical(this, tr("Verification failed"), + // tr("Verification failed. Check that you have entered your token " + // "correctly, and that your internet connection is working.")); + // } } void ConfigureWeb::SetWebServiceConfigEnabled(bool enabled) { diff --git a/src/yuzu/configuration/configure_web.ui b/src/yuzu/configuration/configure_web.ui index 942fb05b26..ac9b6954cd 100644 --- a/src/yuzu/configuration/configure_web.ui +++ b/src/yuzu/configuration/configure_web.ui @@ -43,7 +43,7 @@ - Qt::RightToLeft + Qt::LayoutDirection::RightToLeft Verify @@ -52,13 +52,23 @@ + + false + Sign up - + + + 20 + + + QLineEdit::EchoMode::Normal + + @@ -83,7 +93,7 @@ 80 - QLineEdit::Password + QLineEdit::EchoMode::Normal @@ -97,7 +107,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -143,7 +153,7 @@ - Qt::Vertical + Qt::Orientation::Vertical diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 3fec5b7f61..1cfa37c9e4 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -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 diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 7e31fdae4d..c1f71237ad 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -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 @@ -351,7 +351,7 @@ GMainWindow::GMainWindow(bool has_broken_vulkan) play_time_manager = std::make_unique(system->GetProfileManager()); - system->GetRoomNetwork().Init(); + Network::Init(); RegisterMetaTypes(); @@ -5183,7 +5183,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) { render_window->close(); multiplayer_state->Close(); system->HIDCore().UnloadInputDevices(); - system->GetRoomNetwork().Shutdown(); + Network::Shutdown(); QWidget::closeEvent(event); } diff --git a/src/yuzu/multiplayer/chat_room.cpp b/src/yuzu/multiplayer/chat_room.cpp index 4463616b45..5925266b40 100644 --- a/src/yuzu/multiplayer/chat_room.cpp +++ b/src/yuzu/multiplayer/chat_room.cpp @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra 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 #include #include @@ -27,8 +30,7 @@ class ChatMessage { public: - explicit ChatMessage(const Network::ChatEntry& chat, Network::RoomNetwork& room_network, - QTime ts = {}) { + explicit ChatMessage(const Network::ChatEntry& chat, QTime ts = {}) { /// Convert the time to their default locale defined format QLocale locale; timestamp = locale.toString(ts.isValid() ? ts : QTime::currentTime(), QLocale::ShortFormat); @@ -38,7 +40,7 @@ public: // Check for user pings QString cur_nickname, cur_username; - if (auto room = room_network.GetRoomMember().lock()) { + if (auto room = Network::GetRoomMember().lock()) { cur_nickname = QString::fromStdString(room->GetNickname()); cur_username = QString::fromStdString(room->GetUsername()); } @@ -202,10 +204,9 @@ ChatRoom::ChatRoom(QWidget* parent) : QWidget(parent), ui(std::make_uniqueGetRoomMember().lock()) { + if (auto member = Network::GetRoomMember().lock()) { member->BindOnChatMessageReceived( [this](const Network::ChatEntry& chat) { emit ChatReceived(chat); }); member->BindOnStatusMessageReceived( @@ -239,7 +240,7 @@ void ChatRoom::AppendChatMessage(const QString& msg) { } void ChatRoom::SendModerationRequest(Network::RoomMessageTypes type, const std::string& nickname) { - if (auto room = room_network->GetRoomMember().lock()) { + if (auto room = Network::GetRoomMember().lock()) { auto members = room->GetMemberInformation(); auto it = std::find_if(members.begin(), members.end(), [&nickname](const Network::RoomMember::MemberInformation& member) { @@ -259,7 +260,7 @@ bool ChatRoom::ValidateMessage(const std::string& msg) { void ChatRoom::OnRoomUpdate(const Network::RoomInformation& info) { // TODO(B3N30): change title - if (auto room_member = room_network->GetRoomMember().lock()) { + if (auto room_member = Network::GetRoomMember().lock()) { SetPlayerList(room_member->GetMemberInformation()); } } @@ -278,7 +279,7 @@ void ChatRoom::OnChatReceive(const Network::ChatEntry& chat) { if (!ValidateMessage(chat.message)) { return; } - if (auto room = room_network->GetRoomMember().lock()) { + if (auto room = Network::GetRoomMember().lock()) { // get the id of the player auto members = room->GetMemberInformation(); auto it = std::find_if(members.begin(), members.end(), @@ -296,7 +297,7 @@ void ChatRoom::OnChatReceive(const Network::ChatEntry& chat) { return; } auto player = std::distance(members.begin(), it); - ChatMessage m(chat, *room_network); + ChatMessage m(chat); if (m.ContainsPing()) { emit UserPinged(); } @@ -335,7 +336,7 @@ void ChatRoom::OnStatusMessageReceive(const Network::StatusMessageEntry& status_ } void ChatRoom::OnSendChat() { - if (auto room_member = room_network->GetRoomMember().lock()) { + if (auto room_member = Network::GetRoomMember().lock()) { if (!room_member->IsConnected()) { return; } @@ -357,7 +358,7 @@ void ChatRoom::OnSendChat() { LOG_INFO(Network, "Cannot find self in the player list when sending a message."); } auto player = std::distance(members.begin(), it); - ChatMessage m(chat, *room_network); + ChatMessage m(chat); room_member->SendChatMessage(message); AppendChatMessage(m.GetPlayerChatMessage(player)); ui->chat_message->clear(); @@ -451,7 +452,7 @@ void ChatRoom::PopupContextMenu(const QPoint& menu_location) { } std::string cur_nickname; - if (auto room = room_network->GetRoomMember().lock()) { + if (auto room = Network::GetRoomMember().lock()) { cur_nickname = room->GetNickname(); } diff --git a/src/yuzu/multiplayer/chat_room.h b/src/yuzu/multiplayer/chat_room.h index dd71ea4cdd..f295ea7a7c 100644 --- a/src/yuzu/multiplayer/chat_room.h +++ b/src/yuzu/multiplayer/chat_room.h @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra 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 @@ -30,7 +33,7 @@ class ChatRoom : public QWidget { public: explicit ChatRoom(QWidget* parent); - void Initialize(Network::RoomNetwork* room_network); + void Initialize(); void RetranslateUi(); void SetPlayerList(const Network::RoomMember::MemberList& member_list); void Clear(); @@ -66,7 +69,6 @@ private: std::unique_ptr ui; std::unordered_set block_list; std::unordered_map icon_cache; - Network::RoomNetwork* room_network; }; Q_DECLARE_METATYPE(Network::ChatEntry); diff --git a/src/yuzu/multiplayer/client_room.cpp b/src/yuzu/multiplayer/client_room.cpp index caf34a414f..3453ae34d5 100644 --- a/src/yuzu/multiplayer/client_room.cpp +++ b/src/yuzu/multiplayer/client_room.cpp @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra 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 #include #include @@ -18,14 +21,14 @@ #include "yuzu/multiplayer/moderation_dialog.h" #include "yuzu/multiplayer/state.h" -ClientRoomWindow::ClientRoomWindow(QWidget* parent, Network::RoomNetwork& room_network_) +ClientRoomWindow::ClientRoomWindow(QWidget* parent) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint), - ui(std::make_unique()), room_network{room_network_} { + ui(std::make_unique()) { ui->setupUi(this); - ui->chat->Initialize(&room_network); + ui->chat->Initialize(); // setup the callbacks for network updates - if (auto member = room_network.GetRoomMember().lock()) { + if (auto member = Network::GetRoomMember().lock()) { member->BindOnRoomInformationChanged( [this](const Network::RoomInformation& info) { emit RoomInformationChanged(info); }); member->BindOnStateChanged( @@ -44,7 +47,7 @@ ClientRoomWindow::ClientRoomWindow(QWidget* parent, Network::RoomNetwork& room_n ui->disconnect->setDefault(false); ui->disconnect->setAutoDefault(false); connect(ui->moderation, &QPushButton::clicked, [this] { - ModerationDialog dialog(room_network, this); + ModerationDialog dialog(this); dialog.exec(); }); ui->moderation->setDefault(false); @@ -90,7 +93,7 @@ void ClientRoomWindow::Disconnect() { } void ClientRoomWindow::UpdateView() { - if (auto member = room_network.GetRoomMember().lock()) { + if (auto member = Network::GetRoomMember().lock()) { if (member->IsConnected()) { ui->chat->Enable(); ui->disconnect->setEnabled(true); diff --git a/src/yuzu/multiplayer/client_room.h b/src/yuzu/multiplayer/client_room.h index f338e3c592..6990c56e50 100644 --- a/src/yuzu/multiplayer/client_room.h +++ b/src/yuzu/multiplayer/client_room.h @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra 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 "yuzu/multiplayer/chat_room.h" @@ -13,7 +16,7 @@ class ClientRoomWindow : public QDialog { Q_OBJECT public: - explicit ClientRoomWindow(QWidget* parent, Network::RoomNetwork& room_network_); + explicit ClientRoomWindow(QWidget* parent); ~ClientRoomWindow(); void RetranslateUi(); @@ -35,5 +38,4 @@ private: QStandardItemModel* player_list; std::unique_ptr ui; - Network::RoomNetwork& room_network; }; diff --git a/src/yuzu/multiplayer/direct_connect.cpp b/src/yuzu/multiplayer/direct_connect.cpp index 74da97e218..693cffe0d0 100644 --- a/src/yuzu/multiplayer/direct_connect.cpp +++ b/src/yuzu/multiplayer/direct_connect.cpp @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra 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 #include #include @@ -24,8 +27,7 @@ enum class ConnectionType : u8 { TraversalServer, IP }; DirectConnectWindow::DirectConnectWindow(Core::System& system_, QWidget* parent) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint), - ui(std::make_unique()), system{system_}, room_network{ - system.GetRoomNetwork()} { + ui(std::make_unique()), system{system_} { ui->setupUi(this); @@ -71,7 +73,7 @@ void DirectConnectWindow::Connect() { return; } } - if (const auto member = room_network.GetRoomMember().lock()) { + if (const auto member = Network::GetRoomMember().lock()) { // Prevent the user from trying to join a room while they are already joining. if (member->GetState() == Network::RoomMember::State::Joining) { return; @@ -104,7 +106,7 @@ void DirectConnectWindow::Connect() { // attempt to connect in a different thread QFuture f = QtConcurrent::run([&] { - if (auto room_member = room_network.GetRoomMember().lock()) { + if (auto room_member = Network::GetRoomMember().lock()) { auto port = UISettings::values.multiplayer_port.GetValue(); room_member->Join(ui->nickname->text().toStdString(), ui->ip->text().toStdString().c_str(), port, 0, Network::NoPreferredIP, @@ -129,7 +131,7 @@ void DirectConnectWindow::EndConnecting() { void DirectConnectWindow::OnConnection() { EndConnecting(); - if (auto room_member = room_network.GetRoomMember().lock()) { + if (auto room_member = Network::GetRoomMember().lock()) { if (room_member->IsConnected()) { close(); } diff --git a/src/yuzu/multiplayer/direct_connect.h b/src/yuzu/multiplayer/direct_connect.h index b8f66cfb2b..e7efaecbd2 100644 --- a/src/yuzu/multiplayer/direct_connect.h +++ b/src/yuzu/multiplayer/direct_connect.h @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra 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 @@ -45,5 +48,4 @@ private: std::unique_ptr ui; Validation validation; Core::System& system; - Network::RoomNetwork& room_network; }; diff --git a/src/yuzu/multiplayer/host_room.cpp b/src/yuzu/multiplayer/host_room.cpp index 09f783ad9f..fd047b4b5a 100644 --- a/src/yuzu/multiplayer/host_room.cpp +++ b/src/yuzu/multiplayer/host_room.cpp @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra 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 #include #include @@ -32,8 +35,7 @@ HostRoomWindow::HostRoomWindow(QWidget* parent, QStandardItemModel* list, Core::System& system_) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint), ui(std::make_unique()), - announce_multiplayer_session(session), system{system_}, room_network{ - system.GetRoomNetwork()} { + announce_multiplayer_session(session), system{system_} { ui->setupUi(this); // set up validation for all of the fields @@ -137,7 +139,7 @@ void HostRoomWindow::Host() { return; } } - if (auto member = room_network.GetRoomMember().lock()) { + if (auto member = Network::GetRoomMember().lock()) { if (member->GetState() == Network::RoomMember::State::Joining) { return; } else if (member->IsConnected()) { @@ -161,7 +163,7 @@ void HostRoomWindow::Host() { if (ui->load_ban_list->isChecked()) { ban_list = UISettings::values.multiplayer_ban_list; } - if (auto room = room_network.GetRoom().lock()) { + if (auto room = Network::GetRoom().lock()) { const bool created = room->Create(ui->room_name->text().toStdString(), ui->room_description->toPlainText().toStdString(), "", port, password, @@ -190,7 +192,7 @@ void HostRoomWindow::Host() { QString::fromStdString(result.result_string), QMessageBox::Ok); ui->host->setEnabled(true); - if (auto room = room_network.GetRoom().lock()) { + if (auto room = Network::GetRoom().lock()) { room->Destroy(); } return; @@ -206,7 +208,7 @@ void HostRoomWindow::Host() { WebService::Client client(Settings::values.web_api_url.GetValue(), Settings::values.yuzu_username.GetValue(), Settings::values.yuzu_token.GetValue()); - if (auto room = room_network.GetRoom().lock()) { + if (auto room = Network::GetRoom().lock()) { token = client.GetExternalJWT(room->GetVerifyUID()).returned_data; } if (token.empty()) { diff --git a/src/yuzu/multiplayer/host_room.h b/src/yuzu/multiplayer/host_room.h index ae816e2e03..d9b08d2c8c 100644 --- a/src/yuzu/multiplayer/host_room.h +++ b/src/yuzu/multiplayer/host_room.h @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra 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 @@ -59,7 +62,6 @@ private: ComboBoxProxyModel* proxy; Validation validation; Core::System& system; - Network::RoomNetwork& room_network; }; /** diff --git a/src/yuzu/multiplayer/lobby.cpp b/src/yuzu/multiplayer/lobby.cpp index 52df2456e5..bc91145b97 100644 --- a/src/yuzu/multiplayer/lobby.cpp +++ b/src/yuzu/multiplayer/lobby.cpp @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra 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 #include #include @@ -28,8 +31,7 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list, std::shared_ptr session, Core::System& system_) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint), ui(std::make_unique()), - announce_multiplayer_session(session), system{system_}, room_network{ - system.GetRoomNetwork()} { + announce_multiplayer_session(session), system{system_} { ui->setupUi(this); // setup the watcher for background connections @@ -146,7 +148,7 @@ void Lobby::OnJoinRoom(const QModelIndex& source) { } } - if (const auto member = room_network.GetRoomMember().lock()) { + if (const auto member = Network::GetRoomMember().lock()) { // Prevent the user from trying to join a room while they are already joining. if (member->GetState() == Network::RoomMember::State::Joining) { return; @@ -184,7 +186,7 @@ void Lobby::OnJoinRoom(const QModelIndex& source) { proxy->data(connection_index, LobbyItemHost::HostVerifyUIDRole).toString().toStdString(); // attempt to connect in a different thread - QFuture f = QtConcurrent::run([nickname, ip, port, password, verify_uid, this] { + QFuture f = QtConcurrent::run([nickname, ip, port, password, verify_uid] { std::string token; #ifdef ENABLE_WEB_SERVICE if (!Settings::values.yuzu_username.GetValue().empty() && @@ -200,7 +202,7 @@ void Lobby::OnJoinRoom(const QModelIndex& source) { } } #endif - if (auto room_member = room_network.GetRoomMember().lock()) { + if (auto room_member = Network::GetRoomMember().lock()) { room_member->Join(nickname, ip.c_str(), port, 0, Network::NoPreferredIP, password, token); } diff --git a/src/yuzu/multiplayer/lobby.h b/src/yuzu/multiplayer/lobby.h index e78c9cae3c..4d4e7bd5e4 100644 --- a/src/yuzu/multiplayer/lobby.h +++ b/src/yuzu/multiplayer/lobby.h @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2017 Citra 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 @@ -102,7 +105,6 @@ private: QFutureWatcher* watcher; Validation validation; Core::System& system; - Network::RoomNetwork& room_network; }; /** diff --git a/src/yuzu/multiplayer/moderation_dialog.cpp b/src/yuzu/multiplayer/moderation_dialog.cpp index c9b8ed397a..1a06d661d5 100644 --- a/src/yuzu/multiplayer/moderation_dialog.cpp +++ b/src/yuzu/multiplayer/moderation_dialog.cpp @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2018 Citra 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 #include #include "network/network.h" @@ -16,13 +19,13 @@ enum { }; } -ModerationDialog::ModerationDialog(Network::RoomNetwork& room_network_, QWidget* parent) - : QDialog(parent), ui(std::make_unique()), room_network{room_network_} { +ModerationDialog::ModerationDialog(QWidget* parent) + : QDialog(parent), ui(std::make_unique()) { ui->setupUi(this); qRegisterMetaType(); - if (auto member = room_network.GetRoomMember().lock()) { + if (auto member = Network::GetRoomMember().lock()) { callback_handle_status_message = member->BindOnStatusMessageReceived( [this](const Network::StatusMessageEntry& status_message) { emit StatusMessageReceived(status_message); @@ -55,20 +58,20 @@ ModerationDialog::ModerationDialog(Network::RoomNetwork& room_network_, QWidget* ModerationDialog::~ModerationDialog() { if (callback_handle_status_message) { - if (auto room = room_network.GetRoomMember().lock()) { + if (auto room = Network::GetRoomMember().lock()) { room->Unbind(callback_handle_status_message); } } if (callback_handle_ban_list) { - if (auto room = room_network.GetRoomMember().lock()) { + if (auto room = Network::GetRoomMember().lock()) { room->Unbind(callback_handle_ban_list); } } } void ModerationDialog::LoadBanList() { - if (auto room = room_network.GetRoomMember().lock()) { + if (auto room = Network::GetRoomMember().lock()) { ui->refresh->setEnabled(false); ui->refresh->setText(tr("Refreshing")); ui->unban->setEnabled(false); @@ -97,7 +100,7 @@ void ModerationDialog::PopulateBanList(const Network::Room::BanList& ban_list) { } void ModerationDialog::SendUnbanRequest(const QString& subject) { - if (auto room = room_network.GetRoomMember().lock()) { + if (auto room = Network::GetRoomMember().lock()) { room->SendModerationRequest(Network::IdModUnban, subject.toStdString()); } } diff --git a/src/yuzu/multiplayer/moderation_dialog.h b/src/yuzu/multiplayer/moderation_dialog.h index e9e5daff79..4d32a6895e 100644 --- a/src/yuzu/multiplayer/moderation_dialog.h +++ b/src/yuzu/multiplayer/moderation_dialog.h @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2018 Citra 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 @@ -19,7 +22,7 @@ class ModerationDialog : public QDialog { Q_OBJECT public: - explicit ModerationDialog(Network::RoomNetwork& room_network_, QWidget* parent = nullptr); + explicit ModerationDialog(QWidget* parent = nullptr); ~ModerationDialog(); signals: @@ -36,8 +39,6 @@ private: QStandardItemModel* model; Network::RoomMember::CallbackHandle callback_handle_status_message; Network::RoomMember::CallbackHandle callback_handle_ban_list; - - Network::RoomNetwork& room_network; }; Q_DECLARE_METATYPE(Network::Room::BanList); diff --git a/src/yuzu/multiplayer/state.cpp b/src/yuzu/multiplayer/state.cpp index d82ca9aee5..d5529712b0 100644 --- a/src/yuzu/multiplayer/state.cpp +++ b/src/yuzu/multiplayer/state.cpp @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2018 Citra 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 #include #include @@ -22,8 +25,8 @@ MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_list_model_, QAction* leave_room_, QAction* show_room_, Core::System& system_) : QWidget(parent), game_list_model(game_list_model_), leave_room(leave_room_), - show_room(show_room_), system{system_}, room_network{system.GetRoomNetwork()} { - if (auto member = room_network.GetRoomMember().lock()) { + show_room(show_room_), system{system_} { + if (auto member = Network::GetRoomMember().lock()) { // register the network structs to use in slots and signals state_callback_handle = member->BindOnStateChanged( [this](const Network::RoomMember::State& state) { emit NetworkStateChanged(state); }); @@ -37,7 +40,7 @@ MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_lis qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); - announce_multiplayer_session = std::make_shared(room_network); + announce_multiplayer_session = std::make_shared(); announce_multiplayer_session->BindErrorCallback( [this](const WebService::WebResult& result) { emit AnnounceFailed(result); }); connect(this, &MultiplayerState::AnnounceFailed, this, &MultiplayerState::OnAnnounceFailed); @@ -62,13 +65,13 @@ MultiplayerState::~MultiplayerState() = default; void MultiplayerState::Close() { if (state_callback_handle) { - if (auto member = room_network.GetRoomMember().lock()) { + if (auto member = Network::GetRoomMember().lock()) { member->Unbind(state_callback_handle); } } if (error_callback_handle) { - if (auto member = room_network.GetRoomMember().lock()) { + if (auto member = Network::GetRoomMember().lock()) { member->Unbind(error_callback_handle); } } @@ -256,9 +259,9 @@ void MultiplayerState::OnCreateRoom() { bool MultiplayerState::OnCloseRoom() { if (!NetworkMessage::WarnCloseRoom()) return false; - if (auto room = room_network.GetRoom().lock()) { + if (auto room = Network::GetRoom().lock()) { // if you are in a room, leave it - if (auto member = room_network.GetRoomMember().lock()) { + if (auto member = Network::GetRoomMember().lock()) { member->Leave(); LOG_DEBUG(Frontend, "Left the room (as a client)"); } @@ -292,10 +295,10 @@ void MultiplayerState::HideNotification() { } void MultiplayerState::OnOpenNetworkRoom() { - if (auto member = room_network.GetRoomMember().lock()) { + if (auto member = Network::GetRoomMember().lock()) { if (member->IsConnected()) { if (client_room == nullptr) { - client_room = new ClientRoomWindow(this, room_network); + client_room = new ClientRoomWindow(this); connect(client_room, &ClientRoomWindow::ShowNotification, this, &MultiplayerState::ShowNotification); } diff --git a/src/yuzu/multiplayer/state.h b/src/yuzu/multiplayer/state.h index d6149838f8..4d3dde2162 100644 --- a/src/yuzu/multiplayer/state.h +++ b/src/yuzu/multiplayer/state.h @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2018 Citra 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 @@ -105,7 +108,6 @@ private: bool show_notification = false; Core::System& system; - Network::RoomNetwork& room_network; }; Q_DECLARE_METATYPE(WebService::WebResult); diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 35dc58e4e9..005f5bf1db 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: 2014 Citra 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 #include #include @@ -404,7 +407,7 @@ int main(int argc, char** argv) { } if (use_multiplayer) { - if (auto member = system.GetRoomNetwork().GetRoomMember().lock()) { + if (auto member = Network::GetRoomMember().lock()) { member->BindOnChatMessageReceived(OnMessageReceived); member->BindOnStatusMessageReceived(OnStatusMessageReceived); member->BindOnStateChanged(OnStateChanged); diff --git a/vcpkg.json b/vcpkg.json index d7b1dbb0ce..99ed06cf25 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -38,8 +38,7 @@ "description": "Enable web services (telemetry, etc.)", "dependencies": [ { - "name": "openssl", - "platform": "windows" + "name": "openssl" } ] }