diff --git a/src/core/libraries/system/userservice.cpp b/src/core/libraries/system/userservice.cpp index 0dd0b6d15..dfbd4c191 100644 --- a/src/core/libraries/system/userservice.cpp +++ b/src/core/libraries/system/userservice.cpp @@ -119,7 +119,7 @@ void AddUserServiceEvent(const OrbisUserServiceEvent e) { } s32 PS4_SYSV_ABI sceUserServiceGetEvent(OrbisUserServiceEvent* event) { - LOG_TRACE(Lib_UserService, "(DUMMY) called"); + LOG_TRACE(Lib_UserService, "called"); if (!user_service_event_queue.empty()) { OrbisUserServiceEvent& temp = user_service_event_queue.front(); @@ -592,29 +592,15 @@ s32 PS4_SYSV_ABI sceUserServiceGetLoginUserIdList(OrbisUserServiceLoginUserIdLis auto& user_manager = UserManagement; - std::vector all_users = user_manager.GetValidUsers(); + auto logged_in_users = user_manager.GetLoggedInUsers(); - // Filter users with valid port assignments (1-4) - std::vector valid_users; - std::copy_if(all_users.begin(), all_users.end(), std::back_inserter(valid_users), - [](const User& user) { return user.player_index >= 1 && user.player_index <= 4; }); - - // Sort filtered users by port assignment (1-4) - std::sort(valid_users.begin(), valid_users.end(), - [](const User& a, const User& b) { return a.player_index < b.player_index; }); - - // Fill slots consecutively based on sorted valid users - int num_users = - std::min(static_cast(valid_users.size()), ORBIS_USER_SERVICE_MAX_LOGIN_USERS); - - for (int i = 0; i < num_users; i++) { - userIdList->user_id[i] = valid_users[i].user_id; - LOG_DEBUG(Lib_UserService, "Slot {}: User ID {} (port {})", i, valid_users[i].user_id, - valid_users[i].player_index); + for (int i = 0; i < ORBIS_USER_SERVICE_MAX_LOGIN_USERS; i++) { + s32 id = + logged_in_users[i] ? logged_in_users[i]->user_id : ORBIS_USER_SERVICE_USER_ID_INVALID; + userIdList->user_id[i] = id; + LOG_DEBUG(Lib_UserService, "Slot {}: User ID {} (port {})", i, id, + logged_in_users[i] ? logged_in_users[i]->player_index : -1); } - - LOG_DEBUG(Lib_UserService, "Returning {} logged-in users with valid port assignments", - num_users); return ORBIS_OK; } int PS4_SYSV_ABI sceUserServiceGetMicLevel() { diff --git a/src/core/user_manager.cpp b/src/core/user_manager.cpp index 8ab3a1182..cb5a5f343 100644 --- a/src/core/user_manager.cpp +++ b/src/core/user_manager.cpp @@ -7,6 +7,7 @@ #include "emulator_settings.h" #include "user_manager.h" #include "user_settings.h" +#include "libraries/system/userservice.h" bool UserManager::AddUser(const User& user) { for (const auto& u : m_users.user) { @@ -169,6 +170,31 @@ std::vector UserManager::GetValidUsers() const { return result; } +LoggedInUsers UserManager::GetLoggedInUsers() const { + return logged_in_users; +} + +using namespace Libraries::UserService; + +void UserManager::LoginUser(User* u, s32 player_index) { + if (!u) { + return; + } + u->logged_in = true; + // u->player_index = player_index; + AddUserServiceEvent({OrbisUserServiceEventType::Login, u->user_id}); + logged_in_users[player_index - 1] = u; +} + +void UserManager::LogoutUser(User* u) { + if (!u) { + return; + } + u->logged_in = false; + AddUserServiceEvent({OrbisUserServiceEventType::Logout, u->user_id}); + logged_in_users[u->player_index - 1] = {}; +} + bool UserManager::Save() const { return UserSettings.Save(); } \ No newline at end of file diff --git a/src/core/user_manager.h b/src/core/user_manager.h index 89832cfff..89825bcf6 100644 --- a/src/core/user_manager.h +++ b/src/core/user_manager.h @@ -9,10 +9,12 @@ #include "common/types.h" struct User { - s32 user_id; - std::string user_name; + s32 user_id = -1; + std::string user_name = ""; u32 user_color; - int player_index; // 1-4 + int player_index = 0; // 1-4 + + bool logged_in = false; }; struct Users { @@ -23,6 +25,8 @@ struct Users { NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(User, user_id, user_color, user_name, player_index) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Users, default_user_id, user, commit_hash) +using LoggedInUsers = std::array; + class UserManager { public: UserManager() = default; @@ -38,6 +42,9 @@ public: User GetDefaultUser(); void SetControllerPort(u32 user_id, int port); std::vector GetValidUsers() const; + LoggedInUsers GetLoggedInUsers() const; + void LoginUser(User* u, s32 player_index); + void LogoutUser(User* u); Users& GetUsers() { return m_users; @@ -50,4 +57,5 @@ public: private: Users m_users; + LoggedInUsers logged_in_users{}; }; diff --git a/src/input/controller.cpp b/src/input/controller.cpp index 670d66c2e..fce7a6b56 100644 --- a/src/input/controller.cpp +++ b/src/input/controller.cpp @@ -223,6 +223,7 @@ void GameControllers::TryOpenSDLControllers(GameControllers& controllers) { using namespace Libraries::UserService; int controller_count; SDL_JoystickID* new_joysticks = SDL_GetGamepads(&controller_count); + LOG_INFO(Input, "{} controllers are currently connected", controller_count); std::unordered_set assigned_ids; std::array slot_taken{false, false, false, false}; @@ -252,7 +253,8 @@ void GameControllers::TryOpenSDLControllers(GameControllers& controllers) { } } if (!still_connected) { - AddUserServiceEvent({OrbisUserServiceEventType::Logout, controllers[i]->user_id}); + auto u = UserManagement.GetUserByID(controllers[i]->user_id); + UserManagement.LogoutUser(u); SDL_CloseGamepad(pad); controllers[i]->m_sdl_gamepad = nullptr; controllers[i]->user_id = -1; @@ -269,13 +271,15 @@ void GameControllers::TryOpenSDLControllers(GameControllers& controllers) { continue; SDL_Gamepad* pad = SDL_OpenGamepad(id); - if (!pad) + if (!pad) { continue; + } for (int i = 0; i < 4; i++) { if (!slot_taken[i]) { auto u = UserManagement.GetUserByPlayerIndex(i + 1); if (!u) { + LOG_INFO(Input, "User {} not found", i + 1); continue; // for now, if you don't specify who Player N is in the config, // Player N won't be registered at all } @@ -283,10 +287,9 @@ void GameControllers::TryOpenSDLControllers(GameControllers& controllers) { c->m_sdl_gamepad = pad; LOG_INFO(Input, "Gamepad registered for slot {}! Handle: {}", i, SDL_GetGamepadID(pad)); - c->user_id = u ? u->user_id : ORBIS_USER_SERVICE_USER_ID_INVALID; + c->user_id = u->user_id; slot_taken[i] = true; - c->player_index = i; - AddUserServiceEvent({OrbisUserServiceEventType::Login, c->user_id}); + UserManagement.LoginUser(u, i + 1); if (EmulatorSettings.IsMotionControlsEnabled()) { if (SDL_SetGamepadSensorEnabled(c->m_sdl_gamepad, SDL_SENSOR_GYRO, true)) { c->gyro_poll_rate = @@ -314,7 +317,7 @@ void GameControllers::TryOpenSDLControllers(GameControllers& controllers) { if (controller_count == 0) { auto u = UserManagement.GetUserByPlayerIndex(1); controllers[0]->user_id = u->user_id; - AddUserServiceEvent({OrbisUserServiceEventType::Login, controllers[0]->user_id}); + UserManagement.LoginUser(u, 1); } } SDL_free(new_joysticks); diff --git a/src/sdl_window.cpp b/src/sdl_window.cpp index 7583eabaf..853447e30 100644 --- a/src/sdl_window.cpp +++ b/src/sdl_window.cpp @@ -195,7 +195,6 @@ void WindowSDL::WaitEvent() { break; case SDL_EVENT_GAMEPAD_ADDED: case SDL_EVENT_GAMEPAD_REMOVED: - // todo handle userserviceevents here Input::GameControllers::TryOpenSDLControllers(controllers); break; case SDL_EVENT_GAMEPAD_BUTTON_DOWN: @@ -260,9 +259,7 @@ void WindowSDL::WaitEvent() { break; } controllers[i]->user_id = u->user_id; - Libraries::UserService::AddUserServiceEvent( - {Libraries::UserService::OrbisUserServiceEventType::Login, - controllers[i]->user_id}); + UserManagement.LoginUser(u, i + 1); break; } } @@ -271,9 +268,7 @@ void WindowSDL::WaitEvent() { LOG_INFO(Input, "Remove user"); for (int i = 3; i >= 0; i--) { if (controllers[i]->user_id != -1) { - Libraries::UserService::AddUserServiceEvent( - {Libraries::UserService::OrbisUserServiceEventType::Logout, - (s32)controllers[i]->user_id}); + UserManagement.LogoutUser(UserManagement.GetUserByID(controllers[i]->user_id)); controllers[i]->user_id = -1; break; }