mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Merge pull request #19492 from hrydgard/more-misc-fixes
RetroAchievements login: Implement password masking
This commit is contained in:
commit
9208d9d49a
@ -78,6 +78,9 @@ void NativeShutdown();
|
||||
void PostLoadConfig();
|
||||
|
||||
// Returns false on failure. Shouldn't really happen, though.
|
||||
bool NativeSaveSecret(const char *nameOfSecret, const std::string &data);
|
||||
bool NativeSaveSecret(std::string_view nameOfSecret, std::string_view data);
|
||||
inline bool NativeClearSecret(std::string_view nameOfSecret) {
|
||||
return NativeSaveSecret(nameOfSecret, "");
|
||||
}
|
||||
// On failure, returns an empty string. Good enough since any real secret is non-empty.
|
||||
std::string NativeLoadSecret(const char *nameOfSecret);
|
||||
std::string NativeLoadSecret(std::string_view nameOfSecret);
|
||||
|
@ -84,8 +84,8 @@ extern RequestManager g_requestManager;
|
||||
// Wrappers for easy requests.
|
||||
// NOTE: Semantics have changed - this no longer calls the callback on cancellation, instead you
|
||||
// can specify a different callback for that.
|
||||
inline void System_InputBoxGetString(RequesterToken token, std::string_view title, std::string_view defaultValue, RequestCallback callback, RequestFailedCallback failedCallback = nullptr) {
|
||||
g_requestManager.MakeSystemRequest(SystemRequestType::INPUT_TEXT_MODAL, token, callback, failedCallback, title, defaultValue, 0);
|
||||
inline void System_InputBoxGetString(RequesterToken token, std::string_view title, std::string_view defaultValue, bool passwordMasking, RequestCallback callback, RequestFailedCallback failedCallback = nullptr) {
|
||||
g_requestManager.MakeSystemRequest(SystemRequestType::INPUT_TEXT_MODAL, token, callback, failedCallback, title, defaultValue, passwordMasking ? 1 : 0);
|
||||
}
|
||||
|
||||
// This one will pop up a special image browser if available. You can also pick
|
||||
|
@ -528,7 +528,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_ , [=](const std::string &enteredValue, int) {
|
||||
System_InputBoxGetString(token_, text_, *value_, passwordMasking_, [=](const std::string &enteredValue, int) {
|
||||
*value_ = StripSpaces(enteredValue);
|
||||
EventParams params{};
|
||||
OnChange.Trigger(params);
|
||||
@ -537,6 +537,7 @@ EventReturn PopupTextInputChoice::HandleClick(EventParams &e) {
|
||||
}
|
||||
|
||||
TextEditPopupScreen *popupScreen = new TextEditPopupScreen(value_, placeHolder_, ChopTitle(text_), maxLen_);
|
||||
popupScreen->SetPasswordMasking(passwordMasking_);
|
||||
if (System_GetPropertyBool(SYSPROP_KEYBOARD_IS_SOFT)) {
|
||||
popupScreen->SetAlignTop(true);
|
||||
}
|
||||
@ -570,6 +571,7 @@ void TextEditPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
edit_ = new TextEdit(textEditValue_, Title(), placeholder_, new LinearLayoutParams(1.0f));
|
||||
edit_->SetMaxLen(maxLen_);
|
||||
edit_->SetTextColor(dc.theme->popupStyle.fgColor);
|
||||
edit_->SetPasswordMasking(passwordMasking_);
|
||||
lin->Add(edit_);
|
||||
|
||||
UI::SetFocusedView(edit_);
|
||||
@ -628,7 +630,7 @@ void AbstractChoiceWithValueDisplay::Draw(UIContext &dc) {
|
||||
|
||||
std::string valueText = ValueText();
|
||||
|
||||
if (passwordDisplay_) {
|
||||
if (passwordMasking_) {
|
||||
// Replace all characters with stars.
|
||||
memset(&valueText[0], '*', valueText.size());
|
||||
}
|
||||
|
@ -150,6 +150,10 @@ public:
|
||||
|
||||
const char *tag() const override { return "TextEditPopup"; }
|
||||
|
||||
void SetPasswordMasking(bool masking) {
|
||||
passwordMasking_ = masking;
|
||||
}
|
||||
|
||||
Event OnChange;
|
||||
|
||||
private:
|
||||
@ -159,6 +163,7 @@ private:
|
||||
std::string textEditValue_;
|
||||
std::string placeholder_;
|
||||
int maxLen_;
|
||||
bool passwordMasking_ = false;
|
||||
};
|
||||
|
||||
struct ContextMenuItem {
|
||||
|
@ -1142,18 +1142,25 @@ void TextEdit::Draw(UIContext &dc) {
|
||||
Bounds textBounds = bounds_;
|
||||
textBounds.x = textX - scrollPos_;
|
||||
|
||||
std::string textToDisplay = text_;
|
||||
if (passwordMasking_) {
|
||||
for (int i = 0; i < textToDisplay.size(); i++) {
|
||||
textToDisplay[i] = '*';
|
||||
}
|
||||
}
|
||||
|
||||
if (text_.empty()) {
|
||||
if (placeholderText_.size()) {
|
||||
uint32_t c = textColor & 0x50FFFFFF;
|
||||
dc.DrawTextRect(placeholderText_, bounds_, c, ALIGN_CENTER);
|
||||
}
|
||||
} else {
|
||||
dc.DrawTextRect(text_, textBounds, textColor, ALIGN_VCENTER | ALIGN_LEFT | align_);
|
||||
dc.DrawTextRect(textToDisplay, textBounds, textColor, ALIGN_VCENTER | ALIGN_LEFT | align_);
|
||||
}
|
||||
|
||||
if (HasFocus()) {
|
||||
// Hack to find the caret position. Might want to find a better way...
|
||||
dc.MeasureText(dc.theme->uiFont, 1.0f, 1.0f, text_.substr(0, caret_), &w, &h, ALIGN_VCENTER | ALIGN_LEFT | align_);
|
||||
dc.MeasureText(dc.theme->uiFont, 1.0f, 1.0f, textToDisplay.substr(0, caret_), &w, &h, ALIGN_VCENTER | ALIGN_LEFT | align_);
|
||||
float caretX = w - scrollPos_;
|
||||
if (caretX > bounds_.w) {
|
||||
scrollPos_ += caretX - bounds_.w;
|
||||
|
@ -825,14 +825,14 @@ public:
|
||||
void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override;
|
||||
|
||||
void SetPasswordDisplay() {
|
||||
passwordDisplay_ = true;
|
||||
passwordMasking_ = true;
|
||||
}
|
||||
protected:
|
||||
virtual std::string ValueText() const = 0;
|
||||
|
||||
float CalculateValueScale(const UIContext &dc, std::string_view valueText, float availWidth) const;
|
||||
|
||||
bool passwordDisplay_ = false;
|
||||
bool passwordMasking_ = false;
|
||||
};
|
||||
|
||||
class ChoiceWithCallbackValueDisplay : public AbstractChoiceWithValueDisplay {
|
||||
@ -1026,6 +1026,9 @@ public:
|
||||
const std::string &GetText() const { return text_; }
|
||||
void SetMaxLen(size_t maxLen) { maxLen_ = maxLen; }
|
||||
void SetTextAlign(int align) { align_ = align; } // Only really useful for setting FLAG_DYNAMIC_ASCII
|
||||
void SetPasswordMasking(bool masking) {
|
||||
passwordMasking_ = masking;
|
||||
}
|
||||
|
||||
void FocusChanged(int focusFlags) override;
|
||||
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
|
||||
@ -1050,6 +1053,7 @@ private:
|
||||
int scrollPos_ = 0;
|
||||
size_t maxLen_;
|
||||
bool ctrlDown_ = false; // TODO: Make some global mechanism for this.
|
||||
bool passwordMasking_ = false;
|
||||
int align_ = 0;
|
||||
// TODO: Selections
|
||||
};
|
||||
|
@ -897,7 +897,7 @@ int PSPOskDialog::NativeKeyboard() {
|
||||
defaultText.assign(u"VALUE");
|
||||
|
||||
// There's already ConvertUCS2ToUTF8 in this file. Should we use that instead of the global ones?
|
||||
System_InputBoxGetString(NON_EPHEMERAL_TOKEN, ::ConvertUCS2ToUTF8(titleText), ::ConvertUCS2ToUTF8(defaultText),
|
||||
System_InputBoxGetString(NON_EPHEMERAL_TOKEN, ::ConvertUCS2ToUTF8(titleText), ::ConvertUCS2ToUTF8(defaultText), false,
|
||||
[&](const std::string &value, int) {
|
||||
// Success callback
|
||||
std::lock_guard<std::mutex> guard(nativeMutex_);
|
||||
|
@ -503,8 +503,19 @@ static void login_token_callback(int result, const char *error_message, rc_clien
|
||||
auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS);
|
||||
g_OSD.Show(OSDType::MESSAGE_WARNING, ac->T("Failed logging in to RetroAchievements"), "", g_RAImageID);
|
||||
}
|
||||
|
||||
// Clear the token.
|
||||
if (result == RC_INVALID_CREDENTIALS || result == RC_EXPIRED_TOKEN) {
|
||||
g_Config.sAchievementsUserName.clear();
|
||||
NativeClearSecret(RA_TOKEN_SECRET_NAME);
|
||||
g_loginResult = RC_OK;
|
||||
} else {
|
||||
g_loginResult = result;
|
||||
}
|
||||
|
||||
OnAchievementsLoginStateChange();
|
||||
break;
|
||||
g_isLoggingIn = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
g_loginResult = result;
|
||||
@ -718,7 +729,7 @@ void Logout() {
|
||||
rc_client_logout(g_rcClient);
|
||||
// remove from config
|
||||
g_Config.sAchievementsUserName.clear();
|
||||
NativeSaveSecret(RA_TOKEN_SECRET_NAME, "");
|
||||
NativeClearSecret(RA_TOKEN_SECRET_NAME);
|
||||
g_Config.Save("Achievements logout");
|
||||
g_activeChallenges.clear();
|
||||
g_loginResult = RC_OK; // Allow trying again
|
||||
|
@ -234,7 +234,8 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string
|
||||
g_QuitRequested = true;
|
||||
return true;
|
||||
#if PPSSPP_PLATFORM(SWITCH)
|
||||
case SystemRequestType::INPUT_TEXT_MODAL: {
|
||||
case SystemRequestType::INPUT_TEXT_MODAL:
|
||||
{
|
||||
// swkbd only works on "real" titles
|
||||
if (__nx_applet_type != AppletType_Application && __nx_applet_type != AppletType_SystemApplication) {
|
||||
g_requestManager.PostSystemFailure(requestId);
|
||||
|
@ -97,7 +97,7 @@ UI::EventReturn ChatMenu::OnSubmit(UI::EventParams &e) {
|
||||
sendChat(chat);
|
||||
#elif PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH) || PPSSPP_PLATFORM(IOS)
|
||||
auto n = GetI18NCategory(I18NCat::NETWORKING);
|
||||
System_InputBoxGetString(token_, n->T("Chat"), "", [](const std::string &value, int) {
|
||||
System_InputBoxGetString(token_, n->T("Chat"), "", false, [](const std::string &value, int) {
|
||||
sendChat(value);
|
||||
});
|
||||
#endif
|
||||
@ -180,7 +180,7 @@ void ChatMenu::Update() {
|
||||
// Could remove the fullscreen check here, it works now.
|
||||
auto n = GetI18NCategory(I18NCat::NETWORKING);
|
||||
if (promptInput_ && g_Config.bBypassOSKWithKeyboard && !g_Config.UseFullScreen()) {
|
||||
System_InputBoxGetString(token_, n->T("Chat"), n->T("Chat Here"), [](const std::string &value, int) {
|
||||
System_InputBoxGetString(token_, n->T("Chat"), n->T("Chat Here"), false, [](const std::string &value, int) {
|
||||
sendChat(value);
|
||||
});
|
||||
promptInput_ = false;
|
||||
|
@ -1648,7 +1648,7 @@ 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, [](const std::string &value, int) {
|
||||
System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 1"), g_Config.sQuickChat0, false, [](const std::string &value, int) {
|
||||
g_Config.sQuickChat0 = value;
|
||||
});
|
||||
#endif
|
||||
@ -1658,7 +1658,7 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat0(UI::EventParams &e) {
|
||||
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, [](const std::string &value, int) {
|
||||
System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 2"), g_Config.sQuickChat1, false, [](const std::string &value, int) {
|
||||
g_Config.sQuickChat1 = value;
|
||||
});
|
||||
#endif
|
||||
@ -1668,7 +1668,7 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat1(UI::EventParams &e) {
|
||||
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, [](const std::string &value, int) {
|
||||
System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 3"), g_Config.sQuickChat2, false, [](const std::string &value, int) {
|
||||
g_Config.sQuickChat2 = value;
|
||||
});
|
||||
#endif
|
||||
@ -1678,7 +1678,7 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat2(UI::EventParams &e) {
|
||||
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, [](const std::string &value, int) {
|
||||
System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 4"), g_Config.sQuickChat3, false, [](const std::string &value, int) {
|
||||
g_Config.sQuickChat3 = value;
|
||||
});
|
||||
#endif
|
||||
@ -1688,7 +1688,7 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat3(UI::EventParams &e) {
|
||||
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, [](const std::string &value, int) {
|
||||
System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 5"), g_Config.sQuickChat4, false, [](const std::string &value, int) {
|
||||
g_Config.sQuickChat4 = value;
|
||||
});
|
||||
#endif
|
||||
@ -1698,7 +1698,7 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat4(UI::EventParams &e) {
|
||||
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, [](const std::string &value, int) {
|
||||
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
|
||||
@ -2325,7 +2325,7 @@ UI::EventReturn HostnameSelectScreen::OnDeleteAllClick(UI::EventParams &e) {
|
||||
|
||||
UI::EventReturn HostnameSelectScreen::OnEditClick(UI::EventParams& e) {
|
||||
auto n = GetI18NCategory(I18NCat::NETWORKING);
|
||||
System_InputBoxGetString(GetRequesterToken(), n->T("proAdhocServer Address:"), addrView_->GetText(), [this](const std::string& value, int) {
|
||||
System_InputBoxGetString(GetRequesterToken(), n->T("proAdhocServer Address:"), addrView_->GetText(), false, [this](const std::string& value, int) {
|
||||
addrView_->SetText(value);
|
||||
});
|
||||
return UI::EVENT_DONE;
|
||||
|
@ -237,7 +237,7 @@ void InstallZipScreen::update() {
|
||||
|
||||
if (existingSaveView_) {
|
||||
std::shared_ptr<GameInfo> ginfo = g_gameInfoCache->GetInfo(screenManager()->getDrawContext(), savedataToOverwrite_, GameInfoFlags::FILE_TYPE | GameInfoFlags::PARAM_SFO | GameInfoFlags::ICON | GameInfoFlags::SIZE);
|
||||
existingSaveView_->Update(ginfo.get());
|
||||
existingSaveView_->UpdateGame(ginfo.get());
|
||||
}
|
||||
UIDialogScreenWithBackground::update();
|
||||
}
|
||||
|
@ -344,7 +344,7 @@ void GameButton::Draw(UIContext &dc) {
|
||||
dc.PushScissor(bounds_);
|
||||
const std::string currentTitle = ginfo->GetTitle();
|
||||
if (!currentTitle.empty()) {
|
||||
title_ = ReplaceAll(title_, "\n", " ");
|
||||
title_ = ReplaceAll(currentTitle, "\n", " ");
|
||||
}
|
||||
|
||||
dc.MeasureText(dc.GetFontStyle(), 1.0f, 1.0f, title_, &tw, &th, 0);
|
||||
@ -798,7 +798,7 @@ void GameBrowser::Refresh() {
|
||||
if (System_GetPropertyInt(SYSPROP_DEVICE_TYPE) == DEVICE_TYPE_TV) {
|
||||
topBar->Add(new Choice(mm->T("Enter Path"), new LayoutParams(WRAP_CONTENT, 64.0f)))->OnClick.Add([=](UI::EventParams &) {
|
||||
auto mm = GetI18NCategory(I18NCat::MAINMENU);
|
||||
System_InputBoxGetString(token_, mm->T("Enter Path"), path_.GetPath().ToString(), [=](const char *responseString, int responseValue) {
|
||||
System_InputBoxGetString(token_, mm->T("Enter Path"), path_.GetPath().ToString(), false, [=](const char *responseString, int responseValue) {
|
||||
this->SetPath(Path(responseString));
|
||||
});
|
||||
return UI::EVENT_DONE;
|
||||
@ -1358,7 +1358,7 @@ bool MainScreen::key(const KeyInput &touch) {
|
||||
searchKeyModifier_ = true;
|
||||
if (touch.keyCode == NKCODE_F && searchKeyModifier_ && System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) {
|
||||
auto se = GetI18NCategory(I18NCat::SEARCH);
|
||||
System_InputBoxGetString(GetRequesterToken(), se->T("Search term"), searchFilter_, [&](const std::string &value, int) {
|
||||
System_InputBoxGetString(GetRequesterToken(), se->T("Search term"), searchFilter_, false, [&](const std::string &value, int) {
|
||||
searchFilter_ = StripSpaces(value);
|
||||
searchChanged_ = true;
|
||||
});
|
||||
|
@ -305,7 +305,7 @@ UI::EventReturn MemStickScreen::SetFolderManually(UI::EventParams ¶ms) {
|
||||
// The old way, from before scoped storage. Write in the full path.
|
||||
#if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH)
|
||||
auto sy = GetI18NCategory(I18NCat::SYSTEM);
|
||||
System_InputBoxGetString(GetRequesterToken(), sy->T("Memory Stick Folder"), g_Config.memStickDirectory.ToString(), [&](const std::string &value, int) {
|
||||
System_InputBoxGetString(GetRequesterToken(), sy->T("Memory Stick Folder"), g_Config.memStickDirectory.ToString(), false, [&](const std::string &value, int) {
|
||||
auto sy = GetI18NCategory(I18NCat::SYSTEM);
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
|
||||
|
@ -1536,22 +1536,24 @@ void NativeShutdown() {
|
||||
// In the future, we might make this more sophisticated, such as storing in the app private directory on Android.
|
||||
// Right now we just store secrets in separate files next to ppsspp.ini. The important thing is keeping them out of it
|
||||
// since we often ask people to post or send the ini for debugging.
|
||||
static Path GetSecretPath(const char *nameOfSecret) {
|
||||
static Path GetSecretPath(std::string_view nameOfSecret) {
|
||||
return GetSysDirectory(DIRECTORY_SYSTEM) / ("ppsspp_" + std::string(nameOfSecret) + ".dat");
|
||||
}
|
||||
|
||||
// name should be simple alphanumerics to avoid problems on Windows.
|
||||
bool NativeSaveSecret(const char *nameOfSecret, const std::string &data) {
|
||||
bool NativeSaveSecret(std::string_view nameOfSecret, std::string_view data) {
|
||||
Path path = GetSecretPath(nameOfSecret);
|
||||
if (!File::WriteDataToFile(false, data.data(), data.size(), path)) {
|
||||
WARN_LOG(Log::System, "Failed to write secret '%s' to path '%s'", nameOfSecret, path.c_str());
|
||||
if (data.empty() && File::Exists(path)) {
|
||||
return File::Delete(path);
|
||||
} else if (!File::WriteDataToFile(false, data.data(), data.size(), path)) {
|
||||
WARN_LOG(Log::System, "Failed to write secret '%.*s' to path '%s'", (int)nameOfSecret.size(), nameOfSecret.data(), path.c_str());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// On failure, returns an empty string. Good enough since any real secret is non-empty.
|
||||
std::string NativeLoadSecret(const char *nameOfSecret) {
|
||||
std::string NativeLoadSecret(std::string_view nameOfSecret) {
|
||||
Path path = GetSecretPath(nameOfSecret);
|
||||
std::string data;
|
||||
if (!File::ReadBinaryFileToString(path, &data)) {
|
||||
|
@ -92,7 +92,7 @@ SavedataView::SavedataView(UIContext &dc, const Path &savePath, IdentifiedFileTy
|
||||
}
|
||||
}
|
||||
|
||||
void SavedataView::Update(GameInfo *ginfo) {
|
||||
void SavedataView::UpdateGame(GameInfo *ginfo) {
|
||||
if (!ginfo->Ready(GameInfoFlags::PARAM_SFO | GameInfoFlags::SIZE)) {
|
||||
return;
|
||||
}
|
||||
@ -123,7 +123,7 @@ SavedataView::SavedataView(UIContext &dc, GameInfo *ginfo, IdentifiedFileType ty
|
||||
showIcon,
|
||||
layoutParams) {
|
||||
if (ginfo) {
|
||||
Update(ginfo);
|
||||
UpdateGame(ginfo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,7 +140,7 @@ public:
|
||||
return;
|
||||
}
|
||||
if (savedataView_) {
|
||||
savedataView_->Update(ginfo.get());
|
||||
savedataView_->UpdateGame(ginfo.get());
|
||||
}
|
||||
}
|
||||
|
||||
@ -670,7 +670,7 @@ UI::EventReturn SavedataScreen::OnSortClick(UI::EventParams &e) {
|
||||
UI::EventReturn SavedataScreen::OnSearch(UI::EventParams &e) {
|
||||
if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) {
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
System_InputBoxGetString(GetRequesterToken(), di->T("Filter"), searchFilter_, [](const std::string &value, int ivalue) {
|
||||
System_InputBoxGetString(GetRequesterToken(), di->T("Filter"), searchFilter_, false, [](const std::string &value, int ivalue) {
|
||||
System_PostUIMessage(UIMessage::SAVEDATA_SEARCH, value);
|
||||
});
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ public:
|
||||
SavedataView(UIContext &dc, GameInfo *ginfo, IdentifiedFileType type, bool showIcon, UI::LayoutParams *layoutParams = nullptr);
|
||||
SavedataView(UIContext &dc, const Path &savePath, IdentifiedFileType type, std::string_view title, std::string_view savedataTitle, std::string_view savedataDetail, std::string_view fileSize, std::string_view mtime, bool showIcon, UI::LayoutParams *layoutParams = nullptr);
|
||||
|
||||
void Update(GameInfo *ginfo);
|
||||
void UpdateGame(GameInfo *ginfo);
|
||||
private:
|
||||
UI::TextView *savedataTitle_ = nullptr;
|
||||
UI::TextView *detail_ = nullptr;
|
||||
|
@ -280,21 +280,22 @@ std::string trimString(std::string input)
|
||||
void CtrlDisAsmView::assembleOpcode(u32 address, const std::string &defaultText)
|
||||
{
|
||||
auto memLock = Memory::Lock();
|
||||
if (Core_IsStepping() == false) {
|
||||
if (!Core_IsStepping()) {
|
||||
MessageBox(wnd,L"Cannot change code while the core is running!",L"Error",MB_OK);
|
||||
return;
|
||||
}
|
||||
std::string op;
|
||||
bool result = InputBox_GetString(MainWindow::GetHInstance(),wnd,L"Assemble opcode",defaultText, op, false);
|
||||
if (!result)
|
||||
bool result = InputBox_GetString(MainWindow::GetHInstance(), wnd, L"Assemble opcode", defaultText, op, InputBoxFlags::Default);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check if it changes registers first
|
||||
auto seperator = op.find('=');
|
||||
if (seperator != std::string::npos)
|
||||
auto separator = op.find('=');
|
||||
if (separator != std::string::npos)
|
||||
{
|
||||
std::string registerName = trimString(op.substr(0,seperator));
|
||||
std::string expression = trimString(op.substr(seperator+1));
|
||||
std::string registerName = trimString(op.substr(0,separator));
|
||||
std::string expression = trimString(op.substr(separator+1));
|
||||
|
||||
u32 value;
|
||||
if (parseExpression(expression.c_str(),debugger,value) == true)
|
||||
|
@ -18,7 +18,7 @@ void displayExpressionError(HWND hwnd)
|
||||
bool executeExpressionWindow(HWND hwnd, DebugInterface* cpu, u32& dest)
|
||||
{
|
||||
std::string expression;
|
||||
if (InputBox_GetString(GetModuleHandle(NULL), hwnd, L"Expression", "",expression) == false)
|
||||
if (InputBox_GetString(GetModuleHandle(NULL), hwnd, L"Expression", "", expression) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -30,4 +30,4 @@ bool executeExpressionWindow(HWND hwnd, DebugInterface* cpu, u32& dest)
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ void CtrlDisplayListView::onMouseUp(WPARAM wParam, LPARAM lParam, int button)
|
||||
case ID_GEDBG_GOTOADDR:
|
||||
{
|
||||
std::string expression = StringFromFormat("%08x", curAddress);
|
||||
if (!InputBox_GetString(GetModuleHandle(NULL), wnd, L"Address", expression, expression, true)) {
|
||||
if (!InputBox_GetString(GetModuleHandle(NULL), wnd, L"Address", expression, expression, InputBoxFlags::Selected)) {
|
||||
break;
|
||||
}
|
||||
uint32_t newAddress = curAddress;
|
||||
|
@ -348,6 +348,7 @@ void CGEDebugger::UpdatePrimPreview(u32 op, int which) {
|
||||
u16 minIndex = 0;
|
||||
u16 maxIndex = count - 1;
|
||||
if (!indices.empty()) {
|
||||
_dbg_assert_(count <= indices.size());
|
||||
minIndex = 0xFFFF;
|
||||
maxIndex = 0;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
|
@ -6,31 +6,45 @@
|
||||
#include "Windows/W32Util/Misc.h"
|
||||
#include "Common/Data/Encoding/Utf8.h"
|
||||
|
||||
static std::wstring textBoxContents;
|
||||
static std::wstring passwordContents;
|
||||
static std::wstring out;
|
||||
static std::wstring windowTitle;
|
||||
static bool defaultSelected;
|
||||
static std::string g_userName;
|
||||
static std::string g_passWord;
|
||||
struct DialogBoxParams {
|
||||
std::wstring textBoxContents;
|
||||
std::wstring passwordContents;
|
||||
std::wstring out;
|
||||
std::wstring windowTitle;
|
||||
bool defaultSelected;
|
||||
bool passwordMasking;
|
||||
std::string userName;
|
||||
std::string passWord;
|
||||
};
|
||||
|
||||
static DialogBoxParams g_params;
|
||||
|
||||
static INT_PTR CALLBACK InputBoxFunc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_INITDIALOG:
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_INPUTBOX), textBoxContents.c_str());
|
||||
SetWindowText(hDlg, windowTitle.c_str());
|
||||
if (defaultSelected == false)
|
||||
PostMessage(GetDlgItem(hDlg,IDC_INPUTBOX),EM_SETSEL,-1,-1);
|
||||
{
|
||||
HWND hwndTextBox = GetDlgItem(hDlg, IDC_INPUTBOX);
|
||||
SetWindowText(hwndTextBox, g_params.textBoxContents.c_str());
|
||||
SetWindowText(hDlg, g_params.windowTitle.c_str());
|
||||
if (!g_params.defaultSelected) {
|
||||
PostMessage(hwndTextBox, EM_SETSEL, -1, -1);
|
||||
}
|
||||
if (g_params.passwordMasking) {
|
||||
LONG_PTR style = GetWindowLongPtr(hwndTextBox, GWL_STYLE);
|
||||
SetWindowLongPtr(hwndTextBox, GWL_STYLE, style | ES_PASSWORD);
|
||||
SendMessage(hwndTextBox, EM_SETPASSWORDCHAR, (WPARAM)'*', 0);
|
||||
}
|
||||
W32Util::CenterWindow(hDlg);
|
||||
return TRUE;
|
||||
}
|
||||
case WM_COMMAND:
|
||||
switch (wParam) {
|
||||
case IDOK:
|
||||
{
|
||||
wchar_t temp[512];
|
||||
GetWindowText(GetDlgItem(hDlg, IDC_INPUTBOX), temp, ARRAY_SIZE(temp) - 1);
|
||||
out = temp;
|
||||
GetWindowText(GetDlgItem(hDlg, IDC_INPUTBOX), temp, ARRAY_SIZE(temp));
|
||||
g_params.out = temp;
|
||||
EndDialog(hDlg, IDOK);
|
||||
return TRUE;
|
||||
}
|
||||
@ -45,97 +59,55 @@ static INT_PTR CALLBACK InputBoxFunc(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||
}
|
||||
}
|
||||
|
||||
bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultValue, std::string &outvalue, bool selected)
|
||||
{
|
||||
defaultSelected = selected;
|
||||
if (defaultValue.size() < 255)
|
||||
textBoxContents = ConvertUTF8ToWString(defaultValue);
|
||||
else
|
||||
textBoxContents.clear();
|
||||
|
||||
if (title != NULL)
|
||||
windowTitle = title;
|
||||
else
|
||||
windowTitle.clear();
|
||||
|
||||
if (IDOK == DialogBox(hInst, (LPCWSTR)IDD_INPUTBOX, hParent, InputBoxFunc)) {
|
||||
outvalue = ConvertWStringToUTF8(out);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultValue, std::string &outvalue)
|
||||
{
|
||||
bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultValue, std::string &outvalue, InputBoxFlags flags) {
|
||||
const wchar_t *defaultTitle = L"Input value";
|
||||
defaultSelected = true;
|
||||
|
||||
textBoxContents = ConvertUTF8ToWString(defaultValue);
|
||||
g_params.defaultSelected = flags & InputBoxFlags::Selected;
|
||||
g_params.passwordMasking = flags & InputBoxFlags::PasswordMasking;
|
||||
if (defaultValue.size() < 255) {
|
||||
g_params.textBoxContents = ConvertUTF8ToWString(defaultValue);
|
||||
} else {
|
||||
g_params.textBoxContents.clear();
|
||||
}
|
||||
|
||||
if (title && wcslen(title) <= 0)
|
||||
windowTitle = defaultTitle;
|
||||
else if (title && wcslen(title) < 255)
|
||||
windowTitle = title;
|
||||
else
|
||||
windowTitle = defaultTitle;
|
||||
if (title && wcslen(title) <= 0) {
|
||||
g_params.windowTitle = defaultTitle;
|
||||
} else if (title && wcslen(title) < 255) {
|
||||
g_params.windowTitle = title;
|
||||
} else {
|
||||
g_params.windowTitle = defaultTitle;
|
||||
}
|
||||
|
||||
if (IDOK == DialogBox(hInst, (LPCWSTR)IDD_INPUTBOX, hParent, InputBoxFunc)) {
|
||||
outvalue = ConvertWStringToUTF8(out);
|
||||
outvalue = ConvertWStringToUTF8(g_params.out);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool InputBox_GetWString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::wstring &defaultValue, std::wstring &outvalue)
|
||||
{
|
||||
const wchar_t *defaultTitle = L"Input value";
|
||||
defaultSelected = true;
|
||||
|
||||
textBoxContents = defaultValue;
|
||||
|
||||
if (title && wcslen(title) <= 0)
|
||||
windowTitle = defaultTitle;
|
||||
else if (title && wcslen(title) < 255)
|
||||
windowTitle = title;
|
||||
else
|
||||
windowTitle = defaultTitle;
|
||||
|
||||
if (IDOK == DialogBox(hInst, (LPCWSTR)IDD_INPUTBOX, hParent, InputBoxFunc)) {
|
||||
outvalue = out;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t* title, u32 defaultvalue, u32& outvalue)
|
||||
{
|
||||
bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t* title, u32 defaultvalue, u32 &outvalue) {
|
||||
const wchar_t *defaultTitle = L"Input value";
|
||||
wchar_t temp[256];
|
||||
wsprintf(temp, L"%08x", defaultvalue);
|
||||
textBoxContents = temp;
|
||||
g_params.textBoxContents = temp;
|
||||
|
||||
if (title && wcslen(title) <= 0)
|
||||
windowTitle = defaultTitle;
|
||||
g_params.windowTitle = defaultTitle;
|
||||
else if (title && wcslen(title) < 255)
|
||||
windowTitle = title;
|
||||
g_params.windowTitle = title;
|
||||
else
|
||||
windowTitle = defaultTitle;
|
||||
g_params.windowTitle = defaultTitle;
|
||||
|
||||
INT_PTR value = DialogBox(hInst, (LPCWSTR)IDD_INPUTBOX, hParent, InputBoxFunc);
|
||||
|
||||
if (value == IDOK)
|
||||
{
|
||||
if (swscanf(out.c_str(), L"0x%08x", &outvalue) == 1)
|
||||
if (value == IDOK) {
|
||||
if (swscanf(g_params.out.c_str(), L"0x%08x", &outvalue) == 1)
|
||||
return true;
|
||||
if (swscanf(out.c_str(), L"%08x", &outvalue) == 1)
|
||||
if (swscanf(g_params.out.c_str(), L"%08x", &outvalue) == 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
outvalue = 0;
|
||||
return false;
|
||||
}
|
||||
@ -147,7 +119,7 @@ static INT_PTR CALLBACK UserPasswordBoxFunc(HWND hDlg, UINT message, WPARAM wPar
|
||||
case WM_INITDIALOG:
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_INPUTBOX), L"");
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_PASSWORDBOX), L"");
|
||||
SetWindowText(hDlg, windowTitle.c_str());
|
||||
SetWindowText(hDlg, g_params.windowTitle.c_str());
|
||||
PostMessage(GetDlgItem(hDlg, IDC_INPUTBOX), EM_SETSEL, -1, -1);
|
||||
PostMessage(GetDlgItem(hDlg, IDC_PASSWORDBOX), EM_SETSEL, -1, -1);
|
||||
W32Util::CenterWindow(hDlg);
|
||||
@ -158,10 +130,10 @@ static INT_PTR CALLBACK UserPasswordBoxFunc(HWND hDlg, UINT message, WPARAM wPar
|
||||
case IDOK:
|
||||
{
|
||||
wchar_t temp[256];
|
||||
GetWindowText(GetDlgItem(hDlg, IDC_INPUTBOX), temp, 255);
|
||||
g_userName = ConvertWStringToUTF8(temp);
|
||||
GetWindowText(GetDlgItem(hDlg, IDC_PASSWORDBOX), temp, 255);
|
||||
g_passWord = ConvertWStringToUTF8(temp);
|
||||
GetWindowText(GetDlgItem(hDlg, IDC_INPUTBOX), temp, sizeof(temp));
|
||||
g_params.userName = ConvertWStringToUTF8(temp);
|
||||
GetWindowText(GetDlgItem(hDlg, IDC_PASSWORDBOX), temp, sizeof(temp));
|
||||
g_params.passWord = ConvertWStringToUTF8(temp);
|
||||
EndDialog(hDlg, IDOK);
|
||||
return TRUE;
|
||||
}
|
||||
@ -177,12 +149,12 @@ static INT_PTR CALLBACK UserPasswordBoxFunc(HWND hDlg, UINT message, WPARAM wPar
|
||||
}
|
||||
|
||||
bool UserPasswordBox_GetStrings(HINSTANCE hInst, HWND hParent, const wchar_t *title, std::string *username, std::string *password) {
|
||||
windowTitle = title;
|
||||
g_params.windowTitle = title;
|
||||
INT_PTR value = DialogBox(hInst, (LPCWSTR)IDD_USERPASSWORDBOX, hParent, UserPasswordBoxFunc);
|
||||
|
||||
if (value == IDOK) {
|
||||
*username = g_userName;
|
||||
*password = g_passWord;
|
||||
*username = g_params.userName;
|
||||
*password = g_params.passWord;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -2,11 +2,17 @@
|
||||
|
||||
#include <string>
|
||||
#include "Common/CommonWindows.h"
|
||||
#include "Common/Common.h"
|
||||
|
||||
enum class InputBoxFlags {
|
||||
Default = 0,
|
||||
Selected = 1,
|
||||
PasswordMasking = 2,
|
||||
};
|
||||
ENUM_CLASS_BITOPS(InputBoxFlags);
|
||||
|
||||
// All I/O is in UTF-8
|
||||
bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultvalue, std::string &outvalue, bool selected);
|
||||
bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultvalue, std::string &outvalue);
|
||||
bool InputBox_GetWString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::wstring &defaultvalue, std::wstring &outvalue);
|
||||
bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultvalue, std::string &outvalue, InputBoxFlags flags = InputBoxFlags::Default);
|
||||
bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t *title, u32 defaultvalue, u32 &outvalue);
|
||||
|
||||
bool UserPasswordBox_GetStrings(HINSTANCE hInst, HWND hParent, const wchar_t *title, std::string *username, std::string *password);
|
||||
|
@ -540,7 +540,14 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string
|
||||
case SystemRequestType::INPUT_TEXT_MODAL:
|
||||
std::thread([=] {
|
||||
std::string out;
|
||||
if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), ConvertUTF8ToWString(param1).c_str(), param2, out)) {
|
||||
InputBoxFlags flags{};
|
||||
if (param3) {
|
||||
flags |= InputBoxFlags::PasswordMasking;
|
||||
}
|
||||
if (!param2.empty()) {
|
||||
flags |= InputBoxFlags::Selected;
|
||||
}
|
||||
if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), ConvertUTF8ToWString(param1).c_str(), param2, out, flags)) {
|
||||
g_requestManager.PostSystemSuccess(requestId, out.c_str());
|
||||
} else {
|
||||
g_requestManager.PostSystemFailure(requestId);
|
||||
|
@ -142,8 +142,8 @@ void System_AudioClear() {}
|
||||
void System_AudioPushSamples(const s32 *audio, int numSamples) {}
|
||||
|
||||
// TODO: To avoid having to define these here, these should probably be turned into system "requests".
|
||||
bool NativeSaveSecret(const char *nameOfSecret, const std::string &data) { return false; }
|
||||
std::string NativeLoadSecret(const char *nameOfSecret) {
|
||||
bool NativeSaveSecret(std::string_view nameOfSecret, std::string_view data) { return false; }
|
||||
std::string NativeLoadSecret(std::string_view nameOfSecret) {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@ -1962,7 +1962,7 @@ bool System_AudioRecordingState() { return false; }
|
||||
#endif
|
||||
|
||||
// TODO: To avoid having to define these here, these should probably be turned into system "requests".
|
||||
bool NativeSaveSecret(const char *nameOfSecret, const std::string &data) { return false; }
|
||||
std::string NativeLoadSecret(const char *nameOfSecret) {
|
||||
bool NativeSaveSecret(std::string_view nameOfSecret, std::string_view data) { return false; }
|
||||
std::string NativeLoadSecret(std::string_view nameOfSecret) {
|
||||
return "";
|
||||
}
|
||||
|
@ -108,8 +108,9 @@ void System_AudioClear() {}
|
||||
void System_AudioPushSamples(const s32 *audio, int numSamples) {}
|
||||
|
||||
// TODO: To avoid having to define these here, these should probably be turned into system "requests".
|
||||
bool NativeSaveSecret(const char *nameOfSecret, const std::string &data) { return false; }
|
||||
std::string NativeLoadSecret(const char *nameOfSecret) {
|
||||
// To clear the secret entirely, just save an empty string.
|
||||
bool NativeSaveSecret(std::string_view nameOfSecret, std::string_view data) { return false; }
|
||||
std::string NativeLoadSecret(std::string_view nameOfSecret) {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user