mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2025-07-23 13:15:45 +00:00
Added the public lobby to android. (#125)
This is adapted from kleidis old PR to Azahar. Changes from it: - Fixed inconsistent button styling in the dialog for connection - Allowed to hide both empty and full rooms. - Proper serving of preferred games - Enables web service for android by default - Better implementation of multiplayer.cpp that works with oop Also fixes the room network class and turns it into a static namespace in network Signed-off-by: Aleksandr Popovich <alekpopo@pm.me> Co-authored-by: swurl <swurl@swurl.xyz> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/125 Co-authored-by: Aleksandr Popovich <alekpopo@pm.me> Co-committed-by: Aleksandr Popovich <alekpopo@pm.me>
This commit is contained in:
parent
7e13da47af
commit
76fa525592
99 changed files with 1470 additions and 498 deletions
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <jni.h>
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <chrono>
|
||||
|
||||
namespace IDCache = Common::Android;
|
||||
Network::RoomNetwork* room_network;
|
||||
|
||||
void AddNetPlayMessage(jint type, jstring msg) {
|
||||
AndroidMultiplayer::AndroidMultiplayer(Core::System& system_,
|
||||
std::shared_ptr<Core::AnnounceMultiplayerSession> 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<int>(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<int>(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<int>(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<u16>(port);
|
||||
|
||||
if (!room->Create(room_name, "", ipaddress, static_cast<u16>(port), password,
|
||||
static_cast<u32>(std::min(max_players, 16)), username, game, nullptr, {})) {
|
||||
static_cast<u32>(std::min(max_players, 16)), username, game, std::make_unique<Network::VerifyUser::NullBackend>(), {})) {
|
||||
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<std::string> NetPlayRoomInfo() {
|
||||
std::vector<std::string> AndroidMultiplayer::NetPlayRoomInfo() {
|
||||
std::vector<std::string> 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<std::string> 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<std::string> NetPlayGetBanList() {
|
||||
std::vector<std::string> AndroidMultiplayer::NetPlayGetPublicRooms() {
|
||||
std::vector<std::string> 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<std::string> AndroidMultiplayer::NetPlayGetBanList() {
|
||||
std::vector<std::string> 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
|
||||
|
|
|
@ -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 <common/common_types.h>
|
||||
#include <network/network.h>
|
||||
#include <network/announce_multiplayer_session.h>
|
||||
|
||||
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<std::string> 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<std::string> NetPlayGetBanList();
|
||||
void NetPlayUnbanUser(const std::string& username);
|
||||
class AndroidMultiplayer {
|
||||
public:
|
||||
explicit AndroidMultiplayer(Core::System& system,
|
||||
std::shared_ptr<Core::AnnounceMultiplayerSession> 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<std::string> 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<std::string> NetPlayGetBanList();
|
||||
|
||||
void NetPlayUnbanUser(const std::string &username);
|
||||
|
||||
std::vector<std::string> NetPlayGetPublicRooms();
|
||||
|
||||
private:
|
||||
Core::System& system;
|
||||
static std::unique_ptr<Network::VerifyUser::Backend> CreateVerifyBackend(bool use_validation) ;
|
||||
std::weak_ptr<Core::AnnounceMultiplayerSession> announce_multiplayer_session;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue