Skip to content
Permalink
Browse files

Merge pull request #11132 from unknownbrackets/reporting

 Reporting: Provide suggestions on negative compat reports
  • Loading branch information...
hrydgard committed Jun 6, 2018
2 parents 67fec95 + cb0838f commit 3d12f9acc2045c1724d1824252cda2be2acb59b7
Showing with 113 additions and 24 deletions.
  1. +14 −5 Core/Reporting.cpp
  2. +4 −0 Core/Reporting.h
  3. +88 −16 UI/ReportScreen.cpp
  4. +7 −3 UI/ReportScreen.h
@@ -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<std::string> 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<std::string> CompatibilitySuggestions() {
return lastCompatResult;
}
}
@@ -20,6 +20,7 @@
#include "Common/CommonTypes.h"
#include "Common/Log.h"
#include <string>
#include <vector>

#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<std::string> CompatibilitySuggestions();

// Returns true if that identifier has not been logged yet.
bool ShouldLogOnce(const char *identifier);

@@ -17,6 +17,8 @@

#include <string>
#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);
@@ -170,6 +172,11 @@ void ReportScreen::update() {
UIDialogScreenWithGameBackground::update();
}

void ReportScreen::resized() {
UIDialogScreenWithGameBackground::resized();
RecreateViews();
}

EventReturn ReportScreen::HandleChoice(EventParams &e) {
if (overall_ == ReportingOverallScore::NONE) {
graphics_ = 0;
@@ -218,14 +225,15 @@ void ReportScreen::CreateViews() {

Margins actionMenuMargins(0, 20, 15, 0);
Margins contentMargins(0, 20, 5, 5);
float leftColumnWidth = dp_xres - actionMenuMargins.horiz() - contentMargins.horiz() - 300.0f;
ViewGroup *leftColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(WRAP_CONTENT, FILL_PARENT, 0.4f, contentMargins));
LinearLayout *leftColumnItems = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(WRAP_CONTENT, FILL_PARENT));
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")));
@@ -237,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

@@ -257,11 +268,15 @@ 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);
leftColumnItems->Add(new RatingChoice("Graphics", &graphics_))->SetEnabledPtr(&ratingEnabled_)->OnChoice.Handle(this, &ReportScreen::HandleChoice);
leftColumnItems->Add(new RatingChoice("Speed", &speed_))->SetEnabledPtr(&ratingEnabled_)->OnChoice.Handle(this, &ReportScreen::HandleChoice);
leftColumnItems->Add(new RatingChoice("Gameplay", &gameplay_))->SetEnabledPtr(&ratingEnabled_)->OnChoice.Handle(this, &ReportScreen::HandleChoice);

UI::Orientation ratingsOrient = leftColumnWidth >= 750.0f ? ORIENT_HORIZONTAL : ORIENT_VERTICAL;
UI::LinearLayout *ratingsHolder = new LinearLayout(ratingsOrient, new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT));
leftColumnItems->Add(ratingsHolder);
ratingsHolder->Add(new RatingChoice("Graphics", &graphics_))->SetEnabledPtr(&ratingEnabled_)->OnChoice.Handle(this, &ReportScreen::HandleChoice);
ratingsHolder->Add(new RatingChoice("Speed", &speed_))->SetEnabledPtr(&ratingEnabled_)->OnChoice.Handle(this, &ReportScreen::HandleChoice);
ratingsHolder->Add(new RatingChoice("Gameplay", &gameplay_))->SetEnabledPtr(&ratingEnabled_)->OnChoice.Handle(this, &ReportScreen::HandleChoice);

rightColumnItems->SetSpacing(0.0f);
rightColumnItems->Add(new Choice(rp->T("Open Browser")))->OnClick.Handle(this, &ReportScreen::HandleBrowser);
@@ -288,16 +303,18 @@ void ReportScreen::UpdateSubmit() {
void ReportScreen::UpdateOverallDescription() {
I18NCategory *rp = GetI18NCategory("Reporting");
const char *desc;
uint32_t c = 0xFFFFFFFF;
switch (overall_) {
case ReportingOverallScore::PERFECT: desc = rp->T("Perfect Description", "Flawless emulation for the entire game - great!"); break;
case ReportingOverallScore::PLAYABLE: desc = rp->T("Plays Description", "Fully playable but might be with glitches"); break;
case ReportingOverallScore::INGAME: desc = rp->T("In-game Description", "Gets into gameplay, but too buggy too complete"); break;
case ReportingOverallScore::INGAME: desc = rp->T("In-game Description", "Gets into gameplay, but too buggy to complete"); break;
case ReportingOverallScore::MENU: desc = rp->T("Menu/Intro Description", "Can't get into the game itself"); break;
case ReportingOverallScore::NONE: desc = rp->T("Nothing Description", "Completely broken"); break;
case ReportingOverallScore::NONE: desc = rp->T("Nothing Description", "Completely broken"); c = 0xFF0000FF; break;
default: desc = rp->T("Unselected Overall Description", "How well does this game emulate?"); break;
}

overallDescription_->SetText(desc);
overallDescription_->SetTextColor(c);
}

EventReturn ReportScreen::HandleSubmit(EventParams &e) {
@@ -319,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;
}

@@ -329,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() {
@@ -344,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);
@@ -368,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:
@@ -385,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());
@@ -38,6 +38,7 @@ class ReportScreen : public UIDialogScreenWithGameBackground {

protected:
void update() override;
void resized() override;
void CreateViews() override;
void UpdateSubmit();
void UpdateOverallDescription();
@@ -64,14 +65,17 @@ class ReportScreen : public UIDialogScreenWithGameBackground {

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;
};

0 comments on commit 3d12f9a

Please sign in to comment.
You can’t perform that action at this time.