mirror of
https://github.com/skyline-emu/skyline.git
synced 2025-01-15 05:37:56 +03: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/lm/ILogger.cpp
|
||||||
${source_DIR}/skyline/services/account/IAccountServiceForApplication.cpp
|
${source_DIR}/skyline/services/account/IAccountServiceForApplication.cpp
|
||||||
${source_DIR}/skyline/services/account/IManagerForApplication.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/IServiceCreator.cpp
|
||||||
${source_DIR}/skyline/services/friends/IFriendService.cpp
|
${source_DIR}/skyline/services/friends/IFriendService.cpp
|
||||||
${source_DIR}/skyline/services/nfp/IUserManager.cpp
|
${source_DIR}/skyline/services/nfp/IUserManager.cpp
|
||||||
|
@ -54,6 +54,7 @@ namespace skyline {
|
|||||||
constexpr u32 MaxHandles = 0xEE01; //!< "Too many handles"
|
constexpr u32 MaxHandles = 0xEE01; //!< "Too many handles"
|
||||||
constexpr u32 NotFound = 0xF201; //!< "Not found"
|
constexpr u32 NotFound = 0xF201; //!< "Not found"
|
||||||
constexpr u32 Unimpl = 0x177202; //!< "Unimplemented behaviour"
|
constexpr u32 Unimpl = 0x177202; //!< "Unimplemented behaviour"
|
||||||
|
constexpr u32 InvArg = 0x2c7c; //!< "Argument is invalid"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,11 +3,13 @@
|
|||||||
|
|
||||||
#include "IManagerForApplication.h"
|
#include "IManagerForApplication.h"
|
||||||
#include "IAccountServiceForApplication.h"
|
#include "IAccountServiceForApplication.h"
|
||||||
|
#include "IProfile.h"
|
||||||
|
|
||||||
namespace skyline::service::account {
|
namespace skyline::service::account {
|
||||||
IAccountServiceForApplication::IAccountServiceForApplication(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::account_IAccountServiceForApplication, "account:IAccountServiceForApplication", {
|
IAccountServiceForApplication::IAccountServiceForApplication(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::account_IAccountServiceForApplication, "account:IAccountServiceForApplication", {
|
||||||
{0x1, SFUNC(IAccountServiceForApplication::GetUserExistence)},
|
{0x1, SFUNC(IAccountServiceForApplication::GetUserExistence)},
|
||||||
{0x4, SFUNC(IAccountServiceForApplication::GetLastOpenedUser)},
|
{0x4, SFUNC(IAccountServiceForApplication::GetLastOpenedUser)},
|
||||||
|
{0x5, SFUNC(IAccountServiceForApplication::GetProfile)},
|
||||||
{0x64, SFUNC(IAccountServiceForApplication::InitializeApplicationInfoV0)},
|
{0x64, SFUNC(IAccountServiceForApplication::InitializeApplicationInfoV0)},
|
||||||
{0x65, SFUNC(IAccountServiceForApplication::GetBaasAccountManagerForApplication)}
|
{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::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) {
|
void IAccountServiceForApplication::GetBaasAccountManagerForApplication(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
manager.RegisterService(SRVREG(IManagerForApplication), session, response);
|
manager.RegisterService(SRVREG(IManagerForApplication), session, response);
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,10 @@ namespace skyline {
|
|||||||
inline constexpr bool operator==(const UserId &userId) {
|
inline constexpr bool operator==(const UserId &userId) {
|
||||||
return upper == userId.upper && lower == userId.lower;
|
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)
|
* @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);
|
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
|
* @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,
|
lm_ILogger,
|
||||||
account_IAccountServiceForApplication,
|
account_IAccountServiceForApplication,
|
||||||
account_IManagerForApplication,
|
account_IManagerForApplication,
|
||||||
|
account_IProfile,
|
||||||
friends_IServiceCreator,
|
friends_IServiceCreator,
|
||||||
friends_IFriendService,
|
friends_IFriendService,
|
||||||
nfp_IUserManager,
|
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="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="docked_enabled">The system will emulate being in docked mode</string>
|
||||||
<string name="theme">Theme</string>
|
<string name="theme">Theme</string>
|
||||||
|
<string name="username">Username</string>
|
||||||
|
<string name="username_default">@string/app_name</string>
|
||||||
<!-- Licenses -->
|
<!-- Licenses -->
|
||||||
<string name="licenses">Licenses</string>
|
<string name="licenses">Licenses</string>
|
||||||
<string name="skyline_license_description">The license of Skyline (MPL 2.0)</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"
|
android:summaryOn="@string/log_compact_desc_on"
|
||||||
app:key="log_compact"
|
app:key="log_compact"
|
||||||
app:title="@string/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>
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:key="category_system"
|
android:key="category_system"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user