From 89fe5dab825a62a0e3fd8d248cbc91c65eb2a426 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Fri, 15 Aug 2008 23:44:50 -0500 Subject: Second Life viewer sources 1.14.0.0 --- linden/indra/newview/llfloaterreporter.cpp | 438 ++++++++++++++++++----------- 1 file changed, 268 insertions(+), 170 deletions(-) (limited to 'linden/indra/newview/llfloaterreporter.cpp') diff --git a/linden/indra/newview/llfloaterreporter.cpp b/linden/indra/newview/llfloaterreporter.cpp index 116b338..0337dd0 100644 --- a/linden/indra/newview/llfloaterreporter.cpp +++ b/linden/indra/newview/llfloaterreporter.cpp @@ -63,6 +63,7 @@ #include "lltooldraganddrop.h" #include "llfloatermap.h" #include "lluiconstants.h" +#include "lluploaddialog.h" #include "llcallingcard.h" #include "llviewerobjectlist.h" #include "llagent.h" @@ -80,6 +81,7 @@ #include "llvieweruictrlfactory.h" #include "viewer.h" +#include "llassetuploadresponders.h" const U32 INCLUDE_SCREENSHOT = 0x01 << 0; @@ -115,7 +117,8 @@ LLFloaterReporter::LLFloaterReporter( mDeselectOnClose( FALSE ), mPicking( FALSE), mPosition(), - mCopyrightWarningSeen( FALSE ) + mCopyrightWarningSeen( FALSE ), + mResourceDatap(new LLResourceData()) { if (report_type == BUG_REPORT) { @@ -166,9 +169,9 @@ LLFloaterReporter::LLFloaterReporter( gReporterInstances.addData(report_type, this); - // Upload a screenshot, but don't draw this floater. + // Take a screenshot, but don't draw this floater. setVisible(FALSE); - uploadScreenshot(); + takeScreenshot(); setVisible(TRUE); // Default text to be blank @@ -230,11 +233,7 @@ LLFloaterReporter::~LLFloaterReporter() std::for_each(mMCDList.begin(), mMCDList.end(), DeletePointer() ); mMCDList.clear(); - if (gSelectMgr) - { - gSelectMgr->deselectTransient(); - } - + delete mResourceDatap; gDialogVisible = FALSE; } @@ -368,7 +367,7 @@ void LLFloaterReporter::callbackAvatarID(const std::vector& names, if ( self->mReportType != BUG_REPORT ) { self->childSetText("abuser_name_edit", names[0] ); - + self->mAbuserID = ids[0]; self->refresh(); @@ -379,31 +378,59 @@ void LLFloaterReporter::callbackAvatarID(const std::vector& names, void LLFloaterReporter::onClickSend(void *userdata) { LLFloaterReporter *self = (LLFloaterReporter *)userdata; + + if (self->mPicking) + { + closePickTool(self); + } - // only do this for abuse reports - if ( self->mReportType != BUG_REPORT ) + if(self->validateReport()) { - if ( ! self->mCopyrightWarningSeen ) + // only show copyright alert for abuse reports + if ( self->mReportType != BUG_REPORT ) { - LLString details_lc = self->childGetText("details_edit"); - LLString::toLower( details_lc ); - LLString summary_lc = self->childGetText("summary_edit"); - LLString::toLower( summary_lc ); - if ( details_lc.find( "copyright" ) != std::string::npos || - summary_lc.find( "copyright" ) != std::string::npos ) + if ( ! self->mCopyrightWarningSeen ) { - gViewerWindow->alertXml("HelpReportAbuseContainsCopyright"); - self->mCopyrightWarningSeen = TRUE; - return; + LLString details_lc = self->childGetText("details_edit"); + LLString::toLower( details_lc ); + LLString summary_lc = self->childGetText("summary_edit"); + LLString::toLower( summary_lc ); + if ( details_lc.find( "copyright" ) != std::string::npos || + summary_lc.find( "copyright" ) != std::string::npos ) + { + gViewerWindow->alertXml("HelpReportAbuseContainsCopyright"); + self->mCopyrightWarningSeen = TRUE; + return; + }; }; }; - }; - if (self->mPicking) - { - closePickTool(self); + LLUploadDialog::modalUploadDialog("Uploading...\n\nReport"); + // *TODO don't upload image if checkbox isn't checked + std::string url = gAgent.getRegion()->getCapability("SendUserReport"); + std::string sshot_url = gAgent.getRegion()->getCapability("SendUserReportWithScreenshot"); + if(!url.empty() || !sshot_url.empty()) + { + self->sendReportViaCaps(url, sshot_url, self->gatherReport()); + self->close(); + } + else + { + if(self->childGetValue("screen_check")) + { + self->childDisable("send_btn"); + self->childDisable("cancel_btn"); + // the callback from uploading the image calls sendReportViaLegacy() + self->uploadImage(); + } + else + { + self->sendReportViaLegacy(self->gatherReport()); + LLUploadDialog::modalUploadFinished(); + self->close(); + } + } } - self->sendReport(); } @@ -459,7 +486,7 @@ void LLFloaterReporter::showFromMenu(EReportType report_type) { // ...bring that window to front LLFloaterReporter *f = gReporterInstances.getData(report_type); - f->open(); + f->open(); /* Flawfinder: ignore */ } else { @@ -515,7 +542,7 @@ void LLFloaterReporter::showFromObject(const LLUUID& object_id) // Need to deselect on close f->mDeselectOnClose = TRUE; - f->open(); + f->open(); /* Flawfinder: ignore */ } @@ -556,10 +583,9 @@ void LLFloaterReporter::setPickedObjectProperties(const char *object_name, const childSetText("owner_name", owner_name); } -void LLFloaterReporter::sendReport() + +bool LLFloaterReporter::validateReport() { - LLViewerRegion *regionp = gAgent.getRegion(); - if (!regionp) return; // Ensure user selected a category from the list LLSD category_sd = childGetValue("category_combo"); U8 category = (U8)category_sd.asInteger(); @@ -573,7 +599,7 @@ void LLFloaterReporter::sendReport() { gViewerWindow->alertXml("HelpReportBugSelectCategory"); } - return; + return false; } if ( mReportType != BUG_REPORT ) @@ -581,13 +607,13 @@ void LLFloaterReporter::sendReport() if ( childGetText("abuser_name_edit").empty() ) { gViewerWindow->alertXml("HelpReportAbuseAbuserNameEmpty"); - return; + return false; }; if ( childGetText("abuse_location_edit").empty() ) { gViewerWindow->alertXml("HelpReportAbuseAbuserLocationEmpty"); - return; + return false; }; }; @@ -601,7 +627,7 @@ void LLFloaterReporter::sendReport() { gViewerWindow->alertXml("HelpReportBugSummaryEmpty"); } - return; + return false; }; if ( childGetText("details_edit") == mDefaultSummary ) @@ -614,53 +640,19 @@ void LLFloaterReporter::sendReport() { gViewerWindow->alertXml("HelpReportBugDetailsEmpty"); } - return; + return false; }; + return true; +} + +LLSD LLFloaterReporter::gatherReport() +{ + LLViewerRegion *regionp = gAgent.getRegion(); + if (!regionp) return LLSD(); // *TODO handle this failure case more gracefully // reset flag in case the next report also contains this text mCopyrightWarningSeen = FALSE; - U32 check_flags = 0; - if (childGetValue("screen_check")) - { - check_flags |= INCLUDE_SCREENSHOT; - } - - LLMessageSystem *msg = gMessageSystem; - msg->newMessageFast(_PREHASH_UserReport); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ReportData); - msg->addU8Fast(_PREHASH_ReportType, (U8) mReportType); - msg->addU8(_PREHASH_Category, category); - msg->addVector3Fast(_PREHASH_Position, mPosition); - msg->addU8Fast(_PREHASH_CheckFlags, (U8) check_flags); - - // only send a screenshot ID if we're asked too and the email is - // going to LL - Estate Owners cannot see the screenshot asset - LLSD screenshot_id = LLUUID::null; - if (childGetValue("screen_check")) - { - if ( mReportType != BUG_REPORT ) - { - if ( gEmailToEstateOwner == FALSE ) - { - screenshot_id = childGetValue("screenshot"); - } - } - else - { - screenshot_id = childGetValue("screenshot"); - }; - }; - msg->addUUIDFast(_PREHASH_ScreenshotID, screenshot_id); - msg->addUUIDFast(_PREHASH_ObjectID, mObjectID); - - msg->addUUID("AbuserID", mAbuserID ); - msg->addString("AbuseRegionName", ""); - msg->addUUID("AbuseRegionID", LLUUID::null); - std::ostringstream summary; if (!gInProductionGrid) { @@ -708,7 +700,6 @@ void LLFloaterReporter::sendReport() << " {" << childGetText("abuser_name_edit") << "} " // name of abuse entered in report (chosen using LLAvatarPicker) << " \"" << childGetValue("summary_edit").asString() << "\""; // summary as entered }; - msg->addStringFast(_PREHASH_Summary, summary.str().c_str()); std::ostringstream details; if (mReportType != BUG_REPORT) @@ -733,10 +724,10 @@ void LLFloaterReporter::sendReport() }; details << childGetValue("details_edit").asString(); - msg->addStringFast(_PREHASH_Details, details.str() ); - char version_string[MAX_STRING]; - sprintf(version_string, + char version_string[MAX_STRING]; /* Flawfinder: ignore */ + snprintf(version_string, /* Flawfinder: ignore */ + MAX_STRING, "%d.%d.%d %s %s %s %s", LL_VERSION_MAJOR, LL_VERSION_MINOR, @@ -745,120 +736,204 @@ void LLFloaterReporter::sendReport() gSysCPU.getFamily().c_str(), gGLManager.mGLRenderer.c_str(), gGLManager.mDriverVersionVendorString.c_str()); - msg->addString("VersionString", version_string); - msg->sendReliable(regionp->getHost()); + // only send a screenshot ID if we're asked to and the email is + // going to LL - Estate Owners cannot see the screenshot asset + LLUUID screenshot_id = LLUUID::null; + if (childGetValue("screen_check")) + { + if ( mReportType != BUG_REPORT ) + { + if ( gEmailToEstateOwner == FALSE ) + { + screenshot_id = childGetValue("screenshot"); + } + } + else + { + screenshot_id = childGetValue("screenshot"); + }; + }; + + LLSD report = LLSD::emptyMap(); + report["report-type"] = (U8) mReportType; + report["category"] = childGetValue("category_combo"); + report["position"] = mPosition.getValue(); + report["check-flags"] = (U8)0; // this is not used + report["screenshot-id"] = screenshot_id; + report["object-id"] = mObjectID; + report["abuser-id"] = mAbuserID; + report["abuse-region-name"] = ""; + report["abuse-region-id"] = LLUUID::null; + report["summary"] = summary.str(); + report["version-string"] = version_string; + report["details"] = details.str(); + return report; +} - close(); +void LLFloaterReporter::sendReportViaLegacy(const LLSD & report) +{ + LLViewerRegion *regionp = gAgent.getRegion(); + if (!regionp) return; + LLMessageSystem *msg = gMessageSystem; + msg->newMessageFast(_PREHASH_UserReport); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + + msg->nextBlockFast(_PREHASH_ReportData); + msg->addU8Fast(_PREHASH_ReportType, report["report-type"].asInteger()); + msg->addU8(_PREHASH_Category, report["category"].asInteger()); + msg->addVector3Fast(_PREHASH_Position, LLVector3(report["position"])); + msg->addU8Fast(_PREHASH_CheckFlags, report["check-flags"].asInteger()); + msg->addUUIDFast(_PREHASH_ScreenshotID, report["screenshot-id"].asUUID()); + msg->addUUIDFast(_PREHASH_ObjectID, report["object-id"].asUUID()); + msg->addUUID("AbuserID", report["abuser-id"].asUUID()); + msg->addString("AbuseRegionName", report["abuse-region-name"].asString()); + msg->addUUID("AbuseRegionID", report["abuse-region-id"].asUUID()); + + msg->addStringFast(_PREHASH_Summary, report["summary"].asString().c_str()); + msg->addString("VersionString", report["version-string"]); + msg->addStringFast(_PREHASH_Details, report["details"] ); + + msg->sendReliable(regionp->getHost()); } +class LLUserReportScreenshotResponder : public LLAssetUploadResponder +{ +public: + LLUserReportScreenshotResponder(const LLSD & post_data, + const LLUUID & vfile_id, + LLAssetType::EType asset_type): + LLAssetUploadResponder(post_data, vfile_id, asset_type) + { + } + void uploadFailed(const LLSD& content) + { + // *TODO pop up a dialog so the user knows their report screenshot didn't make it + LLUploadDialog::modalUploadFinished(); + } + void uploadComplete(const LLSD& content) + { + // we don't care about what the server returns from this post, just clean up the UI + LLUploadDialog::modalUploadFinished(); + } +}; + +class LLUserReportResponder : public LLHTTPClient::Responder +{ +public: + LLUserReportResponder(): LLHTTPClient::Responder() {} + + void error(U32 status, const std::string& reason) + { + // *TODO do some user messaging here + LLUploadDialog::modalUploadFinished(); + } + void result(const LLSD& content) + { + // we don't care about what the server returns + LLUploadDialog::modalUploadFinished(); + } +}; + +void LLFloaterReporter::sendReportViaCaps(std::string url, std::string sshot_url, const LLSD& report) +{ + if(childGetValue("screen_check").asBoolean() && !sshot_url.empty()) + { + // try to upload screenshot + LLHTTPClient::post(sshot_url, report, new LLUserReportScreenshotResponder(report, + mResourceDatap->mAssetInfo.mUuid, + mResourceDatap->mAssetInfo.mType)); + } + else + { + // screenshot not wanted or we don't have screenshot cap + LLHTTPClient::post(url, report, new LLUserReportResponder()); + } +} -void LLFloaterReporter::uploadScreenshot() +void LLFloaterReporter::takeScreenshot() { const S32 IMAGE_WIDTH = 1024; const S32 IMAGE_HEIGHT = 768; - LLString filename("report_screenshot.bmp"); - if( !gViewerWindow->saveSnapshot( filename, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, FALSE ) ) + LLPointer raw = new LLImageRaw; + if( !gViewerWindow->rawSnapshot(raw, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, TRUE, FALSE)) { + llwarns << "Unable to take screenshot" << llendl; return; } + LLPointer upload_data = LLViewerImageList::convertToUploadFile(raw); - // Generate the temporary filename - std::string temp_filename = gDirUtilp->getTempFilename(); - - // try to create the upload file - if (!LLViewerImageList::createUploadFile(filename, - temp_filename, - IMG_CODEC_BMP )) + // create a resource data + mResourceDatap->mInventoryType = LLInventoryType::IT_NONE; + mResourceDatap->mAssetInfo.mTransactionID.generate(); + mResourceDatap->mAssetInfo.mUuid = mResourceDatap->mAssetInfo.mTransactionID.makeAssetID(gAgent.getSecureSessionID()); + if (BUG_REPORT == mReportType) { - llwarns << "Unable to upload report screenshot " << filename << ":\n\n" << LLImageBase::getLastError() << "\n" << llendl; - if(LLFile::remove(temp_filename.c_str()) == -1) - { - lldebugs << "unable to remove temp file" << llendl; - } - LLFilePicker::instance().reset(); + mResourceDatap->mAssetInfo.mType = LLAssetType::AT_TEXTURE; + mResourceDatap->mPreferredLocation = LLAssetType::EType(-1); + } + else if (COMPLAINT_REPORT == mReportType) + { + mResourceDatap->mAssetInfo.mType = LLAssetType::AT_TEXTURE; + mResourceDatap->mPreferredLocation = LLAssetType::EType(-2); } else { - // create a resource data - LLResourceData* data = NULL; - data = new LLResourceData; - data->mInventoryType = LLInventoryType::IT_NONE; - data->mAssetInfo.mTransactionID.generate(); - data->mAssetInfo.mUuid = data->mAssetInfo.mTransactionID.makeAssetID(gAgent.getSecureSessionID()); - if (BUG_REPORT == mReportType) - { - //data->mAssetInfo.mType = LLAssetType::AT_BUG_REPORT_SCREENSHOT; - data->mAssetInfo.mType = LLAssetType::AT_TEXTURE; - data->mPreferredLocation = LLAssetType::EType(-1); - } - else if (COMPLAINT_REPORT == mReportType) - { - //data->mAssetInfo.mType = LLAssetType::AT_COMPLAINT_REPORT_SCREENSHOT; - data->mAssetInfo.mType = LLAssetType::AT_TEXTURE; - data->mPreferredLocation = LLAssetType::EType(-2); - } - else - { - llwarns << "Unknown LLFloaterReporter type" << llendl; - } - data->mAssetInfo.mCreatorID = gAgentID; - data->mAssetInfo.setName("screenshot_name"); - data->mAssetInfo.setDescription("screenshot_descr"); - - llinfos << "*** Uploading: " << llendl; - llinfos << "Type: " << LLAssetType::lookup(data->mAssetInfo.mType) << llendl; - llinfos << "File: " << filename << llendl; - llinfos << "Dest: " << temp_filename << llendl; - llinfos << "Name: " << data->mAssetInfo.getName() << llendl; - llinfos << "Desc: " << data->mAssetInfo.getDescription() << llendl; - - gAssetStorage->storeAssetData(temp_filename.c_str(), - data->mAssetInfo.mTransactionID, - data->mAssetInfo.mType, - LLFloaterReporter::uploadDoneCallback, - (void*)data, TRUE); + llwarns << "Unknown LLFloaterReporter type" << llendl; + } + mResourceDatap->mAssetInfo.mCreatorID = gAgentID; + mResourceDatap->mAssetInfo.setName("screenshot_name"); + mResourceDatap->mAssetInfo.setDescription("screenshot_descr"); + + // store in VFS + LLVFile::writeFile(upload_data->getData(), + upload_data->getDataSize(), + gVFS, + mResourceDatap->mAssetInfo.mUuid, + mResourceDatap->mAssetInfo.mType); + + // store in the image list so it doesn't try to fetch from the server + LLViewerImage* image_in_list = new LLViewerImage(mResourceDatap->mAssetInfo.mUuid, TRUE); + image_in_list->createGLTexture(0, raw); + gImageList.addImage(image_in_list); + + // the texture picker then uses that texture + LLTexturePicker* texture = LLUICtrlFactory::getTexturePickerByName(this, "screenshot"); + if (texture) + { + texture->setImageAssetID(mResourceDatap->mAssetInfo.mUuid); + texture->setDefaultImageAssetID(mResourceDatap->mAssetInfo.mUuid); + texture->setCaption("Screenshot"); } + +} + +void LLFloaterReporter::uploadImage() +{ + llinfos << "*** Uploading: " << llendl; + llinfos << "Type: " << LLAssetType::lookup(mResourceDatap->mAssetInfo.mType) << llendl; + llinfos << "UUID: " << mResourceDatap->mAssetInfo.mUuid << llendl; + llinfos << "Name: " << mResourceDatap->mAssetInfo.getName() << llendl; + llinfos << "Desc: " << mResourceDatap->mAssetInfo.getDescription() << llendl; + + gAssetStorage->storeAssetData(mResourceDatap->mAssetInfo.mTransactionID, + mResourceDatap->mAssetInfo.mType, + LLFloaterReporter::uploadDoneCallback, + (void*)mResourceDatap, TRUE); } // static void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data, S32 result) // StoreAssetData callback (fixed) { - LLResourceData* data = (LLResourceData*)user_data; + LLUploadDialog::modalUploadFinished(); - if(result >= 0) - { - EReportType report_type = UNKNOWN_REPORT; - if (data->mPreferredLocation == -1) - { - report_type = BUG_REPORT; - } - else if (data->mPreferredLocation == -2) - { - report_type = COMPLAINT_REPORT; - } - else - { - llwarns << "Unknown report type : " << data->mPreferredLocation << llendl; - } + LLResourceData* data = (LLResourceData*)user_data; - LLFloaterReporter *self = getReporter(report_type); - if (self) - { - LLTexturePicker* texture = LLUICtrlFactory::getTexturePickerByName(self, "screenshot"); - if (texture) - { - texture->setImageAssetID(uuid); - texture->setDefaultImageAssetID(uuid); - texture->setCaption("Screenshot"); - } - self->mScreenID = uuid; - llinfos << "Got screen shot " << uuid << llendl; - } - } - else // if(result >= 0) + if(result < 0) { LLStringBase::format_map_t args; args["[REASON]"] = std::string(LLAssetStorage::getErrorString(result)); @@ -867,8 +942,31 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data, std::string err_msg("There was a problem uploading a report screenshot"); err_msg += " due to the following reason: " + args["[REASON]"]; llwarns << err_msg << llendl; + return; + } + + EReportType report_type = UNKNOWN_REPORT; + if (data->mPreferredLocation == -1) + { + report_type = BUG_REPORT; } - delete data; + else if (data->mPreferredLocation == -2) + { + report_type = COMPLAINT_REPORT; + } + else + { + llwarns << "Unknown report type : " << data->mPreferredLocation << llendl; + } + + LLFloaterReporter *self = getReporter(report_type); + if (self) + { + self->mScreenID = uuid; + llinfos << "Got screen shot " << uuid << llendl; + self->sendReportViaLegacy(self->gatherReport()); + } + self->close(); } -- cgit v1.1