mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-11 09:05:38 +00:00
Infrastructure username handling: Add separate username, pick Nickname as default if valid.
This commit is contained in:
parent
41e156a326
commit
01b06b76c9
@ -105,6 +105,38 @@ int countChar(std::string_view haystack, char needle) {
|
||||
return count;
|
||||
}
|
||||
|
||||
std::string SanitizeString(std::string_view input, StringRestriction restriction, int maxLength) {
|
||||
if (restriction == StringRestriction::None) {
|
||||
return std::string(input);
|
||||
}
|
||||
// First, remove any chars not in A-Za-z0-9_-. This will effectively get rid of any Unicode char, emojis etc too.
|
||||
std::string sanitized;
|
||||
for (auto c : input) {
|
||||
switch (restriction) {
|
||||
case StringRestriction::None:
|
||||
sanitized.push_back(c);
|
||||
break;
|
||||
case StringRestriction::AlphaNumDashUnderscore:
|
||||
if ((c >= 'A' && c <= 'Z') ||
|
||||
(c >= 'a' && c <= 'z') ||
|
||||
(c >= '0' && c <= '9') || c == '-' || c == '_') {
|
||||
// Allowed chars.
|
||||
sanitized.push_back(c);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxLength >= 0) {
|
||||
// TODO: Cut at whole UTF-8 chars!
|
||||
if (sanitized.size() > maxLength) {
|
||||
sanitized.resize(maxLength);
|
||||
}
|
||||
}
|
||||
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args)
|
||||
{
|
||||
int writtenCount = vsnprintf(out, outsize, format, args);
|
||||
|
@ -71,6 +71,13 @@ inline bool equalsNoCase(std::string_view str, std::string_view key) {
|
||||
|
||||
bool containsNoCase(std::string_view haystack, std::string_view needle);
|
||||
|
||||
enum class StringRestriction {
|
||||
None,
|
||||
AlphaNumDashUnderscore, // Used for infrastructure usernames
|
||||
};
|
||||
|
||||
std::string SanitizeString(std::string_view username, StringRestriction restriction, int maxLength = -1);
|
||||
|
||||
void DataToHexString(const uint8_t *data, size_t size, std::string *output);
|
||||
void DataToHexString(int indent, uint32_t startAddr, const uint8_t* data, size_t size, std::string* output);
|
||||
|
||||
|
@ -519,7 +519,7 @@ void SliderFloatPopupScreen::OnCompleted(DialogResult result) {
|
||||
}
|
||||
|
||||
PopupTextInputChoice::PopupTextInputChoice(RequesterToken token, std::string *value, std::string_view title, std::string_view placeholder, int maxLen, ScreenManager *screenManager, LayoutParams *layoutParams)
|
||||
: AbstractChoiceWithValueDisplay(title, layoutParams), screenManager_(screenManager), value_(value), placeHolder_(placeholder), maxLen_(maxLen), token_(token) {
|
||||
: AbstractChoiceWithValueDisplay(title, layoutParams), screenManager_(screenManager), value_(value), placeHolder_(placeholder), maxLen_(maxLen), token_(token), restriction_(StringRestriction::None) {
|
||||
OnClick.Handle(this, &PopupTextInputChoice::HandleClick);
|
||||
}
|
||||
|
||||
@ -529,7 +529,7 @@ EventReturn PopupTextInputChoice::HandleClick(EventParams &e) {
|
||||
// Choose method depending on platform capabilities.
|
||||
if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) {
|
||||
System_InputBoxGetString(token_, text_, *value_, passwordMasking_, [=](const std::string &enteredValue, int) {
|
||||
*value_ = StripSpaces(enteredValue);
|
||||
*value_ = SanitizeString(StripSpaces(enteredValue), restriction_, maxLen_);
|
||||
EventParams params{};
|
||||
OnChange.Trigger(params);
|
||||
});
|
||||
@ -553,6 +553,7 @@ std::string PopupTextInputChoice::ValueText() const {
|
||||
}
|
||||
|
||||
EventReturn PopupTextInputChoice::HandleChange(EventParams &e) {
|
||||
*value_ = StripSpaces(SanitizeString(*value_, restriction_, maxLen_));
|
||||
e.v = this;
|
||||
OnChange.Trigger(e);
|
||||
|
||||
|
@ -8,6 +8,9 @@
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ScrollView.h"
|
||||
|
||||
// from StringUtils
|
||||
enum class StringRestriction;
|
||||
|
||||
namespace UI {
|
||||
|
||||
static const float NO_DEFAULT_FLOAT = -1000000.0f;
|
||||
@ -371,6 +374,10 @@ public:
|
||||
|
||||
Event OnChange;
|
||||
|
||||
void SetRestriction(StringRestriction restriction) {
|
||||
restriction_ = restriction;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string ValueText() const override;
|
||||
|
||||
@ -384,6 +391,7 @@ private:
|
||||
std::string defaultText_;
|
||||
int maxLen_;
|
||||
bool restoreFocus_ = false;
|
||||
StringRestriction restriction_;
|
||||
};
|
||||
|
||||
class ChoiceWithValueDisplay : public AbstractChoiceWithValueDisplay {
|
||||
|
@ -111,7 +111,7 @@ GPUBackend GPUBackendFromString(std::string_view backend) {
|
||||
return GPUBackend::OPENGL;
|
||||
}
|
||||
|
||||
const char *DefaultLangRegion() {
|
||||
std::string DefaultLangRegion() {
|
||||
// Unfortunate default. There's no need to use bFirstRun, since this is only a default.
|
||||
static std::string defaultLangRegion = "en_US";
|
||||
std::string langRegion = System_GetProperty(SYSPROP_LANGREGION);
|
||||
@ -136,7 +136,7 @@ const char *DefaultLangRegion() {
|
||||
}
|
||||
}
|
||||
|
||||
return defaultLangRegion.c_str();
|
||||
return defaultLangRegion;
|
||||
}
|
||||
|
||||
static int DefaultDepthRaster() {
|
||||
@ -602,6 +602,20 @@ static std::string FastForwardModeToString(int v) {
|
||||
return "CONTINUOUS";
|
||||
}
|
||||
|
||||
static std::string DefaultInfrastructureUsername() {
|
||||
// If the user has already picked a Nickname that satisfies the rules and is not "PPSSPP",
|
||||
// let's use that.
|
||||
// NOTE: This type of dependency means that network settings must be AFTER system settings in sections[].
|
||||
if (g_Config.sNickName != "PPSSPP" &&
|
||||
!g_Config.sNickName.empty() &&
|
||||
g_Config.sNickName == SanitizeString(g_Config.sNickName, StringRestriction::AlphaNumDashUnderscore, 16)) {
|
||||
return g_Config.sNickName;
|
||||
}
|
||||
|
||||
// Otherwise let's leave it empty, which will result in login failure and a warning.
|
||||
return std::string();
|
||||
}
|
||||
|
||||
static const ConfigSetting graphicsSettings[] = {
|
||||
ConfigSetting("EnableCardboardVR", &g_Config.bEnableCardboardVR, false, CfgFlag::PER_GAME),
|
||||
ConfigSetting("CardboardScreenSize", &g_Config.iCardboardScreenSize, 50, CfgFlag::PER_GAME),
|
||||
@ -893,6 +907,7 @@ static const ConfigSetting networkSettings[] = {
|
||||
ConfigSetting("ForcedFirstConnect", &g_Config.bForcedFirstConnect, false, CfgFlag::PER_GAME),
|
||||
ConfigSetting("EnableUPnP", &g_Config.bEnableUPnP, false, CfgFlag::PER_GAME),
|
||||
ConfigSetting("UPnPUseOriginalPort", &g_Config.bUPnPUseOriginalPort, false, CfgFlag::PER_GAME),
|
||||
ConfigSetting("InfrastructureUsername", &g_Config.sInfrastructureUsername, &DefaultInfrastructureUsername, CfgFlag::PER_GAME),
|
||||
|
||||
ConfigSetting("EnableNetworkChat", &g_Config.bEnableNetworkChat, false, CfgFlag::PER_GAME),
|
||||
ConfigSetting("ChatButtonPosition", &g_Config.iChatButtonPosition, (int)ScreenEdgePosition::BOTTOM_LEFT, CfgFlag::PER_GAME),
|
||||
@ -993,8 +1008,8 @@ static const ConfigSectionSettings sections[] = {
|
||||
{"Graphics", graphicsSettings, ARRAY_SIZE(graphicsSettings)},
|
||||
{"Sound", soundSettings, ARRAY_SIZE(soundSettings)},
|
||||
{"Control", controlSettings, ARRAY_SIZE(controlSettings)},
|
||||
{"Network", networkSettings, ARRAY_SIZE(networkSettings)},
|
||||
{"SystemParam", systemParamSettings, ARRAY_SIZE(systemParamSettings)},
|
||||
{"Network", networkSettings, ARRAY_SIZE(networkSettings)},
|
||||
{"Debugger", debuggerSettings, ARRAY_SIZE(debuggerSettings)},
|
||||
{"JIT", jitSettings, ARRAY_SIZE(jitSettings)},
|
||||
{"Upgrade", upgradeSettings, ARRAY_SIZE(upgradeSettings)},
|
||||
|
@ -443,8 +443,9 @@ public:
|
||||
bool bDiscardRegsOnJRRA;
|
||||
|
||||
// SystemParam
|
||||
std::string sNickName;
|
||||
std::string sNickName; // AdHoc and system nickname
|
||||
std::string sMACAddress;
|
||||
|
||||
int iLanguage;
|
||||
int iTimeFormat;
|
||||
int iDateFormat;
|
||||
@ -459,6 +460,7 @@ public:
|
||||
std::string proAdhocServer;
|
||||
std::string primaryDNSServer;
|
||||
std::string secondaryDNSServer;
|
||||
std::string sInfrastructureUsername; // Username used for Infrastructure play. Different restrictions.
|
||||
bool bEnableWlan;
|
||||
std::map<std::string, std::string> mHostToAlias; // TODO: mPostShaderSetting
|
||||
bool bEnableAdhocServer;
|
||||
|
@ -36,7 +36,7 @@ bool ConfigSetting::Get(const Section *section) const {
|
||||
case TYPE_FLOAT:
|
||||
return section->Get(iniKey_, ptr_.f, cb_.f ? cb_.f() : default_.f);
|
||||
case TYPE_STRING:
|
||||
return section->Get(iniKey_, ptr_.s, cb_.s ? cb_.s() : default_.s);
|
||||
return section->Get(iniKey_, ptr_.s, cb_.s ? cb_.s().c_str() : default_.s);
|
||||
case TYPE_TOUCH_POS:
|
||||
{
|
||||
ConfigTouchPos defaultTouchPos = cb_.touchPos ? cb_.touchPos() : default_.touchPos;
|
||||
|
@ -57,7 +57,7 @@ struct ConfigSetting {
|
||||
typedef uint32_t(*Uint32DefaultCallback)();
|
||||
typedef uint64_t(*Uint64DefaultCallback)();
|
||||
typedef float (*FloatDefaultCallback)();
|
||||
typedef const char *(*StringDefaultCallback)();
|
||||
typedef std::string (*StringDefaultCallback)();
|
||||
typedef ConfigTouchPos(*TouchPosDefaultCallback)();
|
||||
typedef const char *(*PathDefaultCallback)();
|
||||
typedef ConfigCustomButton(*CustomButtonDefaultCallback)();
|
||||
|
@ -20,7 +20,10 @@
|
||||
|
||||
#include <mutex>
|
||||
#include <deque>
|
||||
#include <StringUtils.h>
|
||||
|
||||
#include "Common/System/OSD.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Core/MemMapHelpers.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/Config.h"
|
||||
@ -52,7 +55,6 @@ std::recursive_mutex npAuthEvtMtx;
|
||||
std::deque<NpAuthArgs> npAuthEvents;
|
||||
std::map<int, NpAuthHandler> npAuthHandlers;
|
||||
|
||||
|
||||
// Tickets data are in big-endian based on captured packets
|
||||
static int writeTicketParam(u8* buffer, const u16_be type, const char* data = nullptr, const u16_be size = 0) {
|
||||
if (buffer == nullptr) return 0;
|
||||
@ -112,12 +114,16 @@ static void notifyNpAuthHandlers(u32 id, u32 result, u32 argAddr) {
|
||||
static int sceNpInit()
|
||||
{
|
||||
ERROR_LOG(Log::sceNet, "UNIMPL %s()", __FUNCTION__);
|
||||
npOnlineId = g_Config.sNickName;
|
||||
// Truncate the nickname to 16 chars exactly - longer names are not support.
|
||||
if (npOnlineId.size() > 16) {
|
||||
npOnlineId.resize(16);
|
||||
|
||||
// We'll sanitize an extra time here, just to be safe from ini modifications.
|
||||
if (g_Config.sInfrastructureUsername == SanitizeString(g_Config.sInfrastructureUsername, StringRestriction::AlphaNumDashUnderscore, 16)) {
|
||||
npOnlineId = g_Config.sInfrastructureUsername;
|
||||
} else {
|
||||
npOnlineId.clear();
|
||||
}
|
||||
|
||||
// NOTE: Checking validity and returning -1 here doesn't seem to work. Instead, we will fail to generate a ticket.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -402,6 +408,14 @@ int sceNpAuthGetTicket(u32 requestId, u32 bufferAddr, u32 length)
|
||||
if (!Memory::IsValidAddress(bufferAddr))
|
||||
return hleLogError(Log::sceNet, SCE_NP_AUTH_ERROR_INVALID_ARGUMENT, "invalid arg");
|
||||
|
||||
// We have validated, and this will be empty if the ID is bad.
|
||||
if (npOnlineId.empty()) {
|
||||
auto n = GetI18NCategory(I18NCat::NETWORKING);
|
||||
// Temporary message.
|
||||
g_OSD.Show(OSDType::MESSAGE_ERROR, n->T("To play in Infrastructure Mode, you must enter a username"), 5.0f);
|
||||
return hleLogError(Log::sceNet, SCE_NP_AUTH_ERROR_UNKNOWN, "Missing npOnlineId");
|
||||
}
|
||||
|
||||
int result = length;
|
||||
Memory::Memset(bufferAddr, 0, length, "NpAuthGetTicket");
|
||||
SceNpTicket ticket = {};
|
||||
|
@ -941,6 +941,16 @@ void GameSettingsScreen::CreateNetworkingSettings(UI::ViewGroup *networkingSetti
|
||||
useOriPort->SetEnabledPtr(&g_Config.bEnableUPnP);
|
||||
|
||||
networkingSettings->Add(new ItemHeader(n->T("Infrastructure")));
|
||||
if (g_Config.sInfrastructureUsername.empty()) {
|
||||
networkingSettings->Add(new NoticeView(NoticeLevel::WARN, n->T("To play in Infrastructure Mode, you must enter a username"), ""));
|
||||
}
|
||||
PopupTextInputChoice *usernameChoice = networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sInfrastructureUsername, n->T("Username"), "", 16, screenManager()));
|
||||
usernameChoice->SetRestriction(StringRestriction::AlphaNumDashUnderscore);
|
||||
usernameChoice->OnChange.Add([this](UI::EventParams &e) {
|
||||
RecreateViews();
|
||||
return UI::EVENT_DONE;
|
||||
});
|
||||
|
||||
networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.primaryDNSServer, n->T("Primary DNS server"), "", 32, screenManager()));
|
||||
networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.secondaryDNSServer, n->T("Secondary DNS server"), "", 32, screenManager()));
|
||||
|
||||
@ -1682,62 +1692,42 @@ UI::EventReturn GameSettingsScreen::OnAudioDevice(UI::EventParams &e) {
|
||||
}
|
||||
|
||||
UI::EventReturn GameSettingsScreen::OnChangeQuickChat0(UI::EventParams &e) {
|
||||
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH)
|
||||
auto n = GetI18NCategory(I18NCat::NETWORKING);
|
||||
System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 1"), g_Config.sQuickChat0, false, [](const std::string &value, int) {
|
||||
g_Config.sQuickChat0 = value;
|
||||
});
|
||||
#endif
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn GameSettingsScreen::OnChangeQuickChat1(UI::EventParams &e) {
|
||||
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH)
|
||||
auto n = GetI18NCategory(I18NCat::NETWORKING);
|
||||
System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 2"), g_Config.sQuickChat1, false, [](const std::string &value, int) {
|
||||
g_Config.sQuickChat1 = value;
|
||||
});
|
||||
#endif
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn GameSettingsScreen::OnChangeQuickChat2(UI::EventParams &e) {
|
||||
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH)
|
||||
auto n = GetI18NCategory(I18NCat::NETWORKING);
|
||||
System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 3"), g_Config.sQuickChat2, false, [](const std::string &value, int) {
|
||||
g_Config.sQuickChat2 = value;
|
||||
});
|
||||
#endif
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn GameSettingsScreen::OnChangeQuickChat3(UI::EventParams &e) {
|
||||
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH)
|
||||
auto n = GetI18NCategory(I18NCat::NETWORKING);
|
||||
System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 4"), g_Config.sQuickChat3, false, [](const std::string &value, int) {
|
||||
g_Config.sQuickChat3 = value;
|
||||
});
|
||||
#endif
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn GameSettingsScreen::OnChangeQuickChat4(UI::EventParams &e) {
|
||||
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH)
|
||||
auto n = GetI18NCategory(I18NCat::NETWORKING);
|
||||
System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 5"), g_Config.sQuickChat4, false, [](const std::string &value, int) {
|
||||
g_Config.sQuickChat4 = value;
|
||||
});
|
||||
#endif
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn GameSettingsScreen::OnChangeNickname(UI::EventParams &e) {
|
||||
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH)
|
||||
auto n = GetI18NCategory(I18NCat::NETWORKING);
|
||||
System_InputBoxGetString(GetRequesterToken(), n->T("Enter a new PSP nickname"), g_Config.sNickName, false, [](const std::string &value, int) {
|
||||
g_Config.sNickName = StripSpaces(value);
|
||||
});
|
||||
#endif
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,6 @@ private:
|
||||
UI::EventReturn OnChangeQuickChat2(UI::EventParams &e);
|
||||
UI::EventReturn OnChangeQuickChat3(UI::EventParams &e);
|
||||
UI::EventReturn OnChangeQuickChat4(UI::EventParams &e);
|
||||
UI::EventReturn OnChangeNickname(UI::EventParams &e);
|
||||
UI::EventReturn OnChangeproAdhocServerAddress(UI::EventParams &e);
|
||||
UI::EventReturn OnChangeBackground(UI::EventParams &e);
|
||||
UI::EventReturn OnFullscreenChange(UI::EventParams &e);
|
||||
|
Loading…
x
Reference in New Issue
Block a user