mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-22 21:02:39 +02:00
psel: Various improvements, including proper version handling. Updated names. Renamed/added modes, with sysver docs. Don't use ptrs for input AccountUids. Added pselShowUserCreatorForStarter and pselShowNintendoAccountNnidLinker. Directly return the Result from PselUiReturnArg. Removed the output user param from pselShowUserCreator.
This commit is contained in:
parent
5182b57a1d
commit
4078de1eff
@ -1,71 +1,79 @@
|
|||||||
/**
|
/**
|
||||||
* @file psel.h
|
* @file psel.h
|
||||||
* @brief Wrapper for using playerSelect (user selection applet).
|
* @brief Wrapper for using playerSelect (user selection applet).
|
||||||
* @author XorTroll
|
* @author XorTroll, yellows8
|
||||||
* @copyright libnx Authors
|
* @copyright libnx Authors
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
#include "../services/applet.h"
|
|
||||||
#include "../services/acc.h"
|
#include "../services/acc.h"
|
||||||
|
|
||||||
/// playerSelect UI modes.
|
/// playerSelect UI modes.
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PselUiMode_SelectUser = 0, ///< Simple user selection (new users cannot be created).
|
PselUiMode_UserSelector = 0, ///< Simple user selection (new users cannot be created).
|
||||||
PselUiMode_UserCreation = 1, ///< Only user creation (the user is later returned).
|
PselUiMode_UserCreator = 1, ///< User creation.
|
||||||
PselUiMode_EnsureNsaAvailable = 2, ///< EnsureNsaAvailable
|
PselUiMode_EnsureNetworkServiceAccountAvailable = 2, ///< EnsureNetworkServiceAccountAvailable
|
||||||
PselUiMode_IconEditor = 3, ///< IconEditor
|
PselUiMode_UserIconEditor = 3, ///< UserIconEditor
|
||||||
PselUiMode_NicknameEditor = 4, ///< NicknameEditor
|
PselUiMode_UserNicknameEditor = 4, ///< UserNicknameEditor
|
||||||
PselUiMode_ForStarter = 5, ///< Mode "starter" uses to register the console's first user on the initial setup
|
PselUiMode_UserCreatorForStarter = 5, ///< Mode "starter" uses to register the console's first user on the initial setup.
|
||||||
PselUiMode_NetworkServiceAccountRegistration = 8, ///< NetworkServiceAccountRegistration
|
// TODO: Add mode 6.
|
||||||
PselUiMode_NintendoAccountNnidLinker = 9, ///< NintendoAccountNnidLinker
|
PselUiMode_IntroduceExternalNetworkServiceAccount = 7, ///< IntroduceExternalNetworkServiceAccount
|
||||||
PselUiMode_LicenseRequirementsForNetworkService = 10, ///< LicenseRequirementsForNetworkService
|
PselUiMode_IntroduceExternalNetworkServiceAccountForRegistration = 8, ///< [6.0.0+] IntroduceExternalNetworkServiceAccountForRegistration
|
||||||
PselUiMode_NaLoginTest = 12, ///< NaLoginTest
|
PselUiMode_NintendoAccountNnidLinker = 9, ///< [6.0.0+] NintendoAccountNnidLinker
|
||||||
|
PselUiMode_LicenseRequirementsForNetworkService = 10, ///< [6.0.0+] LicenseRequirementsForNetworkService
|
||||||
|
PselUiMode_LicenseRequirementsForNetworkServiceWithUserContextImpl = 11, ///< [7.0.0+] LicenseRequirementsForNetworkServiceWithUserContextImpl
|
||||||
|
PselUiMode_UserCreatorForImmediateNaLoginTest = 12, ///< [7.0.0+] UserCreatorForImmediateNaLoginTest
|
||||||
} PselUiMode;
|
} PselUiMode;
|
||||||
|
|
||||||
/// UI settings for playerSelect.
|
/// Base UI settings for playerSelect.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 mode; ///< UI mode, see \ref PselUiMode.
|
u32 mode; ///< \ref PselUiMode
|
||||||
u32 dialogType; ///< Dialog type
|
u32 dialog_type; ///< Dialog type.
|
||||||
AccountUid invalidUserList[ACC_USER_LIST_SIZE]; ///< List of \ref AccountUid user IDs which will be disabled.
|
AccountUid user_list[ACC_USER_LIST_SIZE]; ///< List of \ref AccountUid.
|
||||||
u8 unk_x88[0x8]; ///< Unknown.
|
u8 unk_x88[0x8]; ///< Unknown.
|
||||||
u8 networkServiceRequired; ///< Whether the user needs to be linked to a Nintendo account.
|
u8 network_service_required; ///< Whether the user needs to be linked to a Nintendo account.
|
||||||
u8 unk_x91[0x2]; ///< Unknown.
|
u8 unk_x91[0x2]; ///< Unknown.
|
||||||
u8 allowUserCreation; ///< (With ::PselUiMode_SelectUser) enables the option to create a new user.
|
u8 allow_user_creation; ///< (With ::PselUiMode_SelectUser) enables the option to create a new user.
|
||||||
u8 skipEnabled; ///< Enables the option to skip user selection (a new button is shown)
|
u8 skip_enabled; ///< Enables the option to skip user selection (a new button is shown)
|
||||||
u8 unk_x95[0xb]; ///< Unknown.
|
u8 unk_x95[0x3]; ///< Unknown.
|
||||||
|
} PselUiSettingsV1;
|
||||||
|
|
||||||
|
/// UI settings for versions starting with 0x10000.
|
||||||
|
typedef struct {
|
||||||
|
PselUiSettingsV1 settings; ///< \ref PselUiSettingsV1
|
||||||
|
u8 unk_x98[0x8]; ///< Unknown.
|
||||||
} PselUiSettings;
|
} PselUiSettings;
|
||||||
|
|
||||||
/// Result data sent after execution.
|
/// Return data sent after execution.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 result; ///< Result code.
|
Result res; ///< Result.
|
||||||
AccountUid userId; ///< Selected \ref AccountUid.
|
AccountUid user_id; ///< Selected \ref AccountUid.
|
||||||
} PselResult;
|
} PselUiReturnArg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates a new UI config for playerSelect applet with the specified mode.
|
* @brief Creates a new UI config for the playerSelect applet with the specified mode.
|
||||||
* @param ui PseluiSettings struct.
|
* @param ui PseluiSettings struct.
|
||||||
* @param mode playerSelect UI mode.
|
* @param mode playerSelect UI mode.
|
||||||
*/
|
*/
|
||||||
Result pselUiCreate(PselUiSettings *ui, PselUiMode mode);
|
Result pselUiCreate(PselUiSettings *ui, PselUiMode mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Adds a user to the user list of the applet.
|
* @brief Adds an user to the user list of the applet.
|
||||||
* @param ui PselUiSettings struct.
|
* @param ui PselUiSettings struct.
|
||||||
* @param user_id user ID.
|
* @param[in] user_id user ID.
|
||||||
* @note The users will be treated as invalid users for user selection mode, and as the input user for other modes.
|
* @note The users will be treated as invalid users for user selection mode, and as the input user for other modes.
|
||||||
*/
|
*/
|
||||||
void pselUiAddUser(PselUiSettings *ui, AccountUid *user_id);
|
void pselUiAddUser(PselUiSettings *ui, AccountUid user_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets whether users can be created in the applet
|
* @brief Sets whether users can be created in the applet.
|
||||||
* @param ui PselUiSettings struct.
|
* @param ui PselUiSettings struct.
|
||||||
* @param flag Flag value.
|
* @param flag Flag value.
|
||||||
* @note Only used for ::PselUiMode_SelectUser
|
* @note Only used for ::PselUiMode_SelectUser
|
||||||
*/
|
*/
|
||||||
NX_CONSTEXPR void pselUiSetAllowUserCreation(PselUiSettings *ui, bool flag) {
|
NX_CONSTEXPR void pselUiSetAllowUserCreation(PselUiSettings *ui, bool flag) {
|
||||||
if(ui->mode == PselUiMode_SelectUser) {
|
if(ui->settings.mode == PselUiMode_UserSelector) {
|
||||||
ui->allowUserCreation = flag;
|
ui->settings.allow_user_creation = flag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,20 +83,20 @@ NX_CONSTEXPR void pselUiSetAllowUserCreation(PselUiSettings *ui, bool flag) {
|
|||||||
* @param flag Flag value.
|
* @param flag Flag value.
|
||||||
*/
|
*/
|
||||||
NX_CONSTEXPR void pselUiSetNetworkServiceRequired(PselUiSettings *ui, bool flag) {
|
NX_CONSTEXPR void pselUiSetNetworkServiceRequired(PselUiSettings *ui, bool flag) {
|
||||||
ui->networkServiceRequired = flag;
|
ui->settings.network_service_required = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets whether selection can be skipped (with a new button)
|
* @brief Sets whether selection can be skipped (with a new button).
|
||||||
* @param ui PselUiSettings struct.
|
* @param ui PselUiSettings struct.
|
||||||
* @param flag Flag value.
|
* @param flag Flag value.
|
||||||
*/
|
*/
|
||||||
NX_CONSTEXPR void pselUiSetSkipEnabled(PselUiSettings *ui, bool flag) {
|
NX_CONSTEXPR void pselUiSetSkipEnabled(PselUiSettings *ui, bool flag) {
|
||||||
ui->skipEnabled = flag;
|
ui->settings.skip_enabled = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Shows playerSelect applet with the specified UI settings.
|
* @brief Shows the applet with the specified UI settings.
|
||||||
* @param ui PselUiSettings struct.
|
* @param ui PselUiSettings struct.
|
||||||
* @param out_user Selected user ID.
|
* @param out_user Selected user ID.
|
||||||
* @note If user skips (see \ref pselUiSetSkipEnabled) this will return successfully but the output ID will be 0.
|
* @note If user skips (see \ref pselUiSetSkipEnabled) this will return successfully but the output ID will be 0.
|
||||||
@ -96,25 +104,36 @@ NX_CONSTEXPR void pselUiSetSkipEnabled(PselUiSettings *ui, bool flag) {
|
|||||||
Result pselUiShow(PselUiSettings *ui, AccountUid *out_user);
|
Result pselUiShow(PselUiSettings *ui, AccountUid *out_user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Shows playerSelect applet to select a user.
|
* @brief Shows the applet to select a user.
|
||||||
* @param out_user Returned selected user ID.
|
* @param[out] out_user Returned selected user ID.
|
||||||
*/
|
*/
|
||||||
Result pselShowUserSelector(AccountUid *out_user);
|
Result pselShowUserSelector(AccountUid *out_user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Shows playerSelect applet to create a user.
|
* @brief Shows the applet to create a user.
|
||||||
* @param out_user Returned created user ID.
|
|
||||||
*/
|
*/
|
||||||
Result pselShowUserCreator(AccountUid *out_user);
|
Result pselShowUserCreator(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Shows playerSelect applet to change a user's icon.
|
* @brief Shows the applet to change a user's icon.
|
||||||
* @param user Input user ID.
|
* @param[in] user Input user ID.
|
||||||
*/
|
*/
|
||||||
Result pselShowIconEditor(AccountUid *user);
|
Result pselShowUserIconEditor(AccountUid user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Shows playerSelect applet to change a user's nickname.
|
* @brief Shows the applet to change a user's nickname.
|
||||||
* @param user Input user ID.
|
* @param[in] user Input user ID.
|
||||||
*/
|
*/
|
||||||
Result pselShowNicknameEditor(AccountUid *user);
|
Result pselShowUserNicknameEditor(AccountUid user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Shows the applet to create a user. Used by the starter applet during system setup.
|
||||||
|
*/
|
||||||
|
Result pselShowUserCreatorForStarter(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Shows the applet for Nintendo Account Nnid linking.
|
||||||
|
* @note Only available on [6.0.0+].
|
||||||
|
* @param[in] user Input user ID.
|
||||||
|
*/
|
||||||
|
Result pselShowNintendoAccountNnidLinker(AccountUid user);
|
||||||
|
@ -1,35 +1,29 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "types.h"
|
#include "libapplet_internal.h"
|
||||||
#include "result.h"
|
|
||||||
#include "services/applet.h"
|
|
||||||
#include "services/acc.h"
|
|
||||||
#include "applets/libapplet.h"
|
|
||||||
#include "applets/psel.h"
|
#include "applets/psel.h"
|
||||||
#include "runtime/hosversion.h"
|
#include "runtime/hosversion.h"
|
||||||
|
|
||||||
Result pselUiCreate(PselUiSettings *ui, PselUiMode mode) {
|
Result pselUiCreate(PselUiSettings *ui, PselUiMode mode) {
|
||||||
memset(ui, 0, sizeof(PselUiSettings));
|
memset(ui, 0, sizeof(PselUiSettings));
|
||||||
ui->mode = mode;
|
ui->settings.mode = mode;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pselUiAddUser(PselUiSettings *ui, AccountUid *user_id) {
|
void pselUiAddUser(PselUiSettings *ui, AccountUid user_id) {
|
||||||
int i;
|
for(u32 i=0; i<ACC_USER_LIST_SIZE; i++) {
|
||||||
for(i = 0; i < ACC_USER_LIST_SIZE; i++) {
|
if(!accountUidIsValid(&ui->settings.user_list[i])) {
|
||||||
|
ui->settings.user_list[i] = user_id;
|
||||||
if(!accountUidIsValid(&ui->invalidUserList[i])) {
|
|
||||||
__builtin_memcpy(&ui->invalidUserList[i], user_id, sizeof(AccountUid));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 _pselGetLaVersion() {
|
static u32 _pselGetLaVersion() {
|
||||||
u32 ver = 0;
|
u32 ver = 0x1; // [1.0.0]
|
||||||
u32 hosver = hosversionGet();
|
if (hosversionAtLeast(6,0,0))
|
||||||
if(hosver >= MAKEHOSVERSION(9,0,0)) {
|
|
||||||
ver = 0x20000;
|
ver = 0x20000;
|
||||||
}
|
else if (hosversionAtLeast(2,0,0))
|
||||||
|
ver = 0x10000;
|
||||||
return ver;
|
return ver;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,16 +32,21 @@ Result pselUiShow(PselUiSettings *ui, AccountUid *out_user) {
|
|||||||
LibAppletArgs args;
|
LibAppletArgs args;
|
||||||
u32 la_ver = _pselGetLaVersion();
|
u32 la_ver = _pselGetLaVersion();
|
||||||
libappletArgsCreate(&args, la_ver);
|
libappletArgsCreate(&args, la_ver);
|
||||||
PselResult res;
|
PselUiReturnArg ret;
|
||||||
size_t reply_size;
|
size_t reply_size;
|
||||||
|
const void* arg_ptr = ui;
|
||||||
|
size_t arg_size = sizeof(*ui);
|
||||||
|
|
||||||
rc = libappletLaunch(AppletId_playerSelect, &args, ui, sizeof(PselUiSettings), &res, sizeof(res), &reply_size);
|
if (la_ver == 0x1) { // [1.0.0]
|
||||||
|
arg_ptr = &ui->settings;
|
||||||
|
arg_size = sizeof(ui->settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = libappletLaunch(AppletId_playerSelect, &args, arg_ptr, arg_size, &ret, sizeof(ret), &reply_size);
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
if (res.result != 0) rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit);
|
rc = ret.res; // Official sw returns this directly.
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc) && out_user) *out_user = ret.user_id;
|
||||||
if(out_user) *out_user = res.userId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@ -55,25 +54,26 @@ Result pselUiShow(PselUiSettings *ui, AccountUid *out_user) {
|
|||||||
|
|
||||||
Result pselShowUserSelector(AccountUid *out_user) {
|
Result pselShowUserSelector(AccountUid *out_user) {
|
||||||
PselUiSettings ui;
|
PselUiSettings ui;
|
||||||
Result rc = pselUiCreate(&ui, PselUiMode_SelectUser);
|
Result rc = pselUiCreate(&ui, PselUiMode_UserSelector);
|
||||||
|
// TODO: This is missing the rest of the UiSettings setup done by official sw.
|
||||||
if(R_SUCCEEDED(rc)) {
|
if(R_SUCCEEDED(rc)) {
|
||||||
rc = pselUiShow(&ui, out_user);
|
rc = pselUiShow(&ui, out_user);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result pselShowUserCreator(AccountUid *out_user) {
|
Result pselShowUserCreator(void) {
|
||||||
PselUiSettings ui;
|
PselUiSettings ui;
|
||||||
Result rc = pselUiCreate(&ui, PselUiMode_UserCreation);
|
Result rc = pselUiCreate(&ui, PselUiMode_UserCreator);
|
||||||
if(R_SUCCEEDED(rc)) {
|
if(R_SUCCEEDED(rc)) {
|
||||||
rc = pselUiShow(&ui, out_user);
|
rc = pselUiShow(&ui, NULL);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result pselShowIconEditor(AccountUid *user) {
|
Result pselShowUserIconEditor(AccountUid user) {
|
||||||
PselUiSettings ui;
|
PselUiSettings ui;
|
||||||
Result rc = pselUiCreate(&ui, PselUiMode_IconEditor);
|
Result rc = pselUiCreate(&ui, PselUiMode_UserIconEditor);
|
||||||
if(R_SUCCEEDED(rc)) {
|
if(R_SUCCEEDED(rc)) {
|
||||||
pselUiAddUser(&ui, user);
|
pselUiAddUser(&ui, user);
|
||||||
rc = pselUiShow(&ui, NULL);
|
rc = pselUiShow(&ui, NULL);
|
||||||
@ -81,9 +81,31 @@ Result pselShowIconEditor(AccountUid *user) {
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result pselShowNicknameEditor(AccountUid *user) {
|
Result pselShowUserNicknameEditor(AccountUid user) {
|
||||||
PselUiSettings ui;
|
PselUiSettings ui;
|
||||||
Result rc = pselUiCreate(&ui, PselUiMode_NicknameEditor);
|
Result rc = pselUiCreate(&ui, PselUiMode_UserNicknameEditor);
|
||||||
|
if(R_SUCCEEDED(rc)) {
|
||||||
|
pselUiAddUser(&ui, user);
|
||||||
|
rc = pselUiShow(&ui, NULL);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result pselShowUserCreatorForStarter(void) {
|
||||||
|
PselUiSettings ui;
|
||||||
|
Result rc = pselUiCreate(&ui, PselUiMode_UserCreatorForStarter);
|
||||||
|
if(R_SUCCEEDED(rc)) {
|
||||||
|
rc = pselUiShow(&ui, NULL);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result pselShowNintendoAccountNnidLinker(AccountUid user) {
|
||||||
|
if (hosversionBefore(6,0,0))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||||
|
|
||||||
|
PselUiSettings ui;
|
||||||
|
Result rc = pselUiCreate(&ui, PselUiMode_NintendoAccountNnidLinker);
|
||||||
if(R_SUCCEEDED(rc)) {
|
if(R_SUCCEEDED(rc)) {
|
||||||
pselUiAddUser(&ui, user);
|
pselUiAddUser(&ui, user);
|
||||||
rc = pselUiShow(&ui, NULL);
|
rc = pselUiShow(&ui, NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user