From 94c66f98bfa69f71f5d0623cecac8444e383d34d Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 1 Jul 2025 01:44:12 +0000 Subject: [frontend, web] refactor: web service frontend rewrite (#221) - Automatic verification based on regex - Token generation button - Removed unneeded links - public lobby creation [android] Signed-off-by: crueter Co-authored-by: Aleksandr Popovich Co-authored-by: Aleksandr Popovich Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/221 Co-authored-by: crueter Co-committed-by: crueter --- src/common/android/multiplayer/multiplayer.cpp | 160 +++++++++++++++++-------- 1 file changed, 112 insertions(+), 48 deletions(-) (limited to 'src/common/android/multiplayer/multiplayer.cpp') diff --git a/src/common/android/multiplayer/multiplayer.cpp b/src/common/android/multiplayer/multiplayer.cpp index fe6408fced..26bb800ce2 100644 --- a/src/common/android/multiplayer/multiplayer.cpp +++ b/src/common/android/multiplayer/multiplayer.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #include "common/android/id_cache.h" @@ -10,13 +10,17 @@ #include "network/network.h" #include "android/log.h" +#include "common/settings.h" +#include "web_service/web_backend.h" +#include "web_service/verify_user_jwt.h" +#include "web_service/web_result.h" #include #include namespace IDCache = Common::Android; -AndroidMultiplayer::AndroidMultiplayer(Core::System& system_, +AndroidMultiplayer::AndroidMultiplayer(Core::System &system_, std::shared_ptr session) : system{system_}, announce_multiplayer_session(session) {} @@ -27,8 +31,8 @@ void AndroidMultiplayer::AddNetPlayMessage(jint type, jstring msg) { IDCache::GetAddNetPlayMessage(), type, msg); } -void AndroidMultiplayer::AddNetPlayMessage(int type, const std::string& msg) { - JNIEnv* env = IDCache::GetEnvForThread(); +void AndroidMultiplayer::AddNetPlayMessage(int type, const std::string &msg) { + JNIEnv *env = IDCache::GetEnvForThread(); AddNetPlayMessage(type, Common::Android::ToJString(env, msg)); } @@ -46,7 +50,7 @@ bool AndroidMultiplayer::NetworkInit() { if (auto member = Network::GetRoomMember().lock()) { // register the network structs to use in slots and signals - member->BindOnStateChanged([this](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; @@ -64,7 +68,7 @@ bool AndroidMultiplayer::NetworkInit() { AddNetPlayMessage(static_cast(status), msg); } }); - member->BindOnError([this](const Network::RoomMember::Error& error) { + member->BindOnError([this](const Network::RoomMember::Error &error) { NetPlayStatus status; std::string msg; switch (error) { @@ -107,29 +111,30 @@ bool AndroidMultiplayer::NetworkInit() { } AddNetPlayMessage(static_cast(status), msg); }); - member->BindOnStatusMessageReceived([this](const Network::StatusMessageEntry& status_message) { - NetPlayStatus status = NetPlayStatus::NO_ERROR; - std::string msg(status_message.nickname); - switch (status_message.type) { - case Network::IdMemberJoin: - status = NetPlayStatus::MEMBER_JOIN; - break; - case Network::IdMemberLeave: - status = NetPlayStatus::MEMBER_LEAVE; - break; - case Network::IdMemberKicked: - status = NetPlayStatus::MEMBER_KICKED; - break; - case Network::IdMemberBanned: - status = NetPlayStatus::MEMBER_BANNED; - break; - case Network::IdAddressUnbanned: - status = NetPlayStatus::ADDRESS_UNBANNED; - break; - } - AddNetPlayMessage(static_cast(status), msg); - }); - member->BindOnChatMessageReceived([this](const Network::ChatEntry& chat) { + member->BindOnStatusMessageReceived( + [this](const Network::StatusMessageEntry &status_message) { + NetPlayStatus status = NetPlayStatus::NO_ERROR; + std::string msg(status_message.nickname); + switch (status_message.type) { + case Network::IdMemberJoin: + status = NetPlayStatus::MEMBER_JOIN; + break; + case Network::IdMemberLeave: + status = NetPlayStatus::MEMBER_LEAVE; + break; + case Network::IdMemberKicked: + status = NetPlayStatus::MEMBER_KICKED; + break; + case Network::IdMemberBanned: + status = NetPlayStatus::MEMBER_BANNED; + break; + case Network::IdAddressUnbanned: + status = NetPlayStatus::ADDRESS_UNBANNED; + break; + } + AddNetPlayMessage(static_cast(status), msg); + }); + member->BindOnChatMessageReceived([this](const Network::ChatEntry &chat) { NetPlayStatus status = NetPlayStatus::CHAT_MESSAGE; std::string msg(chat.nickname); msg += ": "; @@ -140,10 +145,14 @@ bool AndroidMultiplayer::NetworkInit() { return true; } -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) { + +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, + bool isPublic) { auto member = Network::GetRoomMember().lock(); if (!member) { return NetPlayStatus::NETWORK_ERROR; @@ -168,17 +177,55 @@ NetPlayStatus AndroidMultiplayer::NetPlayCreateRoom(const std::string& ipaddress .id = preferredGameId, }; - port = (port == 0) ? Network::DefaultRoomPort : static_cast(port); + 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, std::make_unique(), {})) { + static_cast(std::min(max_players, 16)), username, game, + CreateVerifyBackend(isPublic), {})) { return NetPlayStatus::CREATE_ROOM_ERROR; } + // public announce session + if (isPublic) { + if (auto session = announce_multiplayer_session.lock()) { + WebService::WebResult result = session->Register(); + if (result.result_code != WebService::WebResult::Code::Success) { + LOG_ERROR(WebService, "Failed to announce public room lobby"); + room->Destroy(); + return NetPlayStatus::CREATE_ROOM_ERROR; + } + session->Start(); + } else { + LOG_ERROR(Network, "Failed to start announce session"); + } + } + // Failsafe timer to avoid joining before creation std::this_thread::sleep_for(std::chrono::milliseconds(100)); - member->Join(username, ipaddress.c_str(), static_cast(port), 0, Network::NoPreferredIP, password, ""); + std::string token; + // TODO(alekpop): properly handle the compile definition, it's not working right +//#ifdef ENABLE_WEB_SERVICE +// LOG_INFO(WebService, "Web Service enabled"); + if (isPublic) { + WebService::Client client(Settings::values.web_api_url.GetValue(), + Settings::values.eden_username.GetValue(), + Settings::values.eden_token.GetValue()); + + token = client.GetExternalJWT(room->GetVerifyUID()).returned_data; + + if (token.empty()) { + LOG_ERROR(WebService, "Could not get external JWT, verification may fail"); + } else { + LOG_INFO(WebService, "Successfully requested external JWT: size={}", token.size()); + } + } +//#else +// LOG_INFO(WebService, "Web Service disabled"); +//#endif + + member->Join(username, ipaddress.c_str(), static_cast(port), 0, Network::NoPreferredIP, + password, token); // Failsafe timer to avoid joining before creation for (int i = 0; i < 5; i++) { @@ -194,8 +241,9 @@ NetPlayStatus AndroidMultiplayer::NetPlayCreateRoom(const std::string& ipaddress return NetPlayStatus::CREATE_ROOM_ERROR; } -NetPlayStatus AndroidMultiplayer::NetPlayJoinRoom(const std::string& ipaddress, int port, - const std::string& username, const std::string& password) { +NetPlayStatus AndroidMultiplayer::NetPlayJoinRoom(const std::string &ipaddress, int port, + const std::string &username, + const std::string &password) { auto member = Network::GetRoomMember().lock(); if (!member) { return NetPlayStatus::NETWORK_ERROR; @@ -209,7 +257,8 @@ NetPlayStatus AndroidMultiplayer::NetPlayJoinRoom(const std::string& ipaddress, return NetPlayStatus::ALREADY_IN_ROOM; } - member->Join(username, ipaddress.c_str(), static_cast(port), 0, Network::NoPreferredIP, password, ""); + member->Join(username, ipaddress.c_str(), static_cast(port), 0, Network::NoPreferredIP, + password, ""); // Wait a bit for the connection and join process to complete std::this_thread::sleep_for(std::chrono::milliseconds(500)); @@ -226,7 +275,7 @@ NetPlayStatus AndroidMultiplayer::NetPlayJoinRoom(const std::string& ipaddress, return NetPlayStatus::WRONG_PASSWORD; } -void AndroidMultiplayer::NetPlaySendMessage(const std::string& msg) { +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) { @@ -237,11 +286,11 @@ void AndroidMultiplayer::NetPlaySendMessage(const std::string& msg) { } } -void AndroidMultiplayer::NetPlayKickUser(const std::string& username) { +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) { + [&username](const Network::RoomMember::MemberInformation &member) { return member.nickname == username; }); if (it != members.end()) { @@ -250,11 +299,11 @@ void AndroidMultiplayer::NetPlayKickUser(const std::string& username) { } } -void AndroidMultiplayer::NetPlayBanUser(const std::string& username) { +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) { + [&username](const Network::RoomMember::MemberInformation &member) { return member.nickname == username; }); if (it != members.end()) { @@ -263,7 +312,7 @@ void AndroidMultiplayer::NetPlayBanUser(const std::string& username) { } } -void AndroidMultiplayer::NetPlayUnbanUser(const std::string& username) { +void AndroidMultiplayer::NetPlayUnbanUser(const std::string &username) { if (auto room = Network::GetRoomMember().lock()) { room->SendModerationRequest(Network::RoomMessageTypes::IdModUnban, username); } @@ -278,7 +327,7 @@ std::vector AndroidMultiplayer::NetPlayRoomInfo() { auto room_info = room->GetRoomInformation(); info_list.push_back(room_info.name + "|" + std::to_string(room_info.member_slots)); // all members - for (const auto& member : members) { + for (const auto &member: members) { info_list.push_back(member.nickname); } } @@ -368,14 +417,29 @@ std::vector AndroidMultiplayer::NetPlayGetBanList() { auto [username_bans, ip_bans] = room->GetBanList(); // Add username bans - for (const auto& username : username_bans) { + for (const auto &username: username_bans) { ban_list.push_back(username); } // Add IP bans - for (const auto& ip : ip_bans) { + for (const auto &ip: ip_bans) { ban_list.push_back(ip); } } return ban_list; } + +std::unique_ptr AndroidMultiplayer::CreateVerifyBackend(bool use_validation) { + std::unique_ptr verify_backend; + if (use_validation) { +//#ifdef ENABLE_WEB_SERVICE + verify_backend = + std::make_unique(Settings::values.web_api_url.GetValue()); +//#else +// verify_backend = std::make_unique(); +//#endif + } else { + verify_backend = std::make_unique(); + } + return verify_backend; +} \ No newline at end of file -- cgit v1.2.3