From 9c7230e79faf26b903c9d632bdbef0f3929de740 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Fri, 2 Apr 2021 00:54:32 +0200 Subject: [PATCH] cli: set user-id per command line --- rpcs3/Emu/System.cpp | 30 +++++-- rpcs3/Emu/System.h | 4 +- rpcs3/headless_application.cpp | 4 +- rpcs3/main.cpp | 21 ++++- rpcs3/main_application.cpp | 17 +--- rpcs3/main_application.h | 8 +- rpcs3/rpcs3qt/gui_application.cpp | 14 +-- rpcs3/rpcs3qt/user_account.cpp | 44 ++++++++-- rpcs3/rpcs3qt/user_account.h | 19 ++-- rpcs3/rpcs3qt/user_manager_dialog.cpp | 121 ++++++++++---------------- rpcs3/rpcs3qt/user_manager_dialog.h | 2 +- 11 files changed, 165 insertions(+), 119 deletions(-) diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index a5a8e413f3..1fab89517f 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -503,24 +503,31 @@ namespace }; } -bool Emulator::SetUsr(const std::string& user) +u32 Emulator::CheckUsr(const std::string& user) { - if (user.empty()) + u32 id = 0; + + if (user.size() == 8) { - return false; + std::from_chars(&user.front(), &user.back() + 1, id); } - u32 id = 0; - std::from_chars(&user.front(), &user.back() + 1, id); + return id; +} + +void Emulator::SetUsr(const std::string& user) +{ + sys_log.notice("Setting user ID '%s'", user); + + const u32 id = CheckUsr(user); if (id == 0) { - return false; + fmt::throw_exception("Failed to set user ID '%s'", user); } m_usrid = id; m_usr = user; - return true; } std::string Emulator::GetBackgroundPicturePath() const @@ -2015,7 +2022,14 @@ bool Emulator::Quit(bool force_quit) { Emu.CleanUp(); }; - return GetCallbacks().try_to_quit(force_quit, on_exit); + + if (GetCallbacks().try_to_quit) + { + return GetCallbacks().try_to_quit(force_quit, on_exit); + } + + on_exit(); + return true; } void Emulator::CleanUp() diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index a5a4ebfef1..1103a599c5 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -196,7 +196,9 @@ public: return m_usrid; } - bool SetUsr(const std::string& user); + static u32 CheckUsr(const std::string& user); + + void SetUsr(const std::string& user); std::string GetBackgroundPicturePath() const; diff --git a/rpcs3/headless_application.cpp b/rpcs3/headless_application.cpp index a37f027170..54297366d5 100644 --- a/rpcs3/headless_application.cpp +++ b/rpcs3/headless_application.cpp @@ -16,7 +16,7 @@ headless_application::headless_application(int& argc, char** argv) : QCoreApplic bool headless_application::Init() { // Force init the emulator - InitializeEmulator("00000001", true, false); // TODO: get user from cli args if possible + InitializeEmulator(m_active_user.empty() ? "00000001" : m_active_user, false); // Create callbacks from the emulator, which reference the handlers. InitializeCallbacks(); @@ -24,7 +24,7 @@ bool headless_application::Init() // Create connects to propagate events throughout Gui. InitializeConnects(); - // As per QT recommendations to avoid conflicts for POSIX functions + // As per Qt recommendations to avoid conflicts for POSIX functions std::setlocale(LC_NUMERIC, "C"); return true; diff --git a/rpcs3/main.cpp b/rpcs3/main.cpp index 12c4e53fe3..5c8617087f 100644 --- a/rpcs3/main.cpp +++ b/rpcs3/main.cpp @@ -208,6 +208,7 @@ constexpr auto arg_config = "config"; constexpr auto arg_q_debug = "qDebug"; constexpr auto arg_error = "error"; constexpr auto arg_updating = "updating"; +constexpr auto arg_user_id = "user-id"; constexpr auto arg_installfw = "installfw"; constexpr auto arg_installpkg = "installpkg"; constexpr auto arg_commit_db = "get-commit-db"; @@ -521,6 +522,8 @@ int main(int argc, char** argv) parser.addOption(installfw_option); const QCommandLineOption installpkg_option(arg_installpkg, "Forces the emulator to install this pkg file.", "path", ""); parser.addOption(installpkg_option); + const QCommandLineOption user_id_option(arg_user_id, "Start RPCS3 as this user.", "user id", ""); + parser.addOption(user_id_option); parser.addOption(QCommandLineOption(arg_q_debug, "Log qDebug to RPCS3.log.")); parser.addOption(QCommandLineOption(arg_error, "For internal usage.")); parser.addOption(QCommandLineOption(arg_updating, "For internal usage.")); @@ -716,6 +719,19 @@ int main(int argc, char** argv) return 0; } + std::string active_user; + + if (parser.isSet(arg_user_id)) + { + active_user = parser.value(arg_user_id).toStdString(); + + if (Emulator::CheckUsr(active_user) == 0) + { + report_fatal_error(fmt::format("Failed to set user ID '%s'.\nThe user ID must consist of 8 digits and cannot be 00000000.", active_user)); + return 1; + } + } + s_no_gui = parser.isSet(arg_no_gui); if (auto gui_app = qobject_cast(app.data())) @@ -727,6 +743,7 @@ int main(int argc, char** argv) gui_app->SetShowGui(!s_no_gui); gui_app->SetUseCliStyle(use_cli_style); gui_app->SetWithCliBoot(parser.isSet(arg_installfw) || parser.isSet(arg_installpkg) || !parser.positionalArguments().isEmpty()); + gui_app->SetActiveUser(active_user); if (!gui_app->Init()) { @@ -738,6 +755,8 @@ int main(int argc, char** argv) { s_headless = true; + headless_app->SetActiveUser(active_user); + if (!headless_app->Init()) { Emu.Quit(true); @@ -774,7 +793,7 @@ int main(int argc, char** argv) if (!fs::is_file(config_override_path)) { report_fatal_error(fmt::format("No config file found: %s", config_override_path)); - return 0; + return 1; } Emu.SetConfigOverride(config_override_path); diff --git a/rpcs3/main_application.cpp b/rpcs3/main_application.cpp index 35cf90a4a3..8b46e610a6 100644 --- a/rpcs3/main_application.cpp +++ b/rpcs3/main_application.cpp @@ -33,21 +33,12 @@ LOG_CHANNEL(sys_log, "SYS"); -/** Emu.Init() wrapper for user manager */ -bool main_application::InitializeEmulator(const std::string& user, bool force_init, bool show_gui) +/** Emu.Init() wrapper for user management */ +void main_application::InitializeEmulator(const std::string& user, bool show_gui) { Emu.SetHasGui(show_gui); - - // try to set a new user - const bool user_was_set = Emu.SetUsr(user); - - // only init the emulation if forced or a user was set - if (user_was_set || force_init) - { - Emu.Init(); - } - - return user_was_set; + Emu.SetUsr(user); + Emu.Init(); } /** RPCS3 emulator has functions it desires to call from the GUI at times. Initialize them in here. */ diff --git a/rpcs3/main_application.h b/rpcs3/main_application.h index 2ac1b64334..b207976bcb 100644 --- a/rpcs3/main_application.h +++ b/rpcs3/main_application.h @@ -10,12 +10,18 @@ class main_application public: virtual bool Init() = 0; - static bool InitializeEmulator(const std::string& user, bool force_init, bool show_gui); + static void InitializeEmulator(const std::string& user, bool show_gui); + + void SetActiveUser(std::string user) + { + m_active_user = user; + } protected: virtual QThread* get_thread() = 0; EmuCallbacks CreateCallbacks(); + std::string m_active_user; QWindow* m_game_window = nullptr; // (Currently) only needed so that pad handlers have a valid target for event filtering. }; diff --git a/rpcs3/rpcs3qt/gui_application.cpp b/rpcs3/rpcs3qt/gui_application.cpp index 748dda9c73..d7c193ad00 100644 --- a/rpcs3/rpcs3qt/gui_application.cpp +++ b/rpcs3/rpcs3qt/gui_application.cpp @@ -63,14 +63,18 @@ bool gui_application::Init() return false; } - // Get deprecated active user (before August 2nd 2020) - QString active_user = m_gui_settings->GetValue(gui::um_active_user).toString(); + // The user might be set by cli arg. If not, set another user. + if (m_active_user.empty()) + { + // Get deprecated active user (before August 2nd 2020) + const QString active_user = m_gui_settings->GetValue(gui::um_active_user).toString(); - // Get active user with deprecated active user as fallback - active_user = m_persistent_settings->GetCurrentUser(active_user.isEmpty() ? "00000001" : active_user); + // Get active user with deprecated active user as fallback + m_active_user = m_persistent_settings->GetCurrentUser(active_user.isEmpty() ? "00000001" : active_user).toStdString(); + } // Force init the emulator - InitializeEmulator(active_user.toStdString(), true, m_show_gui); + InitializeEmulator(m_active_user, m_show_gui); // Create the main window if (m_show_gui) diff --git a/rpcs3/rpcs3qt/user_account.cpp b/rpcs3/rpcs3qt/user_account.cpp index 158ad92717..7f4c5f1464 100644 --- a/rpcs3/rpcs3qt/user_account.cpp +++ b/rpcs3/rpcs3qt/user_account.cpp @@ -7,7 +7,7 @@ LOG_CHANNEL(gui_log, "GUI"); -UserAccount::UserAccount(const std::string& user_id) +user_account::user_account(const std::string& user_id) { // Setting userId. m_user_id = user_id; @@ -16,8 +16,7 @@ UserAccount::UserAccount(const std::string& user_id) m_user_dir = Emulator::GetHddDir() + "home/" + m_user_id + "/"; // Setting userName. - fs::file file; - if (file.open(m_user_dir + "localusername", fs::read)) + if (fs::file file; file.open(m_user_dir + "localusername", fs::read)) { m_username = file.to_string(); file.close(); @@ -25,15 +24,48 @@ UserAccount::UserAccount(const std::string& user_id) if (m_username.length() > 16) // max of 16 chars on real PS3 { m_username = m_username.substr(0, 16); - gui_log.warning("UserAccount: localusername of userId=%s was too long, cropped to: %s", m_user_id, m_username); + gui_log.warning("user_account: localusername of userId=%s was too long, cropped to: %s", m_user_id, m_username); } } else { - gui_log.error("UserAccount: localusername file read error (userId=%s, userDir=%s).", m_user_id, m_user_dir); + gui_log.error("user_account: localusername file read error (userId=%s, userDir=%s).", m_user_id, m_user_dir); } } -UserAccount::~UserAccount() +user_account::~user_account() { } + +std::map user_account::GetUserAccounts(const std::string& base_dir) +{ + std::map user_list; + + // I believe this gets the folder list sorted alphabetically by default, + // but I can't find proof of this always being true. + for (const auto& user_folder : fs::dir(base_dir)) + { + if (!user_folder.is_directory) + { + continue; + } + + // Is the folder name exactly 8 all-numerical characters long? + const u32 key = Emulator::CheckUsr(user_folder.name); + + if (key == 0) + { + continue; + } + + // Does the localusername file exist? + if (!fs::is_file(base_dir + "/" + user_folder.name + "/localusername")) + { + continue; + } + + user_list.emplace(key, user_account(user_folder.name)); + } + + return user_list; +} diff --git a/rpcs3/rpcs3qt/user_account.h b/rpcs3/rpcs3qt/user_account.h index fe58b43f49..fc394f1d35 100644 --- a/rpcs3/rpcs3qt/user_account.h +++ b/rpcs3/rpcs3qt/user_account.h @@ -1,20 +1,25 @@ #pragma once +#include "util/types.hpp" + +#include #include // Do not confuse this with the "user" in Emu/System.h. // That user is read from config.yml, and it only represents the currently "logged in" user. -// The UserAccount class will represent all users in the home directory for the User Manager dialog. +// The user_account class will represent all users in the home directory for the User Manager dialog. // Selecting a user account in this dialog and saving writes it to config.yml. -class UserAccount +class user_account { public: - explicit UserAccount(const std::string& user_id = "00000001"); + explicit user_account(const std::string& user_id = "00000001"); - std::string GetUserId() { return m_user_id; } - std::string GetUserDir() { return m_user_dir; } - std::string GetUsername() { return m_username; } - ~UserAccount(); + std::string GetUserId() const { return m_user_id; } + std::string GetUserDir() const { return m_user_dir; } + std::string GetUsername() const { return m_username; } + ~user_account(); + + static std::map GetUserAccounts(const std::string& base_dir); private: std::string m_user_id; diff --git a/rpcs3/rpcs3qt/user_manager_dialog.cpp b/rpcs3/rpcs3qt/user_manager_dialog.cpp index 1ffbe3eb8d..7ee8b7f4fc 100644 --- a/rpcs3/rpcs3qt/user_manager_dialog.cpp +++ b/rpcs3/rpcs3qt/user_manager_dialog.cpp @@ -28,43 +28,6 @@ constexpr auto qstr = QString::fromStdString; LOG_CHANNEL(gui_log, "GUI"); -namespace -{ - std::map GetUserAccounts(const std::string& base_dir) - { - std::map user_list; - - // I believe this gets the folder list sorted alphabetically by default, - // but I can't find proof of this always being true. - for (const auto& user_folder : fs::dir(base_dir)) - { - if (!user_folder.is_directory) - { - continue; - } - - // Is the folder name exactly 8 all-numerical characters long? - // We use strtoul to find any non-numeric characters in folder name. - char* non_numeric_char; - const u32 key = static_cast(std::strtoul(user_folder.name.c_str(), &non_numeric_char, 10)); - - if (key == 0 || user_folder.name.length() != 8 || *non_numeric_char != '\0') - { - continue; - } - - // Does the localusername file exist? - if (!fs::is_file(base_dir + "/" + user_folder.name + "/localusername")) - { - continue; - } - - user_list.emplace(key, UserAccount(user_folder.name)); - } - return user_list; - } -} - user_manager_dialog::user_manager_dialog(std::shared_ptr gui_settings, std::shared_ptr persistent_settings, QWidget* parent) : QDialog(parent) , m_gui_settings(gui_settings) @@ -94,16 +57,16 @@ void user_manager_dialog::Init() m_table->horizontalHeader()->setDefaultSectionSize(150); m_table->installEventFilter(this); - QPushButton* push_remove_user = new QPushButton(tr("Delete User"), this); + QPushButton* push_remove_user = new QPushButton(tr("&Delete User"), this); push_remove_user->setAutoDefault(false); - QPushButton* push_create_user = new QPushButton(tr("Create User"), this); + QPushButton* push_create_user = new QPushButton(tr("&Create User"), this); push_create_user->setAutoDefault(false); - QPushButton* push_login_user = new QPushButton(tr("Log In User"), this); + QPushButton* push_login_user = new QPushButton(tr("&Log In User"), this); push_login_user->setAutoDefault(false); - QPushButton* push_rename_user = new QPushButton(tr("Rename User"), this); + QPushButton* push_rename_user = new QPushButton(tr("&Rename User"), this); push_rename_user->setAutoDefault(false); QPushButton* push_close = new QPushButton(tr("&Close"), this); @@ -139,12 +102,18 @@ void user_manager_dialog::Init() } } + // Get the real active user (might differ, set by cli) + if (m_active_user != Emu.GetUsr()) + { + m_active_user = Emu.GetUsr(); + } + UpdateTable(); restoreGeometry(m_gui_settings->GetValue(gui::um_geometry).toByteArray()); // Use this in multiple connects to protect the current user from deletion/rename. - auto enableButtons = [=, this]() + const auto enable_buttons = [=, this]() { const u32 key = GetUserKey(); if (key == 0) @@ -162,7 +131,7 @@ void user_manager_dialog::Init() push_remove_user->setEnabled(enable); }; - enableButtons(); + enable_buttons(); // Connects and events connect(push_close, &QAbstractButton::clicked, this, &user_manager_dialog::close); @@ -170,11 +139,11 @@ void user_manager_dialog::Init() connect(push_rename_user, &QAbstractButton::clicked, this, &user_manager_dialog::OnUserRename); connect(push_create_user, &QAbstractButton::clicked, this, &user_manager_dialog::OnUserCreate); connect(push_login_user, &QAbstractButton::clicked, this, &user_manager_dialog::OnUserLogin); - connect(this, &user_manager_dialog::OnUserLoginSuccess, this, enableButtons); + connect(this, &user_manager_dialog::OnUserLoginSuccess, this, enable_buttons); connect(m_table->horizontalHeader(), &QHeaderView::sectionClicked, this, &user_manager_dialog::OnSort); connect(m_table, &QTableWidget::customContextMenuRequested, this, &user_manager_dialog::ShowContextMenu); connect(m_table, &QTableWidget::itemDoubleClicked, this, &user_manager_dialog::OnUserLogin); - connect(m_table, &QTableWidget::itemSelectionChanged, this, enableButtons); + connect(m_table, &QTableWidget::itemSelectionChanged, this, enable_buttons); } void user_manager_dialog::UpdateTable(bool mark_only) @@ -185,7 +154,7 @@ void user_manager_dialog::UpdateTable(bool mark_only) if (mark_only) { - QString active_user = qstr(m_active_user); + const QString active_user = qstr(m_active_user); for (int i = 0; i < m_table->rowCount(); i++) { @@ -209,26 +178,26 @@ void user_manager_dialog::UpdateTable(bool mark_only) // Get the user folders in the home directory and the currently logged in user. m_user_list.clear(); - m_user_list = GetUserAccounts(Emulator::GetHddDir() + "home"); + m_user_list = user_account::GetUserAccounts(Emulator::GetHddDir() + "home"); // Clear and then repopulate the table with the list gathered above. m_table->setRowCount(static_cast(m_user_list.size())); int row = 0; - for (auto& user : m_user_list) + for (auto& [id, account] : m_user_list) { - QTableWidgetItem* user_id_item = new QTableWidgetItem(qstr(user.second.GetUserId())); - user_id_item->setData(Qt::UserRole, user.first); // For sorting to work properly + QTableWidgetItem* user_id_item = new QTableWidgetItem(qstr(account.GetUserId())); + user_id_item->setData(Qt::UserRole, id); // For sorting to work properly user_id_item->setFlags(user_id_item->flags() & ~Qt::ItemIsEditable); m_table->setItem(row, 0, user_id_item); - QTableWidgetItem* username_item = new QTableWidgetItem(qstr(user.second.GetUsername())); - username_item->setData(Qt::UserRole, user.first); // For sorting to work properly + QTableWidgetItem* username_item = new QTableWidgetItem(qstr(account.GetUsername())); + username_item->setData(Qt::UserRole, id); // For sorting to work properly username_item->setFlags(username_item->flags() & ~Qt::ItemIsEditable); m_table->setItem(row, 1, username_item); // Compare current config value with the one in this user (only 8 digits in userId) - if (m_active_user.starts_with(user.second.GetUserId())) + if (m_active_user.starts_with(account.GetUserId())) { user_id_item->setFont(bold_font); username_item->setFont(bold_font); @@ -240,12 +209,12 @@ void user_manager_dialog::UpdateTable(bool mark_only) m_table->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); m_table->verticalHeader()->resizeSections(QHeaderView::ResizeToContents); - QSize table_size = QSize( + const QSize table_size( m_table->verticalHeader()->width() + m_table->horizontalHeader()->length() + m_table->frameWidth() * 2, m_table->horizontalHeader()->height() + m_table->verticalHeader()->length() + m_table->frameWidth() * 2); - QSize preferred_size = minimumSize().expandedTo(sizeHint() - m_table->sizeHint() + table_size).expandedTo(size()); - QSize max_size = QSize(preferred_size.width(), static_cast(QGuiApplication::primaryScreen()->size().height() * 0.6)); + const QSize preferred_size = minimumSize().expandedTo(sizeHint() - m_table->sizeHint() + table_size).expandedTo(size()); + const QSize max_size(preferred_size.width(), static_cast(QGuiApplication::primaryScreen()->size().height() * 0.6)); resize(preferred_size.boundedTo(max_size)); } @@ -253,7 +222,7 @@ void user_manager_dialog::UpdateTable(bool mark_only) // Remove a user folder, needs to be confirmed. void user_manager_dialog::OnUserRemove() { - u32 key = GetUserKey(); + const u32 key = GetUserKey(); if (key == 0) { return; @@ -274,6 +243,8 @@ void user_manager_dialog::OnUserRemove() void user_manager_dialog::GenerateUser(const std::string& user_id, const std::string& username) { + ensure(Emulator::CheckUsr(user_id) > 0); + // Create user folders and such. const std::string home_dir = Emulator::GetHddDir() + "home/"; const std::string user_dir = home_dir + user_id; @@ -298,7 +269,7 @@ bool user_manager_dialog::ValidateUsername(const QString& text_to_validate) void user_manager_dialog::OnUserRename() { - u32 key = GetUserKey(); + const u32 key = GetUserKey(); if (key == 0) { return; @@ -318,7 +289,7 @@ void user_manager_dialog::OnUserRename() { dialog->resize(200, 100); - QString text_to_validate = dialog->textValue(); + const QString text_to_validate = dialog->textValue(); if (!ValidateUsername(text_to_validate)) { QMessageBox::warning(this, tr("Error"), tr("Name must be between 3 and 16 characters and only consist of letters, numbers, underscores, and hyphens.")); @@ -359,7 +330,14 @@ void user_manager_dialog::OnUserCreate() } } + if (smallest >= 100000000) // Only 8 digits allowed + { + QMessageBox::warning(this, tr("Error"), tr("Cannot add more users.")); + return; + } + const std::string next_user_id = fmt::format("%08d", smallest); + ensure(Emulator::CheckUsr(next_user_id) > 0); QInputDialog* dialog = new QInputDialog(this); dialog->setWindowTitle(tr("New User")); @@ -397,11 +375,7 @@ void user_manager_dialog::OnUserLogin() const u32 key = GetUserKey(); const std::string new_user = m_user_list[key].GetUserId(); - if (!main_application::InitializeEmulator(new_user, false, Emu.HasGui())) - { - gui_log.fatal("Failed to login user! username=%s key=%d", new_user, key); - return; - } + main_application::InitializeEmulator(new_user, Emu.HasGui()); m_active_user = new_user; m_persistent_settings->SetValue(gui::persistent::active_user, qstr(m_active_user)); @@ -429,7 +403,7 @@ void user_manager_dialog::OnSort(int logicalIndex) void user_manager_dialog::ShowContextMenu(const QPoint &pos) { - u32 key = GetUserKey(); + const u32 key = GetUserKey(); if (key == 0) { return; @@ -448,8 +422,7 @@ void user_manager_dialog::ShowContextMenu(const QPoint &pos) QAction* show_dir_act = menu->addAction(tr("&Open User Directory")); // Only enable actions if selected user is not logged in user. - std::string idx_user = m_user_list[key].GetUserId(); - bool enable = idx_user != m_active_user; + const bool enable = m_user_list[key].GetUserId() != m_active_user; remove_act->setEnabled(enable); rename_act->setEnabled(enable); @@ -458,14 +431,14 @@ void user_manager_dialog::ShowContextMenu(const QPoint &pos) connect(remove_act, &QAction::triggered, this, &user_manager_dialog::OnUserRemove); connect(rename_act, &QAction::triggered, this, &user_manager_dialog::OnUserRename); connect(login_act, &QAction::triggered, this, &user_manager_dialog::OnUserLogin); - connect(show_dir_act, &QAction::triggered, [=, this]() + connect(show_dir_act, &QAction::triggered, this, [this, key]() { - QString path = qstr(m_user_list[key].GetUserDir()); + const QString path = qstr(m_user_list[key].GetUserDir()); QDesktopServices::openUrl(QUrl::fromLocalFile(path)); }); - connect(user_id_act, &QAction::triggered, this, [=, this] {OnSort(0); }); - connect(username_act, &QAction::triggered, this, [=, this] {OnSort(1); }); + connect(user_id_act, &QAction::triggered, this, [this] {OnSort(0); }); + connect(username_act, &QAction::triggered, this, [this] {OnSort(1); }); menu->exec(m_table->viewport()->mapToGlobal(pos)); } @@ -473,20 +446,20 @@ void user_manager_dialog::ShowContextMenu(const QPoint &pos) // Returns the current user's key > 0. if no user is selected, return 0 u32 user_manager_dialog::GetUserKey() { - int idx = m_table->currentRow(); + const int idx = m_table->currentRow(); if (idx < 0) { return 0; } - QTableWidgetItem* item = m_table->item(idx, 0); + const QTableWidgetItem* item = m_table->item(idx, 0); if (!item) { return 0; } const u32 idx_real = item->data(Qt::UserRole).toUInt(); - if (m_user_list.find(idx_real) == m_user_list.end()) + if (!m_user_list.contains(idx_real)) { return 0; } diff --git a/rpcs3/rpcs3qt/user_manager_dialog.h b/rpcs3/rpcs3qt/user_manager_dialog.h index b5cc60961d..90c3cfffb4 100644 --- a/rpcs3/rpcs3qt/user_manager_dialog.h +++ b/rpcs3/rpcs3qt/user_manager_dialog.h @@ -40,7 +40,7 @@ private: QTableWidget* m_table; std::string m_active_user; - std::map m_user_list; + std::map m_user_list; std::shared_ptr m_gui_settings; std::shared_ptr m_persistent_settings;