mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-26 10:14:17 +01:00
Add profile service to support custom usernames
This commit is contained in:
parent
b86aac26d7
commit
ffb9e743dd
@ -118,6 +118,7 @@ add_library(skyline SHARED
|
||||
${source_DIR}/skyline/services/lm/ILogger.cpp
|
||||
${source_DIR}/skyline/services/account/IAccountServiceForApplication.cpp
|
||||
${source_DIR}/skyline/services/account/IManagerForApplication.cpp
|
||||
${source_DIR}/skyline/services/account/IProfile.cpp
|
||||
${source_DIR}/skyline/services/friends/IServiceCreator.cpp
|
||||
${source_DIR}/skyline/services/friends/IFriendService.cpp
|
||||
${source_DIR}/skyline/services/nfp/IUserManager.cpp
|
||||
|
@ -54,6 +54,7 @@ namespace skyline {
|
||||
constexpr u32 MaxHandles = 0xEE01; //!< "Too many handles"
|
||||
constexpr u32 NotFound = 0xF201; //!< "Not found"
|
||||
constexpr u32 Unimpl = 0x177202; //!< "Unimplemented behaviour"
|
||||
constexpr u32 InvArg = 0x2c7c; //!< "Argument is invalid"
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -3,11 +3,13 @@
|
||||
|
||||
#include "IManagerForApplication.h"
|
||||
#include "IAccountServiceForApplication.h"
|
||||
#include "IProfile.h"
|
||||
|
||||
namespace skyline::service::account {
|
||||
IAccountServiceForApplication::IAccountServiceForApplication(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::account_IAccountServiceForApplication, "account:IAccountServiceForApplication", {
|
||||
{0x1, SFUNC(IAccountServiceForApplication::GetUserExistence)},
|
||||
{0x4, SFUNC(IAccountServiceForApplication::GetLastOpenedUser)},
|
||||
{0x5, SFUNC(IAccountServiceForApplication::GetProfile)},
|
||||
{0x64, SFUNC(IAccountServiceForApplication::InitializeApplicationInfoV0)},
|
||||
{0x65, SFUNC(IAccountServiceForApplication::GetBaasAccountManagerForApplication)}
|
||||
}) {}
|
||||
@ -24,6 +26,16 @@ namespace skyline::service::account {
|
||||
|
||||
void IAccountServiceForApplication::InitializeApplicationInfoV0(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
|
||||
|
||||
void IAccountServiceForApplication::GetProfile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
auto id = request.Pop<UserId>();
|
||||
if (id != constant::DefaultUserId) {
|
||||
response.errorCode = constant::status::InvArg;
|
||||
return;
|
||||
}
|
||||
|
||||
manager.RegisterService(std::make_shared<IProfile>(state, manager, id), session, response);
|
||||
}
|
||||
|
||||
void IAccountServiceForApplication::GetBaasAccountManagerForApplication(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
manager.RegisterService(SRVREG(IManagerForApplication), session, response);
|
||||
}
|
||||
|
@ -19,9 +19,13 @@ namespace skyline {
|
||||
* @param userId The user ID to compare with
|
||||
* @return Whether this user ID matches the one given as a parameter
|
||||
*/
|
||||
inline constexpr bool operator==(const UserId& userId) {
|
||||
inline constexpr bool operator==(const UserId &userId) {
|
||||
return upper == userId.upper && lower == userId.lower;
|
||||
}
|
||||
|
||||
inline constexpr bool operator!=(const UserId &userId) {
|
||||
return !(*this == userId);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @brief IAccountServiceForApplication or acc:u0 provides functions for reading user information (https://switchbrew.org/wiki/Account_services#acc:u0)
|
||||
@ -45,6 +49,11 @@ namespace skyline {
|
||||
*/
|
||||
void InitializeApplicationInfoV0(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||
|
||||
/**
|
||||
* @brief This returns a handle to an IProfile which can be used for reading user information
|
||||
*/
|
||||
void GetProfile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||
|
||||
/**
|
||||
* @brief This returns a handle to an IManagerForApplication which can be used for reading Nintendo Online info
|
||||
*/
|
||||
|
24
app/src/main/cpp/skyline/services/account/IProfile.cpp
Normal file
24
app/src/main/cpp/skyline/services/account/IProfile.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#include <kernel/types/KProcess.h>
|
||||
#include "IProfile.h"
|
||||
|
||||
namespace skyline::service::account {
|
||||
IProfile::IProfile(const DeviceState &state, ServiceManager &manager, const UserId &userId) : BaseService(state, manager, Service::account_IProfile, "account:IProfile", {
|
||||
{0x0, SFUNC(IProfile::Get)}
|
||||
}) {}
|
||||
|
||||
void IProfile::Get(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
AccountUserData userData{};
|
||||
AccountProfileBase profileBase{};
|
||||
|
||||
std::string username = state.settings->GetString("username_value");
|
||||
size_t usernameSize = std::min(sizeof(profileBase), username.size());
|
||||
std::memcpy(profileBase.nickname, username.c_str(), usernameSize);
|
||||
profileBase.nickname[usernameSize] = '\0';
|
||||
|
||||
state.process->WriteMemory(userData, request.outputBuf.at(0).address);
|
||||
response.Push(profileBase);
|
||||
}
|
||||
}
|
41
app/src/main/cpp/skyline/services/account/IProfile.h
Normal file
41
app/src/main/cpp/skyline/services/account/IProfile.h
Normal file
@ -0,0 +1,41 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IAccountServiceForApplication.h"
|
||||
#include <services/base_service.h>
|
||||
|
||||
namespace skyline::service::account {
|
||||
|
||||
/// UserData
|
||||
typedef struct {
|
||||
u32 unk_x0; ///< Unknown.
|
||||
u32 iconID; ///< Icon ID. 0 = Mii, the rest are character icon IDs.
|
||||
u8 iconBackgroundColorID; ///< Profile icon background color ID
|
||||
u8 unk_x9[0x7]; ///< Unknown.
|
||||
u8 miiID[0x10]; ///< Some ID related to the Mii? All zeros when a character icon is used.
|
||||
u8 unk_x20[0x60]; ///< Usually zeros?
|
||||
} AccountUserData;
|
||||
|
||||
/// ProfileBase
|
||||
typedef struct {
|
||||
UserId uid; ///< \ref AccountUid
|
||||
u64 lastEditTimestamp; ///< POSIX UTC timestamp, for the last account edit.
|
||||
char nickname[0x20]; ///< UTF-8 Nickname.
|
||||
} AccountProfileBase;
|
||||
|
||||
/**
|
||||
* @brief IProfile provides functions for reading user profile (https://switchbrew.org/wiki/Account_services#IProfile)
|
||||
*/
|
||||
class IProfile : public BaseService {
|
||||
public:
|
||||
IProfile(const DeviceState &state, ServiceManager &manager, const UserId &userId);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief This returns AccountUserData (optional) and AccountProfileBase
|
||||
*/
|
||||
void Get(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||
};
|
||||
}
|
@ -73,6 +73,7 @@ namespace skyline::service {
|
||||
lm_ILogger,
|
||||
account_IAccountServiceForApplication,
|
||||
account_IManagerForApplication,
|
||||
account_IProfile,
|
||||
friends_IServiceCreator,
|
||||
friends_IFriendService,
|
||||
nfp_IUserManager,
|
||||
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
*/
|
||||
|
||||
package emu.skyline.preference
|
||||
|
||||
import android.content.Context
|
||||
import android.text.InputFilter
|
||||
import android.text.InputFilter.LengthFilter
|
||||
import android.util.AttributeSet
|
||||
import androidx.preference.EditTextPreference
|
||||
import emu.skyline.R
|
||||
|
||||
/**
|
||||
* [EditTextPreference] lacks the feature to set the automatically value as summary.
|
||||
* This class adds this missing thing. Also added useful attributes.
|
||||
*/
|
||||
class CustomEditTextPreference : EditTextPreference {
|
||||
|
||||
constructor(context : Context, attrs : AttributeSet?, defStyleAttr : Int, defStyleRes : Int) : super(context, attrs, defStyleAttr, defStyleRes) {
|
||||
attrs?.let {
|
||||
val a = context.obtainStyledAttributes(it, R.styleable.CustomEditTextPreference, defStyleAttr, 0)
|
||||
val limit = a.getInt(R.styleable.CustomEditTextPreference_limit, -1)
|
||||
a.recycle()
|
||||
|
||||
if (limit >= 0) {
|
||||
setOnBindEditTextListener { editText -> editText.filters = arrayOf<InputFilter>(LengthFilter(limit)) }
|
||||
}
|
||||
}
|
||||
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
summary = newValue.toString()
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
constructor(context : Context, attrs : AttributeSet?, defStyleAttr : Int) : this(context, attrs, defStyleAttr, 0)
|
||||
|
||||
constructor(context : Context, attrs : AttributeSet?) : this(context, attrs, androidx.preference.R.attr.editTextPreferenceStyle)
|
||||
|
||||
constructor(context : Context) : this(context, null)
|
||||
|
||||
override fun onAttached() {
|
||||
super.onAttached()
|
||||
|
||||
summary = text
|
||||
}
|
||||
}
|
6
app/src/main/res/values/attrs.xml
Normal file
6
app/src/main/res/values/attrs.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="CustomEditTextPreference">
|
||||
<attr name="limit" format="integer"/>
|
||||
</declare-styleable>
|
||||
</resources>
|
@ -38,6 +38,8 @@
|
||||
<string name="handheld_enabled">The system will emulate being in handheld mode</string>
|
||||
<string name="docked_enabled">The system will emulate being in docked mode</string>
|
||||
<string name="theme">Theme</string>
|
||||
<string name="username">Username</string>
|
||||
<string name="username_default">@string/app_name</string>
|
||||
<!-- Licenses -->
|
||||
<string name="licenses">Licenses</string>
|
||||
<string name="skyline_license_description">The license of Skyline (MPL 2.0)</string>
|
||||
|
@ -62,6 +62,11 @@
|
||||
android:summaryOn="@string/log_compact_desc_on"
|
||||
app:key="log_compact"
|
||||
app:title="@string/log_compact" />
|
||||
<emu.skyline.preference.CustomEditTextPreference
|
||||
android:defaultValue="@string/username_default"
|
||||
app:key="username_value"
|
||||
app:limit="32"
|
||||
app:title="@string/username" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory
|
||||
android:key="category_system"
|
||||
|
Loading…
Reference in New Issue
Block a user