forked from eden-emu/eden
[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 <swurl@swurl.xyz> Co-authored-by: Aleksandr Popovich <alekpopo@pm.me> Co-authored-by: Aleksandr Popovich <alekpopo@proton.me> Reviewed-on: eden-emu/eden#221 Co-authored-by: crueter <swurl@swurl.xyz> Co-committed-by: crueter <swurl@swurl.xyz>
This commit is contained in:
parent
2fe728766e
commit
94c66f98bf
34 changed files with 1985 additions and 327 deletions
|
@ -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 <thread>
|
||||
#include <chrono>
|
||||
|
||||
namespace IDCache = Common::Android;
|
||||
|
||||
AndroidMultiplayer::AndroidMultiplayer(Core::System& system_,
|
||||
AndroidMultiplayer::AndroidMultiplayer(Core::System &system_,
|
||||
std::shared_ptr<Core::AnnounceMultiplayerSession> 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<int>(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<int>(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<int>(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<int>(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<u16>(port);
|
||||
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, std::make_unique<Network::VerifyUser::NullBackend>(), {})) {
|
||||
static_cast<u32>(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<u16>(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<u16>(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<u16>(port), 0, Network::NoPreferredIP, password, "");
|
||||
member->Join(username, ipaddress.c_str(), static_cast<u16>(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<std::string> 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<std::string> 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<Network::VerifyUser::Backend> AndroidMultiplayer::CreateVerifyBackend(bool use_validation) {
|
||||
std::unique_ptr<Network::VerifyUser::Backend> verify_backend;
|
||||
if (use_validation) {
|
||||
//#ifdef ENABLE_WEB_SERVICE
|
||||
verify_backend =
|
||||
std::make_unique<WebService::VerifyUserJWT>(Settings::values.web_api_url.GetValue());
|
||||
//#else
|
||||
// verify_backend = std::make_unique<Network::VerifyUser::NullBackend>();
|
||||
//#endif
|
||||
} else {
|
||||
verify_backend = std::make_unique<Network::VerifyUser::NullBackend>();
|
||||
}
|
||||
return verify_backend;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue