From 4cbfb4aa98f05cda39f5287ed0b47de03c1847c8 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 3 Jun 2018 14:47:49 -0700 Subject: [PATCH] Reporting: Provide suggestions on negative reports. Based on other reports, try suggesting settings to change or actions to take. Fairly rudimentary currently. --- Core/Reporting.cpp | 19 ++++++++--- Core/Reporting.h | 4 +++ UI/ReportScreen.cpp | 82 +++++++++++++++++++++++++++++++++++++++------ UI/ReportScreen.h | 9 +++-- 4 files changed, 95 insertions(+), 19 deletions(-) diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index 02503301d..a927c5551 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -67,6 +67,8 @@ namespace Reporting static bool currentSupported = false; // Whether the most recent server request seemed successful. static bool serverWorking = true; + // The latest compatibility result from the server. + static std::vector lastCompatResult; enum class RequestType { @@ -423,6 +425,7 @@ namespace Reporting postdata.Add("speed", StringFromFormat("%d", payload.int2)); postdata.Add("gameplay", StringFromFormat("%d", payload.int3)); postdata.Add("crc", StringFromFormat("%08x", Core_GetPowerSaving() ? 0 : RetrieveCRC())); + postdata.Add("suggestions", payload.string1 != "perfect" && payload.string1 != "playable" ? "1" : "0"); AddScreenshotData(postdata, payload.string2); payload.string1.clear(); payload.string2.clear(); @@ -432,12 +435,14 @@ namespace Reporting if (!SendReportRequest("/report/compat", postdata.ToString(), postdata.GetMimeType(), &output)) { serverWorking = false; } else { - char res = 0; - if (!output.empty()) { - output.Take(1, &res); - } - if (res == 0) + std::string result; + output.TakeAll(&result); + + lastCompatResult.clear(); + if (result.empty() || result[0] == '0') serverWorking = false; + else if (result[0] != '1') + SplitString(result, '\n', lastCompatResult); } break; @@ -594,4 +599,8 @@ namespace Reporting std::thread th(Process, pos); th.detach(); } + + std::vector CompatibilitySuggestions() { + return lastCompatResult; + } } diff --git a/Core/Reporting.h b/Core/Reporting.h index 08acc9d26..c34f81511 100644 --- a/Core/Reporting.h +++ b/Core/Reporting.h @@ -20,6 +20,7 @@ #include "Common/CommonTypes.h" #include "Common/Log.h" #include +#include #define DEBUG_LOG_REPORT(t,...) do { DEBUG_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); } while (false) #define ERROR_LOG_REPORT(t,...) do { ERROR_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); } while (false) @@ -74,6 +75,9 @@ namespace Reporting // Report the compatibility of the current game / configuration. void ReportCompatibility(const char *compat, int graphics, int speed, int gameplay, const std::string &screenshotFilename); + // Get the latest compatibility result. Only valid when GetStatus() is not BUSY. + std::vector CompatibilitySuggestions(); + // Returns true if that identifier has not been logged yet. bool ShouldLogOnce(const char *identifier); diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp index f1c00a5e2..70c92cf26 100644 --- a/UI/ReportScreen.cpp +++ b/UI/ReportScreen.cpp @@ -17,6 +17,8 @@ #include #include "base/display.h" +// TODO: For text align flags, probably shouldn';t be in gfx_es2/... +#include "gfx_es2/draw_buffer.h" #include "i18n/i18n.h" #include "thin3d/thin3d.h" #include "ui/ui_context.h" @@ -66,7 +68,7 @@ RatingChoice::RatingChoice(const char *captionKey, int *value, LayoutParams *lay I18NCategory *rp = GetI18NCategory("Reporting"); group_ = new LinearLayout(ORIENT_HORIZONTAL); - Add(new TextView(rp->T(captionKey)))->SetShadow(true); + Add(new TextView(rp->T(captionKey), FLAG_WRAP_TEXT, false))->SetShadow(true); Add(group_); group_->SetSpacing(0.0f); @@ -229,9 +231,9 @@ void ReportScreen::CreateViews() { ViewGroup *rightColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(300, FILL_PARENT, actionMenuMargins)); LinearLayout *rightColumnItems = new LinearLayout(ORIENT_VERTICAL); - leftColumnItems->Add(new TextView(rp->T("FeedbackDesc", "How's the emulation? Let us and the community know!"), new LinearLayoutParams(Margins(12, 5, 0, 5))))->SetShadow(true); + leftColumnItems->Add(new TextView(rp->T("FeedbackDesc", "How's the emulation? Let us and the community know!"), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5))))->SetShadow(true); if (!Reporting::IsEnabled()) { - reportingNotice_ = leftColumnItems->Add(new TextView(rp->T("FeedbackDisabled", "Compatibility server reports must be enabled."), new LinearLayoutParams(Margins(12, 5, 0, 5)))); + reportingNotice_ = leftColumnItems->Add(new TextView(rp->T("FeedbackDisabled", "Compatibility server reports must be enabled."), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5)))); reportingNotice_->SetShadow(true); reportingNotice_->SetTextColor(0xFF3030FF); CheckBox *reporting = leftColumnItems->Add(new CheckBox(&enableReporting_, sy->T("Enable Compatibility Server Reports"))); @@ -243,7 +245,10 @@ void ReportScreen::CreateViews() { #ifdef MOBILE_DEVICE if (!Core_GetPowerSaving()) { - leftColumnItems->Add(new TextView(rp->T("FeedbackIncludeCRC", "Note: Battery will be used to send a disc CRC"), new LinearLayoutParams(Margins(12, 5, 0, 5))))->SetEnabledPtr(&enableReporting_); + auto crcWarning = new TextView(rp->T("FeedbackIncludeCRC", "Note: Battery will be used to send a disc CRC"), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5))); + crcWarning->SetShadow(true); + crcWarning->SetEnabledPtr(&enableReporting_); + leftColumnItems->Add(crcWarning); } #endif @@ -263,7 +268,7 @@ void ReportScreen::CreateViews() { } leftColumnItems->Add(new CompatRatingChoice("Overall", (int *)&overall_))->SetEnabledPtr(&enableReporting_)->OnChoice.Handle(this, &ReportScreen::HandleChoice); - overallDescription_ = leftColumnItems->Add(new TextView("", new LinearLayoutParams(Margins(10, 0)))); + overallDescription_ = leftColumnItems->Add(new TextView("", FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(10, 0)))); overallDescription_->SetShadow(true); UI::Orientation ratingsOrient = leftColumnWidth >= 750.0f ? ORIENT_HORIZONTAL : ORIENT_VERTICAL; @@ -331,7 +336,7 @@ EventReturn ReportScreen::HandleSubmit(EventParams &e) { std::string filename = includeScreenshot_ ? screenshotFilename_ : ""; Reporting::ReportCompatibility(compat, graphics_ + 1, speed_ + 1, gameplay_ + 1, filename); TriggerFinish(DR_OK); - screenManager()->push(new ReportFinishScreen(gamePath_)); + screenManager()->push(new ReportFinishScreen(gamePath_, overall_)); return EVENT_DONE; } @@ -341,8 +346,8 @@ EventReturn ReportScreen::HandleBrowser(EventParams &e) { return EVENT_DONE; } -ReportFinishScreen::ReportFinishScreen(const std::string &gamePath) - : UIDialogScreenWithGameBackground(gamePath), resultNotice_(nullptr), setStatus_(false) { +ReportFinishScreen::ReportFinishScreen(const std::string &gamePath, ReportingOverallScore score) + : UIDialogScreenWithGameBackground(gamePath), score_(score) { } void ReportFinishScreen::CreateViews() { @@ -356,8 +361,15 @@ void ReportFinishScreen::CreateViews() { ViewGroup *rightColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(300, FILL_PARENT, actionMenuMargins)); LinearLayout *rightColumnItems = new LinearLayout(ORIENT_VERTICAL); - leftColumnItems->Add(new TextView(rp->T("FeedbackThanks", "Thanks for your feedback."), new LinearLayoutParams(Margins(12, 5, 0, 5)))); - resultNotice_ = leftColumnItems->Add(new TextView(rp->T("FeedbackDelayInfo", "Your data is being submitted in the background."), new LinearLayoutParams(Margins(12, 5, 0, 5)))); + leftColumnItems->Add(new TextView(rp->T("FeedbackThanks", "Thanks for your feedback."), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5))))->SetShadow(true); + if (score_ == ReportingOverallScore::PERFECT || score_ == ReportingOverallScore::PLAYABLE) { + resultNotice_ = leftColumnItems->Add(new TextView(rp->T("FeedbackDelayInfo", "Your data is being submitted in the background."), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5)))); + } else { + resultNotice_ = leftColumnItems->Add(new TextView(rp->T("SuggestionsWaiting", "Submitting and checking other user feedback.."), FLAG_WRAP_TEXT, false, new LinearLayoutParams(Margins(12, 5, 0, 5)))); + } + resultNotice_->SetShadow(true); + resultItems_ = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, Margins(12, 5, 0, 5))); + leftColumnItems->Add(resultItems_); rightColumnItems->SetSpacing(0.0f); rightColumnItems->Add(new Choice(rp->T("View Feedback")))->OnClick.Handle(this, &ReportFinishScreen::HandleViewFeedback); @@ -380,11 +392,13 @@ void ReportFinishScreen::update() { Reporting::ReportStatus status = Reporting::GetStatus(); switch (status) { case Reporting::ReportStatus::WORKING: - resultNotice_->SetText(rp->T("FeedbackSubmitDone", "Your data has been submitted.")); + ShowSuggestions(); + setStatus_ = true; break; case Reporting::ReportStatus::FAILING: resultNotice_->SetText(rp->T("FeedbackSubmitFail", "Could not submit data to server. Try updating PPSSPP.")); + setStatus_ = true; break; case Reporting::ReportStatus::BUSY: @@ -397,6 +411,52 @@ void ReportFinishScreen::update() { UIDialogScreenWithGameBackground::update(); } +void ReportFinishScreen::ShowSuggestions() { + I18NCategory *rp = GetI18NCategory("Reporting"); + + auto suggestions = Reporting::CompatibilitySuggestions(); + if (score_ == ReportingOverallScore::PERFECT || score_ == ReportingOverallScore::PLAYABLE) { + resultNotice_->SetText(rp->T("FeedbackSubmitDone", "Your data has been submitted.")); + } else if (suggestions.empty()) { + resultNotice_->SetText(rp->T("SuggestionsNone", "This game isn't working for other users too.")); + } else { + resultNotice_->SetText(rp->T("SuggestionsFound", "Other users have reported better results. Tap View Feedback for more detail.")); + + resultItems_->Clear(); + bool shownConfig = false; + bool valid = false; + for (auto item : suggestions) { + const char *suggestion = nullptr; + if (item == "Upgrade") { + suggestion = rp->T("SuggestionUpgrade", "Upgrade to a newer PPSSPP build"); + } if (item == "Downgrade") { + suggestion = rp->T("SuggestionDowngrade", "Downgrade to an older PPSSPP version (please report this bug)"); + } else if (item == "VerifyDisc") { + suggestion = rp->T("SuggestionVerifyDisc", "Check your ISO is a good copy of your disc"); + } else if (item == "Config:CPUSpeed:0") { + suggestion = rp->T("SuggestionCPUSpeed0", "Disable locked CPU speed setting"); + } else { + bool isConfig = startsWith(item, "Config:"); + if (isConfig && !shownConfig) { + suggestion = rp->T("SuggestionConfig", "See reports on website for good settings"); + shownConfig = true; + } + // Ignore unknown configs, hopefully we recognized "Upgrade" at least. + } + + if (suggestion) { + valid = true; + resultItems_->Add(new TextView(std::string(" - ") + suggestion, FLAG_WRAP_TEXT, false))->SetShadow(true); + } + } + + if (!valid) { + // No actual valid versions. Let's just say upgrade and hope the server's not broken. + resultItems_->Add(new TextView(std::string(" - ") + rp->T("SuggestionUpgrade", "Upgrade to a newer PPSSPP build"), FLAG_WRAP_TEXT, false))->SetShadow(true); + } + } +} + UI::EventReturn ReportFinishScreen::HandleViewFeedback(UI::EventParams &e) { const std::string url = "http://" + Reporting::ServerHost() + "/game/" + Reporting::CurrentGameID(); LaunchBrowser(url.c_str()); diff --git a/UI/ReportScreen.h b/UI/ReportScreen.h index 40eed81b6..18c0d2b93 100644 --- a/UI/ReportScreen.h +++ b/UI/ReportScreen.h @@ -65,14 +65,17 @@ protected: class ReportFinishScreen : public UIDialogScreenWithGameBackground { public: - ReportFinishScreen(const std::string &gamePath); + ReportFinishScreen(const std::string &gamePath, ReportingOverallScore score); protected: void update() override; void CreateViews() override; + void ShowSuggestions(); UI::EventReturn HandleViewFeedback(UI::EventParams &e); - UI::TextView *resultNotice_; - bool setStatus_; + UI::TextView *resultNotice_ = nullptr; + UI::LinearLayout *resultItems_ = nullptr; + ReportingOverallScore score_; + bool setStatus_ = false; };