diff --git a/indra/llinventory/llparcelflags.h b/indra/llinventory/llparcelflags.h index 122468e91..343044727 100644 --- a/indra/llinventory/llparcelflags.h +++ b/indra/llinventory/llparcelflags.h @@ -59,6 +59,7 @@ const U32 PF_URL_WEB_PAGE = 1 << 19; // The "media URL" is an HTML page const U32 PF_URL_RAW_HTML = 1 << 20; // The "media URL" is a raw HTML string like

Foo

const U32 PF_RESTRICT_PUSHOBJECT = 1 << 21; // Restrict push object to either on agent or on scripts owned by parcel owner const U32 PF_DENY_ANONYMOUS = 1 << 22; // Deny all non identified/transacted accounts +const U32 PF_GAMING = 1 << 23; // Denotes a gaming parcel on certain grids // const U32 PF_DENY_IDENTIFIED = 1 << 23; // Deny identified accounts // const U32 PF_DENY_TRANSACTED = 1 << 24; // Deny identified accounts const U32 PF_ALLOW_GROUP_SCRIPTS = 1 << 25; // Allow scripts owned by group diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index a45b990e9..f5f9f4428 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -844,7 +844,12 @@ P(environmentRequestResponder); P(estateChangeInfoResponder); P(eventPollResponder); P(fetchInventoryResponder); +P(fetchScriptLimitsAttachmentInfoResponder); +P(fetchScriptLimitsRegionDetailsResponder); +P(fetchScriptLimitsRegionInfoResponder); +P(fetchScriptLimitsRegionSummaryResponder); P(fnPtrResponder); +P2(gamingDataReceived, transfer_18s); P2(groupMemberDataResponder, transfer_300s); P2(groupProposalBallotResponder, transfer_300s); P(homeLocationResponder); diff --git a/indra/llmessage/llqueryflags.h b/indra/llmessage/llqueryflags.h index 14a62de04..311c90000 100644 --- a/indra/llmessage/llqueryflags.h +++ b/indra/llmessage/llqueryflags.h @@ -66,6 +66,8 @@ const U32 DFQ_INC_NEW_VIEWER = (DFQ_INC_PG | DFQ_INC_MATURE | DFQ_INC_ADULT); // const U32 DFQ_ADULT_SIMS_ONLY = 0x1 << 27; +const U32 DFQ_FILTER_GAMING = 0x1 << 28; + // Sell Type flags const U32 ST_AUCTION = 0x1 << 1; const U32 ST_NEWBIE = 0x1 << 2; diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h index 1cf940918..8d51207a9 100644 --- a/indra/llmessage/llregionflags.h +++ b/indra/llmessage/llregionflags.h @@ -51,6 +51,8 @@ const U64 REGION_FLAGS_BLOCK_LAND_RESELL = (1 << 7); // All content wiped once per night const U64 REGION_FLAGS_SANDBOX = (1 << 8); +const U64 REGION_FLAGS_GAMING = (1 << 10); // Denotes a gaming region on certain grids +const U64 REGION_FLAGS_HIDE_FROM_SEARCH = (1 << 11); // Hides region from search on certain grids const U64 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid bodies const U64 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13); const U64 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics @@ -96,6 +98,18 @@ const U64 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE | REGION_FLAGS_DENY_ANONYMOUS | REGION_FLAGS_DENY_AGEUNVERIFIED; +// 'Gaming' flags +const U32 REGION_GAMING_PRESENT = (1 << 0); +const U32 REGION_GAMING_HIDE_PARCEL = (1 << 1); +const U32 REGION_GAMING_HIDE_FIND_ALL = (1 << 2); +const U32 REGION_GAMING_HIDE_FIND_CLASSIFIEDS = (1 << 3); +const U32 REGION_GAMING_HIDE_FIND_EVENTS = (1 << 4); +const U32 REGION_GAMING_HIDE_FIND_LAND = (1 << 5); +const U32 REGION_GAMING_HIDE_FIND_SIMS = (1 << 6); +const U32 REGION_GAMING_HIDE_FIND_GROUPS = (1 << 7); +const U32 REGION_GAMING_HIDE_FIND_ALL_CLASSIC = (1 << 8); +const U32 REGION_GAMING_HIDE_GOD_FLOATER = (1 << 9); + inline BOOL is_prelude( U64 flags ) { // definition of prelude does not depend on fixed-sun diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index cce9eb172..5c74462f1 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1945,7 +1945,7 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory { // SUBMENU LLMenuGL *submenu = (LLMenuGL*)LLMenuGL::fromXML(child, parent, factory); - appendMenu(submenu); + appendMenu(submenu, 0); if (LLMenuGL::sMenuContainer != NULL) { submenu->updateParent(LLMenuGL::sMenuContainer); @@ -2214,18 +2214,27 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory } } +// This wrapper is needed because the virtual linkage causes errors if default parameters are used bool LLMenuGL::addChild(LLView* view, S32 tab_group) +{ + return addChild(view, 0, tab_group); +} + +bool LLMenuGL::addChild(LLView* view, LLView* insert_before, S32 tab_group) { if (LLMenuGL* menup = dynamic_cast(view)) { lldebugs << "Adding menu " << menup->getName() << " to " << getName() << llendl; - appendMenu(menup); + if (!insert_before) + appendMenu(menup); + else + appendMenu(menup, insert_before); return true; } else if (LLMenuItemGL* itemp = dynamic_cast(view)) { lldebugs << "Adding " << itemp->getName() << " to " << getName() << llendl; - append(itemp); + append(itemp, insert_before); return true; } lldebugs << "Error adding unknown child '"<<(view ? view->getName() : std::string("NULL")) << "' to " << getName() << llendl; @@ -2712,10 +2721,29 @@ BOOL LLMenuGL::handleJumpKey(KEY key) // Add the menu item to this menu. +// This wrapper is needed because the virtual linkage causes errors if default parameters are used BOOL LLMenuGL::append( LLMenuItemGL* item ) +{ + return append(item, 0); +} + +BOOL LLMenuGL::append(LLMenuItemGL* item, LLView* insert_before) { if (!item) return FALSE; + if (!insert_before) + { mItems.push_back( item ); + } + else + { + item_list_t::iterator i; + + for (i = mItems.begin(); i != mItems.end(); ++i) + if (*i == insert_before) + break; + mItems.insert(i, item); + } + LLUICtrl::addChild(item); needsArrange(); return TRUE; @@ -2729,7 +2757,13 @@ BOOL LLMenuGL::addSeparator() } // add a menu - this will create a cascading menu +// This wrapper is needed because the virtual linkage causes errors if default parameters are used BOOL LLMenuGL::appendMenu( LLMenuGL* menu ) +{ + return appendMenu(menu, 0); +} + +BOOL LLMenuGL::appendMenu(LLMenuGL* menu, LLView* insert_before) { if( menu == this ) { @@ -2741,7 +2775,7 @@ BOOL LLMenuGL::appendMenu( LLMenuGL* menu ) LLMenuItemBranchGL* branch = NULL; branch = new LLMenuItemBranchGL( menu->getName(), menu->getLabel(), menu->getHandle() ); branch->setJumpKey(menu->getJumpKey()); - success &= append( branch ); + success &= append( branch, insert_before ); // Inherit colors menu->setBackgroundColor( mBackgroundColor ); diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 581fcc1a5..07effab8d 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -476,6 +476,8 @@ public: /*virtual*/ void removeChild( LLView* ctrl); /*virtual*/ BOOL postBuild(); + bool addChild(LLView* view, LLView* insert_before, S32 tab_group = 0); + virtual BOOL handleAcceleratorKey(KEY key, MASK mask); LLMenuGL* getChildMenuByName(const std::string& name, BOOL recurse) const; @@ -572,11 +574,14 @@ public: protected: void createSpilloverBranch(); void cleanupSpilloverBranch(); + // Add the menu item to this menu. virtual BOOL append( LLMenuItemGL* item ); + BOOL append(LLMenuItemGL* item, LLView* insert_before); // add a menu - this will create a cascading menu virtual BOOL appendMenu( LLMenuGL* menu ); + BOOL appendMenu(LLMenuGL* menu, LLView* insert_before); // TODO: create accessor methods for these? typedef std::list< LLMenuItemGL* > item_list_t; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index c068de93a..a102126d9 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -244,6 +244,7 @@ set(viewer_SOURCE_FILES llfloaterregioninfo.cpp llfloaterreporter.cpp llfloaterscriptdebug.cpp + llfloaterscriptlimits.cpp llfloatersearchreplace.cpp llfloatersellland.cpp llfloatersettingsdebug.cpp @@ -745,6 +746,7 @@ set(viewer_HEADER_FILES llfloaterregioninfo.h llfloaterreporter.h llfloaterscriptdebug.h + llfloaterscriptlimits.h llfloatersearchreplace.h llfloatersellland.h llfloatersettingsdebug.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index aef7f4e17..de8f149ce 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5768,6 +5768,84 @@ This should be as low as possible, but too low may break functionality Value 10.0 + FilterGamingSearchAll + + Comment + Filter results flagged gaming in everything search + Persist + 1 + HideFromEditor + 1 + Type + Boolean + Value + 1 + + FilterGamingClassifieds + + Comment + Filter results flagged gaming in classifieds search + Persist + 1 + HideFromEditor + 1 + Type + Boolean + Value + 1 + + FilterGamingEvents + + Comment + Filter results flagged gaming in event search + Persist + 1 + HideFromEditor + 1 + Type + Boolean + Value + 1 + + FilterGamingGroups + + Comment + Filter results flagged gaming in groups search + Persist + 1 + HideFromEditor + 1 + Type + Boolean + Value + 1 + + FilterGamingLand + + Comment + Filter results flagged gaming in land search + Persist + 1 + HideFromEditor + 1 + Type + Boolean + Value + 1 + + FilterGamingSims + + Comment + Filter results flagged gaming in sim search + Persist + 1 + HideFromEditor + 1 + Type + Boolean + Value + 1 + FilterItemsPerFrame Comment @@ -7072,6 +7150,22 @@ This should be as low as possible, but too low may break functionality 0 + FloaterScriptLimitsRect + + Comment + Rectangle for Script Limits window + Persist + 1 + Type + Rect + Value + + 0 + 500 + 480 + 0 + + FloaterSnapshotRect Comment diff --git a/indra/newview/hippogridmanager.cpp b/indra/newview/hippogridmanager.cpp index 674206e79..18663b175 100644 --- a/indra/newview/hippogridmanager.cpp +++ b/indra/newview/hippogridmanager.cpp @@ -357,7 +357,7 @@ std::string HippoGridInfo::getSearchUrl(SearchType ty, bool is_web) const } else if (ty == SEARCH_ALL_TEMPLATE) { - return "lang=[LANG]&mat=[MATURITY]&t=[TEEN]®ion=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]"; + return "lang=[LANG]&mat=[MATURITY]&t=[TEEN]®ion=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]&dice=[DICE]"; } else { @@ -400,7 +400,7 @@ std::string HippoGridInfo::getSearchUrl(SearchType ty, bool is_web) const } else if (ty == SEARCH_ALL_TEMPLATE) { - return "lang=[LANG]&m=[MATURITY]&t=[TEEN]®ion=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]"; + return "lang=[LANG]&m=[MATURITY]&t=[TEEN]®ion=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]&dice=[DICE]"; } else { diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 8f412d0b8..2539c8f91 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4459,9 +4459,9 @@ void LLAgent::sendAgentSetAppearance() body_size.mV[VX] += x_off; body_size.mV[VY] += y_off; - body_size.mV[VZ] += z_off; // Offset by RLVa, but not overridden. // [RLVa:KB] - Checked: 2010-10-11 (RLVa-1.2.0e) | Added: RLVa-1.2.0e - body_size.mV[VZ] += RlvSettings::getAvatarOffsetZ(); + F32 rlvz_off = RlvSettings::getAvatarOffsetZ(); + body_size.mV[VZ] += fabs(rlvz_off) ? rlvz_off : z_off; // [/RLVa:KB] msg->addVector3Fast(_PREHASH_Size, body_size); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index dd7255e21..cf0d063eb 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -243,7 +243,6 @@ const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user fl F32 gSimLastTime; // Used in LLAppViewer::init and send_stats() F32 gSimFrames; -BOOL gAllowIdleAFK = FALSE; BOOL gAllowTapTapHoldRun = TRUE; BOOL gShowObjectUpdates = FALSE; BOOL gUseQuickTime = TRUE; @@ -397,15 +396,16 @@ LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ; void idle_afk_check() { + static const LLCachedControl allow_idk_afk("AllowIdleAFK"); // check idle timers static const LLCachedControl afk_timeout("AFKTimeout",0.f); - //if (gAllowIdleAFK && (gAwayTriggerTimer.getElapsedTimeF32() > gSavedSettings.getF32("AFKTimeout"))) + //if (allow_idk_afk && (gAwayTriggerTimer.getElapsedTimeF32() > gSavedSettings.getF32("AFKTimeout"))) // [RLVa:KB] - Checked: 2009-10-19 (RLVa-1.1.0g) | Added: RLVa-1.1.0g #ifdef RLV_EXTENSION_CMD_ALLOWIDLE - if ( (gAllowIdleAFK || gRlvHandler.hasBehaviour(RLV_BHVR_ALLOWIDLE)) && + if ( (allow_idk_afk || gRlvHandler.hasBehaviour(RLV_BHVR_ALLOWIDLE)) && (gAwayTriggerTimer.getElapsedTimeF32() > afk_timeout) && (afk_timeout > 0)) #else - if (gAllowIdleAFK && (gAwayTriggerTimer.getElapsedTimeF32() > afk_timeout) && (afk_timeout > 0)) + if (allow_idk_afk && (gAwayTriggerTimer.getElapsedTimeF32() > afk_timeout) && (afk_timeout > 0)) #endif // RLV_EXTENSION_CMD_ALLOWIDLE // [/RLVa:KB] { @@ -504,7 +504,6 @@ static void settings_to_globals() gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle")); gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc"); - gAllowIdleAFK = gSavedSettings.getBOOL("AllowIdleAFK"); gAllowTapTapHoldRun = gSavedSettings.getBOOL("AllowTapTapHoldRun"); gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); LLWorldMapView::sMapScale = llmax(.1f,gSavedSettings.getF32("MapScale")); @@ -2675,7 +2674,6 @@ void LLAppViewer::cleanupSavedSettings() gSavedSettings.setBOOL("DebugWindowProc", gDebugWindowProc); - gSavedSettings.setBOOL("AllowIdleAFK", gAllowIdleAFK); gSavedSettings.setBOOL("AllowTapTapHoldRun", gAllowTapTapHoldRun); gSavedSettings.setBOOL("ShowObjectUpdates", gShowObjectUpdates); diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 681cb505d..6facb1266 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -275,7 +275,6 @@ const S32 AGENT_UPDATES_PER_SECOND = 10; extern LLSD gDebugInfo; -extern BOOL gAllowIdleAFK; extern BOOL gAllowTapTapHoldRun; extern BOOL gShowObjectUpdates; diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index f410bd615..39c82ab77 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -876,7 +876,7 @@ void LLFloaterAvatarList::refreshAvatarList() LLColor4 name_color = sDefaultListText; //Lindens are always more Linden than your friend, make that take precedence - if(LLMuteList::getInstance()->isLinden(av_name)) + if(LLMuteList::getInstance()->isLinden(av_id)) { static const LLCachedControl ascent_linden_color("AscentLindenColor",LLColor4(0.f,0.f,1.f,1.f)); name_color = ascent_linden_color; diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp index 4ab128f1b..873108ee0 100644 --- a/indra/newview/llfloatergodtools.cpp +++ b/indra/newview/llfloatergodtools.cpp @@ -461,6 +461,10 @@ BOOL LLPanelRegionTools::postBuild() getChild("block terraform")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); getChild("allow transfer")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); getChild("is sandbox")->setCommitCallback( boost::bind(&LLPanelRegionTools::onChangeAnything, this)); + getChild("is gaming")->setVisible((gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_GOD_FLOATER)); + getChild("is gaming")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); + getChild("hide from search")->setVisible(!gHippoGridManager->getConnectedGrid()->isSecondLife()); + getChild("hide from search")->setCommitCallback(boost::bind(&LLPanelRegionTools::onChangeAnything, this)); childSetAction("Bake Terrain", boost::bind(&LLPanelRegionTools::onBakeTerrain, this)); childSetAction("Revert Terrain", boost::bind(&LLPanelRegionTools::onRevertTerrain, this)); @@ -670,6 +674,14 @@ U64 LLPanelRegionTools::getRegionFlags() const { flags |= REGION_FLAGS_SANDBOX; } + if (getChild("is gaming")->getValue().asBoolean()) + { + flags |= REGION_FLAGS_GAMING; + } + if (getChild("hide from search")->getValue().asBoolean()) + { + flags |= REGION_FLAGS_HIDE_FROM_SEARCH; + } return flags; } @@ -708,6 +720,14 @@ U64 LLPanelRegionTools::getRegionFlagsMask() const { flags &= ~REGION_FLAGS_SANDBOX; } + if (!getChild("is gaming")->getValue().asBoolean()) + { + flags &= ~REGION_FLAGS_GAMING; + } + if (!getChild("hide from search")->getValue().asBoolean()) + { + flags &= ~REGION_FLAGS_HIDE_FROM_SEARCH; + } return flags; } @@ -766,6 +786,8 @@ void LLPanelRegionTools::setCheckFlags(U64 flags) getChild("block terraform")->setValue(flags & REGION_FLAGS_BLOCK_TERRAFORM ? TRUE : FALSE); getChild("block dwell")->setValue(flags & REGION_FLAGS_BLOCK_DWELL ? TRUE : FALSE); getChild("is sandbox")->setValue(flags & REGION_FLAGS_SANDBOX ? TRUE : FALSE ); + getChild("is gaming")->setValue(flags & REGION_FLAGS_GAMING ? true : false); + getChild("hide from search")->setValue(flags & REGION_FLAGS_HIDE_FROM_SEARCH ? true : false); } void LLPanelRegionTools::setBillableFactor(F32 billable_factor) diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 37d795a49..154acc65e 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -48,15 +48,16 @@ #include "llagent.h" #include "llagentaccess.h" #include "llavatarconstants.h" //For new Online check - HgB -#include "llfloateravatarpicker.h" #include "llbutton.h" #include "llcheckboxctrl.h" #include "llradiogroup.h" #include "llcombobox.h" #include "llfloaterauction.h" #include "llfloateravatarinfo.h" +#include "llfloateravatarpicker.h" #include "llfloatergroups.h" #include "llfloatergroupinfo.h" +#include "llfloaterscriptlimits.h" #include "lllineeditor.h" #include "llnamelistctrl.h" #include "llnotify.h" @@ -221,8 +222,6 @@ LLFloaterLand::LLFloaterLand(const LLSD& seed) { LLCallbackMap::map_t factory_map; factory_map["land_general_panel"] = LLCallbackMap(createPanelLandGeneral, this); - - factory_map["land_covenant_panel"] = LLCallbackMap(createPanelLandCovenant, this); factory_map["land_objects_panel"] = LLCallbackMap(createPanelLandObjects, this); factory_map["land_options_panel"] = LLCallbackMap(createPanelLandOptions, this); @@ -344,16 +343,15 @@ LLPanelLandGeneral::LLPanelLandGeneral(LLParcelSelectionHandle& parcel) BOOL LLPanelLandGeneral::postBuild() { mEditName = getChild("Name"); - mEditName->setCommitCallback(onCommitAny); - childSetPrevalidate("Name", LLLineEditor::prevalidatePrintableNotPipe); - childSetUserData("Name", this); + mEditName->setCommitCallback(onCommitAny, this); + getChild("Name")->setPrevalidate(LLLineEditor::prevalidatePrintableNotPipe); mEditDesc = getChild("Description"); mEditDesc->setCommitOnFocusLost(TRUE); - mEditDesc->setCommitCallback(onCommitAny); - //childSetPrevalidate("Description", LLLineEditor::prevalidatePrintableNotPipe); Making Dummy View -HgB - childSetUserData("Description", this); - + mEditDesc->setCommitCallback(onCommitAny, this); + // No prevalidate function - historically the prevalidate function was broken, + // allowing residents to put in characters like U+2661 WHITE HEART SUIT, so + // preserve that ability. mTextSalePending = getChild("SalePending"); mTextOwnerLabel = getChild("Owner:"); @@ -363,7 +361,7 @@ BOOL LLPanelLandGeneral::postBuild() mLandType = getChild("LandTypeText"); mBtnProfile = getChild("Profile..."); - mBtnProfile->setClickedCallback(onClickProfile, this); + mBtnProfile->setClickedCallback(boost::bind(&LLPanelLandGeneral::onClickProfile, this)); mTextGroupLabel = getChild("Group:"); @@ -371,7 +369,7 @@ BOOL LLPanelLandGeneral::postBuild() mBtnSetGroup = getChild("Set..."); - mBtnSetGroup->setClickedCallback(onClickSetGroup, this); + mBtnSetGroup->setCommitCallback(boost::bind(&LLPanelLandGeneral::onClickSetGroup, this)); getChild("group_profile")->setClickedCallback(onClickInfoGroup, this); @@ -416,10 +414,30 @@ BOOL LLPanelLandGeneral::postBuild() mTextDwell = getChild("DwellText"); - mBtnBuyLand = getChild("Buy Land..."); mBtnBuyLand->setClickedCallback(onClickBuyLand, (void*)&BUY_PERSONAL_LAND); + + // note: on region change this will not be re checked, should not matter on Agni as + // 99% of the time all regions will return the same caps. In case of an erroneous setting + // to enabled the floater will just throw an error when trying to get it's cap + std::string url = gAgent.getRegion()->getCapability("LandResources"); + if (!url.empty()) + { + mBtnScriptLimits = getChild("Scripts..."); + if(mBtnScriptLimits) + { + mBtnScriptLimits->setClickedCallback(onClickScriptLimits, this); + } + } + else + { + mBtnScriptLimits = getChild("Scripts..."); + if(mBtnScriptLimits) + { + mBtnScriptLimits->setVisible(false); + } + } mBtnBuyGroupLand = getChild("Buy For Group..."); mBtnBuyGroupLand->setClickedCallback(onClickBuyLand, (void*)&BUY_GROUP_LAND); @@ -508,6 +526,7 @@ void LLPanelLandGeneral::refresh() mTextDwell->setText(LLStringUtil::null); mBtnBuyLand->setEnabled(FALSE); + mBtnScriptLimits->setEnabled(FALSE); mBtnBuyGroupLand->setEnabled(FALSE); mBtnReleaseLand->setEnabled(FALSE); mBtnReclaimLand->setEnabled(FALSE); @@ -723,6 +742,7 @@ void LLPanelLandGeneral::refresh() mBtnBuyLand->setEnabled( LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, false)); + mBtnScriptLimits->setEnabled(true); mBtnBuyGroupLand->setEnabled( LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, true)); @@ -741,7 +761,7 @@ void LLPanelLandGeneral::refresh() mBtnReleaseLand->setEnabled( can_release ); } - BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST) && !LLViewerParcelMgr::getInstance()->isCollisionBanned();; + BOOL use_pass = parcel->getOwnerID()!= gAgent.getID() && parcel->getParcelFlag(PF_USE_PASS_LIST) && !LLViewerParcelMgr::getInstance()->isCollisionBanned();; mBtnBuyPass->setEnabled(use_pass); } } @@ -805,22 +825,20 @@ void LLPanelLandGeneral::draw() LLPanel::draw(); } -// static -void LLPanelLandGeneral::onClickSetGroup(void* userdata) +void LLPanelLandGeneral::onClickSetGroup() { - LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)userdata; - LLFloaterGroupPicker* fg; + LLFloater* parent_floater = gFloaterView->getParentFloater(this); - LLFloater* parent_floater = gFloaterView->getParentFloater(panelp); - - fg = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); - fg->setSelectCallback( cbGroupID, userdata ); - - if (parent_floater) + LLFloaterGroupPicker* fg = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); + if (fg) { - LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg); - fg->setOrigin(new_rect.mLeft, new_rect.mBottom); - parent_floater->addDependentFloater(fg); + fg->setSelectCallback( cbGroupID, this); + if (parent_floater) + { + LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg); + fg->setOrigin(new_rect.mLeft, new_rect.mBottom); + parent_floater->addDependentFloater(fg); + } } } @@ -834,11 +852,9 @@ void LLPanelLandGeneral::onClickInfoGroup(void* userdata) if(id.notNull())LLFloaterGroupInfo::showFromUUID(parcel->getGroupID()); } -// static -void LLPanelLandGeneral::onClickProfile(void* data) +void LLPanelLandGeneral::onClickProfile() { - LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data; - LLParcel* parcel = panelp->mParcel->getParcel(); + LLParcel* parcel = mParcel->getParcel(); if (!parcel) return; if (parcel->getIsGroupOwned()) @@ -891,17 +907,15 @@ void LLPanelLandGeneral::onClickBuyLand(void* data) LLViewerParcelMgr::getInstance()->startBuyLand(*for_group); } - - - - - - -BOOL LLPanelLandGeneral::enableDeedToGroup(void* data) +// static +void LLPanelLandGeneral::onClickScriptLimits(void* data) { LLPanelLandGeneral* panelp = (LLPanelLandGeneral*)data; LLParcel* parcel = panelp->mParcel->getParcel(); - return (parcel != NULL) && (parcel->getParcelFlag(PF_ALLOW_DEED_TO_GROUP)); + if(parcel != NULL) + { + LLFloaterScriptLimits::showInstance(); + } } // static @@ -954,6 +968,7 @@ void LLPanelLandGeneral::onClickBuyPass(void* data) LLSD args; args["COST"] = cost; + args["CURRENCY"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol(); args["PARCEL_NAME"] = parcel_name; args["TIME"] = time; @@ -1844,6 +1859,7 @@ LLPanelLandOptions::LLPanelLandOptions(LLParcelSelectionHandle& parcel) mSetBtn(NULL), mClearBtn(NULL), mMatureCtrl(NULL), + mGamingCtrl(NULL), mPushRestrictionCtrl(NULL), mSeeAvatarsCtrl(NULL), mParcel(parcel), @@ -1869,9 +1885,9 @@ BOOL LLPanelLandOptions::postBuild() mCheckEditLand = getChild( "edit land check"); childSetCommitCallback("edit land check", onCommitAny, this); - mCheckLandmark = getChild( "check landmark"); childSetCommitCallback("check landmark", onCommitAny, this); + mCheckLandmark->setVisible(!gHippoGridManager->getConnectedGrid()->isSecondLife()); mCheckGroupScripts = getChild( "check group scripts"); @@ -1921,6 +1937,11 @@ BOOL LLPanelLandOptions::postBuild() mMatureCtrl = getChild( "MatureCheck"); childSetCommitCallback("MatureCheck", onCommitAny, this); + + mGamingCtrl = getChild( "GamingCheck"); + childSetCommitCallback("GamingCheck", onCommitAny, this); + mGamingCtrl->setVisible((gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_PARCEL)); + mGamingCtrl->setEnabled(false); mPublishHelpButton = getChild("?"); mPublishHelpButton->setClickedCallback(onClickPublishHelp, this); @@ -1938,8 +1959,7 @@ BOOL LLPanelLandOptions::postBuild() mSnapshotCtrl = getChild("snapshot_ctrl"); if (mSnapshotCtrl) { - mSnapshotCtrl->setCommitCallback( onCommitAny ); - mSnapshotCtrl->setCallbackUserData( this ); + mSnapshotCtrl->setCommitCallback( onCommitAny, this ); mSnapshotCtrl->setAllowNoTexture ( TRUE ); mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); @@ -2029,6 +2049,7 @@ void LLPanelLandOptions::refresh() mClearBtn->setEnabled(FALSE); mMatureCtrl->setEnabled(FALSE); + mGamingCtrl->setEnabled(false); mPublishHelpButton->setEnabled(FALSE); } else @@ -2152,6 +2173,8 @@ void LLPanelLandOptions::refresh() } } } + mGamingCtrl->set(parcel->getParcelFlag(PF_GAMING)); + mGamingCtrl->setEnabled(can_change_options); } } @@ -2288,6 +2311,7 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata) BOOL mature_publish = self->mMatureCtrl->get(); BOOL push_restriction = self->mPushRestrictionCtrl->get(); BOOL see_avs = self->mSeeAvatarsCtrl->get(); + bool gaming = self->mGamingCtrl->get(); BOOL show_directory = self->mCheckShowDirectory->get(); // we have to get the index from a lookup, not from the position in the dropdown! S32 category_index = LLParcel::getCategoryFromString(self->mCategoryCombo->getSelectedValue()); @@ -2296,11 +2320,16 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata) LLViewerRegion* region; region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); - if (!allow_other_scripts && region && region->getAllowDamage()) - { - - LLNotificationsUtil::add("UnableToDisableOutsideScripts"); - return; + if (region && region->getAllowDamage()) + { // Damage is allowed on the region - server will always allow scripts + if ( (!allow_other_scripts && parcel->getParcelFlag(PF_ALLOW_OTHER_SCRIPTS)) || + (!allow_group_scripts && parcel->getParcelFlag(PF_ALLOW_GROUP_SCRIPTS)) ) + { // Don't allow turning off "Run Scripts" if damage is allowed in the region + self->mCheckOtherScripts->set(parcel->getParcelFlag(PF_ALLOW_OTHER_SCRIPTS)); // Restore UI to actual settings + self->mCheckGroupScripts->set(parcel->getParcelFlag(PF_ALLOW_GROUP_SCRIPTS)); + LLNotificationsUtil::add("UnableToDisableOutsideScripts"); + return; + } } // Push data into current parcel @@ -2317,6 +2346,7 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata) parcel->setParcelFlag(PF_SHOW_DIRECTORY, show_directory); parcel->setParcelFlag(PF_ALLOW_PUBLISH, allow_publish); parcel->setParcelFlag(PF_MATURE_PUBLISH, mature_publish); + parcel->setParcelFlag(PF_GAMING, gaming); parcel->setParcelFlag(PF_RESTRICT_PUSHOBJECT, push_restriction); parcel->setCategory((LLParcel::ECategory)category_index); parcel->setLandingType((LLParcel::ELandingType)landing_type_index); @@ -2419,9 +2449,9 @@ BOOL LLPanelLandAccess::postBuild() childSetCommitCallback("PriceSpin", onCommitAny, this); childSetCommitCallback("HoursSpin", onCommitAny, this); - childSetAction("add_allowed", onClickAddAccess, this); + childSetAction("add_allowed", boost::bind(&LLPanelLandAccess::onClickAddAccess, this)); childSetAction("remove_allowed", onClickRemoveAccess, this); - childSetAction("add_banned", onClickAddBanned, this); + childSetAction("add_banned", boost::bind(&LLPanelLandAccess::onClickAddBanned, this)); childSetAction("remove_banned", onClickRemoveBanned, this); mListAccess = getChild("AccessList"); @@ -2456,12 +2486,12 @@ void LLPanelLandAccess::refresh() BOOL use_group = parcel->getParcelFlag(PF_USE_ACCESS_GROUP); BOOL public_access = !use_access_list && !use_group; - childSetValue("public_access", public_access ); - childSetValue("GroupCheck", use_group ); + getChild("public_access")->setValue(public_access ); + getChild("GroupCheck")->setValue(use_group ); std::string group_name; gCacheName->getGroupName(parcel->getGroupID(), group_name); - childSetLabelArg("GroupCheck", "[GROUP]", group_name ); + getChild("GroupCheck")->setLabelArg("[GROUP]", group_name ); // Allow list if (mListAccess) @@ -2470,8 +2500,8 @@ void LLPanelLandAccess::refresh() mListAccess->clearSortOrder(); mListAccess->deleteAllItems(); S32 count = parcel->mAccessList.size(); - childSetToolTipArg("AccessList", "[LISTED]", llformat("%d",count)); - childSetToolTipArg("AccessList", "[MAX]", llformat("%d",PARCEL_MAX_ACCESS_LIST)); + getChild("AccessList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count)); + getChild("AccessList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST)); for (access_map_const_iterator cit = parcel->mAccessList.begin(); cit != parcel->mAccessList.end(); ++cit) @@ -2517,8 +2547,8 @@ void LLPanelLandAccess::refresh() mListBanned->deleteAllItems(); S32 count = parcel->mBanList.size(); - childSetToolTipArg("BannedList", "[LISTED]", llformat("%d",count)); - childSetToolTipArg("BannedList", "[MAX]", llformat("%d",PARCEL_MAX_ACCESS_LIST)); + getChild("BannedList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count)); + getChild("BannedList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST)); for (access_map_const_iterator cit = parcel->mBanList.begin(); cit != parcel->mBanList.end(); ++cit) @@ -2558,23 +2588,23 @@ void LLPanelLandAccess::refresh() if(parcel->getRegionDenyAnonymousOverride()) { - childSetValue("limit_payment", TRUE); + getChild("limit_payment")->setValue(TRUE); } else { - childSetValue("limit_payment", (parcel->getParcelFlag(PF_DENY_ANONYMOUS))); + getChild("limit_payment")->setValue((parcel->getParcelFlag(PF_DENY_ANONYMOUS))); } if(parcel->getRegionDenyAgeUnverifiedOverride()) { - childSetValue("limit_age_verified", TRUE); + getChild("limit_age_verified")->setValue(TRUE); } else { - childSetValue("limit_age_verified", (parcel->getParcelFlag(PF_DENY_AGEUNVERIFIED))); + getChild("limit_age_verified")->setValue((parcel->getParcelFlag(PF_DENY_AGEUNVERIFIED))); } BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST); - childSetValue("PassCheck", use_pass ); + getChild("PassCheck")->setValue(use_pass ); LLCtrlSelectionInterface* passcombo = childGetSelectionInterface("pass_combo"); if (passcombo) { @@ -2585,41 +2615,41 @@ void LLPanelLandAccess::refresh() } S32 pass_price = parcel->getPassPrice(); - childSetValue( "PriceSpin", (F32)pass_price ); - childSetLabelArg("PriceSpin", "[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol()); + getChild("PriceSpin")->setValue((F32)pass_price ); + getChild("PriceSpin")->setLabelArg("[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol()); F32 pass_hours = parcel->getPassHours(); - childSetValue( "HoursSpin", pass_hours ); + getChild("HoursSpin")->setValue(pass_hours ); } else { - childSetValue("public_access", FALSE); - childSetValue("limit_payment", FALSE); - childSetValue("limit_age_verified", FALSE); - childSetValue("GroupCheck", FALSE); - childSetLabelArg("GroupCheck", "[GROUP]", LLStringUtil::null ); - childSetValue("PassCheck", FALSE); - childSetValue("PriceSpin", (F32)PARCEL_PASS_PRICE_DEFAULT); - childSetValue( "HoursSpin", PARCEL_PASS_HOURS_DEFAULT ); - childSetToolTipArg("AccessList", "[LISTED]", llformat("%d",0)); - childSetToolTipArg("AccessList", "[MAX]", llformat("%d",0)); - childSetToolTipArg("BannedList", "[LISTED]", llformat("%d",0)); - childSetToolTipArg("BannedList", "[MAX]", llformat("%d",0)); + getChild("public_access")->setValue(FALSE); + getChild("limit_payment")->setValue(FALSE); + getChild("limit_age_verified")->setValue(FALSE); + getChild("GroupCheck")->setValue(FALSE); + getChild("GroupCheck")->setLabelArg("[GROUP]", LLStringUtil::null ); + getChild("PassCheck")->setValue(FALSE); + getChild("PriceSpin")->setValue((F32)PARCEL_PASS_PRICE_DEFAULT); + getChild("HoursSpin")->setValue(PARCEL_PASS_HOURS_DEFAULT ); + getChild("AccessList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",0)); + getChild("AccessList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",0)); + getChild("BannedList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",0)); + getChild("BannedList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",0)); } } void LLPanelLandAccess::refresh_ui() { - childSetEnabled("public_access", FALSE); - childSetEnabled("limit_payment", FALSE); - childSetEnabled("limit_age_verified", FALSE); - childSetEnabled("GroupCheck", FALSE); - childSetEnabled("PassCheck", FALSE); - childSetEnabled("pass_combo", FALSE); - childSetEnabled("PriceSpin", FALSE); - childSetEnabled("HoursSpin", FALSE); - childSetEnabled("AccessList", FALSE); - childSetEnabled("BannedList", FALSE); + getChildView("public_access")->setEnabled(FALSE); + getChildView("limit_payment")->setEnabled(FALSE); + getChildView("limit_age_verified")->setEnabled(FALSE); + getChildView("GroupCheck")->setEnabled(FALSE); + getChildView("PassCheck")->setEnabled(FALSE); + getChildView("pass_combo")->setEnabled(FALSE); + getChildView("PriceSpin")->setEnabled(FALSE); + getChildView("HoursSpin")->setEnabled(FALSE); + getChildView("AccessList")->setEnabled(FALSE); + getChildView("BannedList")->setEnabled(FALSE); LLParcel *parcel = mParcel->getParcel(); if (parcel) @@ -2627,73 +2657,73 @@ void LLPanelLandAccess::refresh_ui() BOOL can_manage_allowed = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_ALLOWED); BOOL can_manage_banned = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_BANNED); - childSetEnabled("public_access", can_manage_allowed); - BOOL public_access = childGetValue("public_access").asBoolean(); + getChildView("public_access")->setEnabled(can_manage_allowed); + BOOL public_access = getChild("public_access")->getValue().asBoolean(); if (public_access) { bool override = false; if(parcel->getRegionDenyAnonymousOverride()) { override = true; - childSetEnabled("limit_payment", FALSE); + getChildView("limit_payment")->setEnabled(FALSE); } else { - childSetEnabled("limit_payment", can_manage_allowed); + getChildView("limit_payment")->setEnabled(can_manage_allowed); } if(parcel->getRegionDenyAgeUnverifiedOverride()) { override = true; - childSetEnabled("limit_age_verified", FALSE); + getChildView("limit_age_verified")->setEnabled(FALSE); } else { - childSetEnabled("limit_age_verified", can_manage_allowed); + getChildView("limit_age_verified")->setEnabled(can_manage_allowed); } if (override) { - childSetToolTip("Only Allow", getString("estate_override")); + getChildView("Only Allow")->setToolTip(getString("estate_override")); } else { - childSetToolTip("Only Allow", std::string()); + getChildView("Only Allow")->setToolTip(std::string()); } - childSetEnabled("GroupCheck", FALSE); - childSetEnabled("PassCheck", FALSE); - childSetEnabled("pass_combo", FALSE); - childSetEnabled("AccessList", FALSE); + getChildView("GroupCheck")->setEnabled(FALSE); + getChildView("PassCheck")->setEnabled(FALSE); + getChildView("pass_combo")->setEnabled(FALSE); + getChildView("AccessList")->setEnabled(FALSE); } else { - childSetEnabled("limit_payment", FALSE); - childSetEnabled("limit_age_verified", FALSE); + getChildView("limit_payment")->setEnabled(FALSE); + getChildView("limit_age_verified")->setEnabled(FALSE); std::string group_name; if (gCacheName->getGroupName(parcel->getGroupID(), group_name)) { - childSetEnabled("GroupCheck", can_manage_allowed); + getChildView("GroupCheck")->setEnabled(can_manage_allowed); } - BOOL group_access = childGetValue("GroupCheck").asBoolean(); - BOOL sell_passes = childGetValue("PassCheck").asBoolean(); - childSetEnabled("PassCheck", can_manage_allowed); + BOOL group_access = getChild("GroupCheck")->getValue().asBoolean(); + BOOL sell_passes = getChild("PassCheck")->getValue().asBoolean(); + getChildView("PassCheck")->setEnabled(can_manage_allowed); if (sell_passes) { - childSetEnabled("pass_combo", group_access && can_manage_allowed); - childSetEnabled("PriceSpin", can_manage_allowed); - childSetEnabled("HoursSpin", can_manage_allowed); + getChildView("pass_combo")->setEnabled(group_access && can_manage_allowed); + getChildView("PriceSpin")->setEnabled(can_manage_allowed); + getChildView("HoursSpin")->setEnabled(can_manage_allowed); } } - childSetEnabled("AccessList", can_manage_allowed); + getChildView("AccessList")->setEnabled(can_manage_allowed); S32 allowed_list_count = parcel->mAccessList.size(); - childSetEnabled("add_allowed", can_manage_allowed && allowed_list_count < PARCEL_MAX_ACCESS_LIST); - BOOL has_selected = mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0; - childSetEnabled("remove_allowed", can_manage_allowed && has_selected); + getChildView("add_allowed")->setEnabled(can_manage_allowed && allowed_list_count < PARCEL_MAX_ACCESS_LIST); + BOOL has_selected = (mListAccess && mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0); + getChildView("remove_allowed")->setEnabled(can_manage_allowed && has_selected); - childSetEnabled("BannedList", can_manage_banned); + getChildView("BannedList")->setEnabled(can_manage_banned); S32 banned_list_count = parcel->mBanList.size(); - childSetEnabled("add_banned", can_manage_banned && banned_list_count < PARCEL_MAX_ACCESS_LIST); - has_selected = mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0; - childSetEnabled("remove_banned", can_manage_banned && has_selected); + getChildView("add_banned")->setEnabled(can_manage_banned && banned_list_count < PARCEL_MAX_ACCESS_LIST); + has_selected = (mListBanned && mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0); + getChildView("remove_banned")->setEnabled(can_manage_banned && has_selected); } } @@ -2707,7 +2737,7 @@ void LLPanelLandAccess::refreshNames() { gCacheName->getGroupName(parcel->getGroupID(), group_name); } - childSetLabelArg("GroupCheck", "[GROUP]", group_name); + getChild("GroupCheck")->setLabelArg("[GROUP]", group_name); } @@ -2730,13 +2760,13 @@ void LLPanelLandAccess::onCommitPublicAccess(LLUICtrl *ctrl, void *userdata) } // If we disabled public access, enable group access by default (if applicable) - BOOL public_access = self->childGetValue("public_access").asBoolean(); + BOOL public_access = self->getChild("public_access")->getValue().asBoolean(); if (public_access == FALSE) { std::string group_name; if (gCacheName->getGroupName(parcel->getGroupID(), group_name)) { - self->childSetValue("GroupCheck", public_access ? FALSE : TRUE); + self->getChild("GroupCheck")->setValue(public_access ? FALSE : TRUE); } } @@ -2755,8 +2785,8 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata) } // Extract data from UI - BOOL public_access = self->childGetValue("public_access").asBoolean(); - BOOL use_access_group = self->childGetValue("GroupCheck").asBoolean(); + BOOL public_access = self->getChild("public_access")->getValue().asBoolean(); + BOOL use_access_group = self->getChild("GroupCheck")->getValue().asBoolean(); if (use_access_group) { std::string group_name; @@ -2774,13 +2804,13 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata) { use_access_list = FALSE; use_access_group = FALSE; - limit_payment = self->childGetValue("limit_payment").asBoolean(); - limit_age_verified = self->childGetValue("limit_age_verified").asBoolean(); + limit_payment = self->getChild("limit_payment")->getValue().asBoolean(); + limit_age_verified = self->getChild("limit_age_verified")->getValue().asBoolean(); } else { use_access_list = TRUE; - use_pass_list = self->childGetValue("PassCheck").asBoolean(); + use_pass_list = self->getChild("PassCheck")->getValue().asBoolean(); if (use_access_group && use_pass_list) { LLCtrlSelectionInterface* passcombo = self->childGetSelectionInterface("pass_combo"); @@ -2794,8 +2824,8 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata) } } - S32 pass_price = llfloor((F32)self->childGetValue("PriceSpin").asReal()); - F32 pass_hours = (F32)self->childGetValue("HoursSpin").asReal(); + S32 pass_price = llfloor((F32)self->getChild("PriceSpin")->getValue().asReal()); + F32 pass_hours = (F32)self->getChild("HoursSpin")->getValue().asReal(); // Push data into current parcel parcel->setParcelFlag(PF_USE_ACCESS_GROUP, use_access_group); @@ -2815,13 +2845,13 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata) self->refresh(); } -// static -void LLPanelLandAccess::onClickAddAccess(void* data) +void LLPanelLandAccess::onClickAddAccess() { - LLPanelLandAccess* panelp = (LLPanelLandAccess*)data; - if (panelp) + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( + boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1)); + if (picker) { - gFloaterView->getParentFloater(panelp)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, panelp, _1))); + gFloaterView->getParentFloater(this)->addDependentFloater(picker); } } @@ -2863,11 +2893,14 @@ void LLPanelLandAccess::onClickRemoveAccess(void* data) } } -// static -void LLPanelLandAccess::onClickAddBanned(void* data) +void LLPanelLandAccess::onClickAddBanned() { - LLPanelLandAccess* panelp = (LLPanelLandAccess*)data; - gFloaterView->getParentFloater(panelp)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, panelp, _1))); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( + boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1)); + if (picker) + { + gFloaterView->getParentFloater(this)->addDependentFloater(picker); + } } void LLPanelLandAccess::callbackAvatarCBBanned(const uuid_vec_t& ids) diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index d7c0cfeef..4dd7b962b 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -49,11 +49,11 @@ class LLButton; class LLCheckBoxCtrl; class LLRadioGroup; class LLComboBox; -class LLNameListCtrl; -class LLSpinCtrl; class LLLineEditor; +class LLNameListCtrl; class LLRadioGroup; class LLParcelSelectionObserver; +class LLSpinCtrl; class LLTabContainer; class LLTextBox; class LLTextEditor; @@ -149,13 +149,13 @@ public: virtual void draw(); void setGroup(const LLUUID& group_id); - static void onClickProfile(void*); - static void onClickSetGroup(void*); + void onClickProfile(); + void onClickSetGroup(); static void onClickInfoGroup(void*); static void cbGroupID(LLUUID group_id, void* userdata); - static BOOL enableDeedToGroup(void*); static void onClickDeed(void*); static void onClickBuyLand(void* data); + static void onClickScriptLimits(void* data); static void onClickRelease(void*); static void onClickReclaim(void*); static void onClickBuyPass(void* deselect_when_done); @@ -225,6 +225,7 @@ protected: LLTextBox* mTextDwell; LLButton* mBtnBuyLand; + LLButton* mBtnScriptLimits; LLButton* mBtnBuyGroupLand; // these buttons share the same location, but @@ -361,6 +362,7 @@ private: LLButton* mClearBtn; LLCheckBoxCtrl *mMatureCtrl; + LLCheckBoxCtrl *mGamingCtrl; LLCheckBoxCtrl *mPushRestrictionCtrl; LLCheckBoxCtrl *mSeeAvatarsCtrl; LLButton *mPublishHelpButton; @@ -382,15 +384,16 @@ public: static void onCommitPublicAccess(LLUICtrl* ctrl, void *userdata); static void onCommitAny(LLUICtrl* ctrl, void *userdata); - static void onClickAddAccess(void*); - void callbackAvatarCBAccess(const uuid_vec_t& ids); static void onClickRemoveAccess(void*); - static void onClickAddBanned(void*); - void callbackAvatarCBBanned(const uuid_vec_t& ids); static void onClickRemoveBanned(void*); virtual BOOL postBuild(); + void onClickAddAccess(); + void onClickAddBanned(); + void callbackAvatarCBBanned(const uuid_vec_t& ids); + void callbackAvatarCBAccess(const uuid_vec_t& ids); + protected: LLNameListCtrl* mListAccess; LLNameListCtrl* mListBanned; diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp new file mode 100644 index 000000000..70022a6e2 --- /dev/null +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -0,0 +1,1352 @@ +/** + * @file llfloaterscriptlimits.cpp + * @author Gabriel Lee + * @brief Implementation of the region info and controls floater and panels. + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llhttpclient.h" +#include "llfloaterscriptlimits.h" + +// library includes +#include "llavatarnamecache.h" +#include "llsdutil.h" +#include "llsdutil_math.h" +#include "message.h" + +#include "llagent.h" +#include "llfloateravatarpicker.h" +#include "llfloaterland.h" +#include "llregionhandle.h" +#include "llscrolllistctrl.h" +#include "llparcel.h" +#include "lltabcontainer.h" +#include "lltracker.h" +#include "lltrans.h" +#include "llviewercontrol.h" +#include "lluictrlfactory.h" +#include "llviewerparcelmgr.h" +#include "llviewerregion.h" +#include "llviewerwindow.h" + +///---------------------------------------------------------------------------- +/// LLFloaterScriptLimits +///---------------------------------------------------------------------------- + +// debug switches, won't work in release +#ifndef LL_RELEASE_FOR_DOWNLOAD + +// dump responder replies to llinfos for debugging +//#define DUMP_REPLIES_TO_LLINFOS + +#ifdef DUMP_REPLIES_TO_LLINFOS +#include "llsdserialize.h" +#include "llwindow.h" +#endif + +// use fake LLSD responses to check the viewer side is working correctly +// I'm syncing this with the server side efforts so hopfully we can keep +// the to-ing and fro-ing between the two teams to a minimum +//#define USE_FAKE_RESPONSES + +#ifdef USE_FAKE_RESPONSES +const S32 FAKE_NUMBER_OF_URLS = 329; +const S32 FAKE_AVAILABLE_URLS = 731; +const S32 FAKE_AMOUNT_OF_MEMORY = 66741; +const S32 FAKE_AVAILABLE_MEMORY = 895577; +#endif + +#endif + +const S32 SIZE_OF_ONE_KB = 1024; + +LLFloaterScriptLimits::LLFloaterScriptLimits(const LLSD& seed) + : LLFloater(/*seed*/) +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_script_limits.xml"); +} + +BOOL LLFloaterScriptLimits::postBuild() +{ + // a little cheap and cheerful - if there's an about land panel open default to showing parcel info, + // otherwise default to showing attachments (avatar appearance) + bool selectParcelPanel = false; + + LLFloaterLand* instance = LLFloaterLand::getInstance(); + if(instance) + { + if(instance->instanceVisible()) + { + selectParcelPanel = true; + } + } + + mTab = getChild("scriptlimits_panels"); + + if(!mTab) + { + llwarns << "Error! couldn't get scriptlimits_panels, aborting Script Information setup" << llendl; + return FALSE; + } + + // contruct the panels + std::string land_url = gAgent.getRegion()->getCapability("LandResources"); + if (!land_url.empty()) + { + LLPanelScriptLimitsRegionMemory* panel_memory; + panel_memory = new LLPanelScriptLimitsRegionMemory; + mInfoPanels.push_back(panel_memory); + LLUICtrlFactory::getInstance()->buildPanel(panel_memory, "panel_script_limits_region_memory.xml"); + mTab->addTabPanel(panel_memory, "Region Memory"); + } + + std::string attachment_url = gAgent.getRegion()->getCapability("AttachmentResources"); + if (!attachment_url.empty()) + { + LLPanelScriptLimitsAttachment* panel_attachments = new LLPanelScriptLimitsAttachment; + mInfoPanels.push_back(panel_attachments); + LLUICtrlFactory::getInstance()->buildPanel(panel_attachments, "panel_script_limits_my_avatar.xml"); + mTab->addTabPanel(panel_attachments, "My Avatar"); + } + + if(mInfoPanels.size() > 0) + { + mTab->selectTab(0); + } + + if(!selectParcelPanel && (mInfoPanels.size() > 1)) + { + mTab->selectTab(1); + } + + return TRUE; +} + +LLFloaterScriptLimits::~LLFloaterScriptLimits() +{ +} + +// public +void LLFloaterScriptLimits::refresh() +{ + for(info_panels_t::iterator iter = mInfoPanels.begin(); + iter != mInfoPanels.end(); ++iter) + { + (*iter)->refresh(); + } +} + +///---------------------------------------------------------------------------- +// Base class for panels +///---------------------------------------------------------------------------- + +LLPanelScriptLimitsInfo::LLPanelScriptLimitsInfo() + : LLPanel() +{ +} + + +// virtual +BOOL LLPanelScriptLimitsInfo::postBuild() +{ + refresh(); + return TRUE; +} + +// virtual +void LLPanelScriptLimitsInfo::updateChild(LLUICtrl* child_ctr) +{ +} + +///---------------------------------------------------------------------------- +// Responders +///---------------------------------------------------------------------------- + +void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content) +{ + //we don't need to test with a fake response here (shouldn't anyway) + +#ifdef DUMP_REPLIES_TO_LLINFOS + + LLSDNotationStreamer notation_streamer(content); + std::ostringstream nice_llsd; + nice_llsd << notation_streamer; + + OSMessageBox(nice_llsd.str(), "main cap response:", 0); + + llinfos << "main cap response:" << content << llendl; + +#endif + + // at this point we have an llsd which should contain ether one or two urls to the services we want. + // first we look for the details service: + if(content.has("ScriptResourceDetails")) + { + LLHTTPClient::get(content["ScriptResourceDetails"], new fetchScriptLimitsRegionDetailsResponder(mInfo)); + } + else + { + LLFloaterScriptLimits* instance = LLFloaterScriptLimits::getInstance(); + if(!instance) + { + llwarns << "Failed to get llfloaterscriptlimits instance" << llendl; + } + } + + // then the summary service: + if(content.has("ScriptResourceSummary")) + { + LLHTTPClient::get(content["ScriptResourceSummary"], new fetchScriptLimitsRegionSummaryResponder(mInfo)); + } +} + +void fetchScriptLimitsRegionInfoResponder::error(U32 status, const std::string& reason) +{ + llwarns << "Error from responder " << reason << llendl; +} + +void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref) +{ +#ifdef USE_FAKE_RESPONSES + + LLSD fake_content; + LLSD summary = LLSD::emptyMap(); + LLSD available = LLSD::emptyArray(); + LLSD available_urls = LLSD::emptyMap(); + LLSD available_memory = LLSD::emptyMap(); + LLSD used = LLSD::emptyArray(); + LLSD used_urls = LLSD::emptyMap(); + LLSD used_memory = LLSD::emptyMap(); + + used_urls["type"] = "urls"; + used_urls["amount"] = FAKE_NUMBER_OF_URLS; + available_urls["type"] = "urls"; + available_urls["amount"] = FAKE_AVAILABLE_URLS; + used_memory["type"] = "memory"; + used_memory["amount"] = FAKE_AMOUNT_OF_MEMORY; + available_memory["type"] = "memory"; + available_memory["amount"] = FAKE_AVAILABLE_MEMORY; + +//summary response:{'summary':{'available':[{'amount':i731,'type':'urls'},{'amount':i895577,'type':'memory'},{'amount':i731,'type':'urls'},{'amount':i895577,'type':'memory'}],'used':[{'amount':i329,'type':'urls'},{'amount':i66741,'type':'memory'}]}} + + used.append(used_urls); + used.append(used_memory); + available.append(available_urls); + available.append(available_memory); + + summary["available"] = available; + summary["used"] = used; + + fake_content["summary"] = summary; + + const LLSD& content = fake_content; + +#else + + const LLSD& content = content_ref; + +#endif + + +#ifdef DUMP_REPLIES_TO_LLINFOS + + LLSDNotationStreamer notation_streamer(content); + std::ostringstream nice_llsd; + nice_llsd << notation_streamer; + + OSMessageBox(nice_llsd.str(), "summary response:", 0); + + llwarns << "summary response:" << *content << llendl; + +#endif + + LLFloaterScriptLimits* instance = LLFloaterScriptLimits::getInstance(); + if(!instance) + { + llwarns << "Failed to get llfloaterscriptlimits instance" << llendl; + } + else + { + LLTabContainer* tab = instance->getChild("scriptlimits_panels"); + if(tab) + { + LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild("script_limits_region_memory_panel"); + if(panel_memory) + { + panel_memory->getChild("loading_text")->setValue(LLSD(std::string(""))); + + LLButton* btn = panel_memory->getChild("refresh_list_btn"); + if(btn) + { + btn->setEnabled(true); + } + + panel_memory->setRegionSummary(content); + } + } + } +} + +void fetchScriptLimitsRegionSummaryResponder::error(U32 status, const std::string& reason) +{ + llwarns << "Error from responder " << reason << llendl; +} + +void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content_ref) +{ +#ifdef USE_FAKE_RESPONSES +/* +Updated detail service, ** denotes field added: + +result (map) ++-parcels (array of maps) + +-id (uuid) + +-local_id (S32)** + +-name (string) + +-owner_id (uuid) (in ERS as owner, but owner_id in code) + +-objects (array of maps) + +-id (uuid) + +-name (string) + +-owner_id (uuid) (in ERS as owner, in code as owner_id) + +-owner_name (sting)** + +-location (map)** + +-x (float) + +-y (float) + +-z (float) + +-resources (map) (this is wrong in the ERS but right in code) + +-type (string) + +-amount (int) +*/ + LLSD fake_content; + LLSD resource = LLSD::emptyMap(); + LLSD location = LLSD::emptyMap(); + LLSD object = LLSD::emptyMap(); + LLSD objects = LLSD::emptyArray(); + LLSD parcel = LLSD::emptyMap(); + LLSD parcels = LLSD::emptyArray(); + + resource["urls"] = FAKE_NUMBER_OF_URLS; + resource["memory"] = FAKE_AMOUNT_OF_MEMORY; + + location["x"] = 128.0f; + location["y"] = 128.0f; + location["z"] = 0.0f; + + object["id"] = LLUUID("d574a375-0c6c-fe3d-5733-da669465afc7"); + object["name"] = "Gabs fake Object!"; + object["owner_id"] = LLUUID("8dbf2d41-69a0-4e5e-9787-0c9d297bc570"); + object["owner_name"] = "Gabs Linden"; + object["location"] = location; + object["resources"] = resource; + + objects.append(object); + + parcel["id"] = LLUUID("da05fb28-0d20-e593-2728-bddb42dd0160"); + parcel["local_id"] = 42; + parcel["name"] = "Gabriel Linden\'s Sub Plot"; + parcel["objects"] = objects; + parcels.append(parcel); + + fake_content["parcels"] = parcels; + const LLSD& content = fake_content; + +#else + + const LLSD& content = content_ref; + +#endif + +#ifdef DUMP_REPLIES_TO_LLINFOS + + LLSDNotationStreamer notation_streamer(content); + std::ostringstream nice_llsd; + nice_llsd << notation_streamer; + + OSMessageBox(nice_llsd.str(), "details response:", 0); + + llinfos << "details response:" << content << llendl; + +#endif + + LLFloaterScriptLimits* instance = LLFloaterScriptLimits::getInstance(); + + if(!instance) + { + llwarns << "Failed to get llfloaterscriptlimits instance" << llendl; + } + else + { + LLTabContainer* tab = instance->getChild("scriptlimits_panels"); + if(tab) + { + LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild("script_limits_region_memory_panel"); + if(panel_memory) + { + panel_memory->setRegionDetails(content); + } + else + { + llwarns << "Failed to get scriptlimits memory panel" << llendl; + } + } + else + { + llwarns << "Failed to get scriptlimits_panels" << llendl; + } + } +} + +void fetchScriptLimitsRegionDetailsResponder::error(U32 status, const std::string& reason) +{ + llwarns << "Error from responder " << reason << llendl; +} + +void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref) +{ + +#ifdef USE_FAKE_RESPONSES + + // just add the summary, as that's all I'm testing currently! + LLSD fake_content = LLSD::emptyMap(); + LLSD summary = LLSD::emptyMap(); + LLSD available = LLSD::emptyArray(); + LLSD available_urls = LLSD::emptyMap(); + LLSD available_memory = LLSD::emptyMap(); + LLSD used = LLSD::emptyArray(); + LLSD used_urls = LLSD::emptyMap(); + LLSD used_memory = LLSD::emptyMap(); + + used_urls["type"] = "urls"; + used_urls["amount"] = FAKE_NUMBER_OF_URLS; + available_urls["type"] = "urls"; + available_urls["amount"] = FAKE_AVAILABLE_URLS; + used_memory["type"] = "memory"; + used_memory["amount"] = FAKE_AMOUNT_OF_MEMORY; + available_memory["type"] = "memory"; + available_memory["amount"] = FAKE_AVAILABLE_MEMORY; + + used.append(used_urls); + used.append(used_memory); + available.append(available_urls); + available.append(available_memory); + + summary["available"] = available; + summary["used"] = used; + + fake_content["summary"] = summary; + fake_content["attachments"] = content_ref["attachments"]; + + const LLSD& content = fake_content; + +#else + + const LLSD& content = content_ref; + +#endif + +#ifdef DUMP_REPLIES_TO_LLINFOS + + LLSDNotationStreamer notation_streamer(content); + std::ostringstream nice_llsd; + nice_llsd << notation_streamer; + + OSMessageBox(nice_llsd.str(), "attachment response:", 0); + + llinfos << "attachment response:" << content << llendl; + +#endif + + LLFloaterScriptLimits* instance = LLFloaterScriptLimits::getInstance(); + + if(!instance) + { + llwarns << "Failed to get llfloaterscriptlimits instance" << llendl; + } + else + { + LLTabContainer* tab = instance->getChild("scriptlimits_panels"); + if(tab) + { + LLPanelScriptLimitsAttachment* panel = (LLPanelScriptLimitsAttachment*)tab->getChild("script_limits_my_avatar_panel"); + if(panel) + { + panel->getChild("loading_text")->setValue(LLSD(std::string(""))); + + LLButton* btn = panel->getChild("refresh_list_btn"); + if(btn) + { + btn->setEnabled(true); + } + + panel->setAttachmentDetails(content); + } + else + { + llwarns << "Failed to get script_limits_my_avatar_panel" << llendl; + } + } + else + { + llwarns << "Failed to get scriptlimits_panels" << llendl; + } + } +} + +void fetchScriptLimitsAttachmentInfoResponder::error(U32 status, const std::string& reason) +{ + llwarns << "Error from responder " << reason << llendl; +} + +///---------------------------------------------------------------------------- +// Memory Panel +///---------------------------------------------------------------------------- + +LLPanelScriptLimitsRegionMemory::~LLPanelScriptLimitsRegionMemory() +{ + if(!mParcelId.isNull()) + { + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this); + mParcelId.setNull(); + } +}; + +BOOL LLPanelScriptLimitsRegionMemory::getLandScriptResources() +{ + LLSD body; + std::string url = gAgent.getRegion()->getCapability("LandResources"); + if (!url.empty()) + { + body["parcel_id"] = mParcelId; + + LLSD info; + info["parcel_id"] = mParcelId; + LLHTTPClient::post(url, body, new fetchScriptLimitsRegionInfoResponder(info)); + + return TRUE; + } + else + { + return FALSE; + } +} + +void LLPanelScriptLimitsRegionMemory::processParcelInfo(const LLParcelData& parcel_data) +{ + if(!getLandScriptResources()) + { + std::string msg_error = LLTrans::getString("ScriptLimitsRequestError"); + getChild("loading_text")->setValue(LLSD(msg_error)); + } + else + { + std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); + getChild("loading_text")->setValue(LLSD(msg_waiting)); + } +} + +void LLPanelScriptLimitsRegionMemory::setParcelID(const LLUUID& parcel_id) +{ + if (!parcel_id.isNull()) + { + if(!mParcelId.isNull()) + { + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this); + mParcelId.setNull(); + } + mParcelId = parcel_id; + LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this); + LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id); + } + else + { + std::string msg_error = LLTrans::getString("ScriptLimitsRequestError"); + getChild("loading_text")->setValue(LLSD(msg_error)); + } +} + +// virtual +void LLPanelScriptLimitsRegionMemory::setErrorStatus(U32 status, const std::string& reason) +{ + llwarns << "Can't handle remote parcel request."<< " Http Status: "<< status << ". Reason : "<< reason<("scripts_list"); + if(!list) + { + return; + } + + std::string name; + if (LLAvatarNameCache::useDisplayNames()) + { + name = LLCacheName::buildUsername(full_name); + } + else + { + name = full_name; + } + + std::vector::iterator id_itor; + for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor) + { + LLSD element = *id_itor; + if(element["owner_id"].asUUID() == id) + { + LLScrollListItem* item = list->getItem(element["id"].asUUID()); + + if(item) + { + item->getColumn(3)->setValue(LLSD(name)); + element["columns"][3]["value"] = name; + } + } + } +} + +void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content) +{ + LLScrollListCtrl *list = getChild("scripts_list"); + + if(!list) + { + llwarns << "Error getting the scripts_list control" << llendl; + return; + } + + S32 number_parcels = content["parcels"].size(); + + LLStringUtil::format_map_t args_parcels; + args_parcels["[PARCELS]"] = llformat ("%d", number_parcels); + std::string msg_parcels = LLTrans::getString("ScriptLimitsParcelsOwned", args_parcels); + getChild("parcels_listed")->setValue(LLSD(msg_parcels)); + + uuid_vec_t names_requested; + + // This makes the assumption that all objects will have the same set + // of attributes, ie they will all have, or none will have locations + // This is a pretty safe assumption as it's reliant on server version. + bool has_locations = false; + bool has_local_ids = false; + + for(S32 i = 0; i < number_parcels; i++) + { + std::string parcel_name = content["parcels"][i]["name"].asString(); + LLUUID parcel_id = content["parcels"][i]["id"].asUUID(); + S32 number_objects = content["parcels"][i]["objects"].size(); + + S32 local_id = 0; + if(content["parcels"][i].has("local_id")) + { + // if any locations are found flag that we can use them and turn on the highlight button + has_local_ids = true; + local_id = content["parcels"][i]["local_id"].asInteger(); + } + + for(S32 j = 0; j < number_objects; j++) + { + S32 size = content["parcels"][i]["objects"][j]["resources"]["memory"].asInteger() / SIZE_OF_ONE_KB; + + S32 urls = content["parcels"][i]["objects"][j]["resources"]["urls"].asInteger(); + + std::string name_buf = content["parcels"][i]["objects"][j]["name"].asString(); + LLUUID task_id = content["parcels"][i]["objects"][j]["id"].asUUID(); + LLUUID owner_id = content["parcels"][i]["objects"][j]["owner_id"].asUUID(); + // This field may not be sent by all server versions, but it's OK if + // it uses the LLSD default of false + bool is_group_owned = content["parcels"][i]["objects"][j]["is_group_owned"].asBoolean(); + + F32 location_x = 0.0f; + F32 location_y = 0.0f; + F32 location_z = 0.0f; + + if(content["parcels"][i]["objects"][j].has("location")) + { + // if any locations are found flag that we can use them and turn on the highlight button + LLVector3 vec = ll_vector3_from_sd(content["parcels"][i]["objects"][j]["location"]); + has_locations = true; + location_x = vec.mV[0]; + location_y = vec.mV[1]; + location_z = vec.mV[2]; + } + + std::string owner_buf; + + // in the future the server will give us owner names, so see if we're there yet: + if(content["parcels"][i]["objects"][j].has("owner_name")) + { + owner_buf = content["parcels"][i]["objects"][j]["owner_name"].asString(); + } + // ...and if not use the slightly more painful method of disovery: + else + { + BOOL name_is_cached; + if (is_group_owned) + { + name_is_cached = gCacheName->getGroupName(owner_id, owner_buf); + } + else + { + name_is_cached = LLAvatarNameCache::getPNSName(owner_id, owner_buf); // username + } + if(!name_is_cached) + { + if(std::find(names_requested.begin(), names_requested.end(), owner_id) == names_requested.end()) + { + names_requested.push_back(owner_id); + gCacheName->get(owner_id, is_group_owned, // username + boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache, + this, _1, _2)); + } + } + } + + LLSD item_params; + item_params["id"] = task_id; + + item_params["columns"][0]["column"] = "size"; + item_params["columns"][0]["value"] = size; + + item_params["columns"][1]["column"] = "urls"; + item_params["columns"][1]["value"] = urls; + + item_params["columns"][2]["column"] = "name"; + item_params["columns"][2]["value"] = name_buf; + + item_params["columns"][3]["column"] = "owner"; + item_params["columns"][3]["value"] = owner_buf; + + item_params["columns"][4]["column"] = "parcel"; + item_params["columns"][4]["value"] = parcel_name; + + item_params["columns"][5]["column"] = "location"; + item_params["columns"][5]["value"] = has_locations + ? llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z) + : ""; + + list->addElement(item_params); + + LLSD element; + element["owner_id"] = owner_id; + + element["id"] = task_id; + element["local_id"] = local_id; + mObjectListItems.push_back(element); + } + } + + if (has_locations) + { + LLButton* btn = getChild("highlight_btn"); + if(btn) + { + btn->setVisible(true); + } + } + + if (has_local_ids) + { + LLButton* btn = getChild("return_btn"); + if(btn) + { + btn->setVisible(true); + } + } + + // save the structure to make object return easier + mContent = content; +} + +void LLPanelScriptLimitsRegionMemory::setRegionSummary(LLSD content) +{ + if(content["summary"]["used"][0]["type"].asString() == std::string("memory")) + { + mParcelMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; + mParcelMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; + mGotParcelMemoryUsed = true; + } + else if(content["summary"]["used"][1]["type"].asString() == std::string("memory")) + { + mParcelMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; + mParcelMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; + mGotParcelMemoryUsed = true; + } + else + { + llwarns << "summary doesn't contain memory info" << llendl; + return; + } + + if(content["summary"]["used"][0]["type"].asString() == std::string("urls")) + { + mParcelURLsUsed = content["summary"]["used"][0]["amount"].asInteger(); + mParcelURLsMax = content["summary"]["available"][0]["amount"].asInteger(); + mGotParcelURLsUsed = true; + } + else if(content["summary"]["used"][1]["type"].asString() == std::string("urls")) + { + mParcelURLsUsed = content["summary"]["used"][1]["amount"].asInteger(); + mParcelURLsMax = content["summary"]["available"][1]["amount"].asInteger(); + mGotParcelURLsUsed = true; + } + else + { + llwarns << "summary doesn't contain urls info" << llendl; + return; + } + + if((mParcelMemoryUsed >= 0) && (mParcelMemoryMax >= 0)) + { + S32 parcel_memory_available = mParcelMemoryMax - mParcelMemoryUsed; + + LLStringUtil::format_map_t args_parcel_memory; + args_parcel_memory["[COUNT]"] = llformat ("%d", mParcelMemoryUsed); + args_parcel_memory["[MAX]"] = llformat ("%d", mParcelMemoryMax); + args_parcel_memory["[AVAILABLE]"] = llformat ("%d", parcel_memory_available); + std::string msg_parcel_memory = LLTrans::getString("ScriptLimitsMemoryUsed", args_parcel_memory); + getChild("memory_used")->setValue(LLSD(msg_parcel_memory)); + } + + if((mParcelURLsUsed >= 0) && (mParcelURLsMax >= 0)) + { + S32 parcel_urls_available = mParcelURLsMax - mParcelURLsUsed; + + LLStringUtil::format_map_t args_parcel_urls; + args_parcel_urls["[COUNT]"] = llformat ("%d", mParcelURLsUsed); + args_parcel_urls["[MAX]"] = llformat ("%d", mParcelURLsMax); + args_parcel_urls["[AVAILABLE]"] = llformat ("%d", parcel_urls_available); + std::string msg_parcel_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_parcel_urls); + getChild("urls_used")->setValue(LLSD(msg_parcel_urls)); + } +} + +BOOL LLPanelScriptLimitsRegionMemory::postBuild() +{ + childSetAction("refresh_list_btn", onClickRefresh, this); + childSetAction("highlight_btn", onClickHighlight, this); + childSetAction("return_btn", onClickReturn, this); + + std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); + getChild("loading_text")->setValue(LLSD(msg_waiting)); + + LLScrollListCtrl *list = getChild("scripts_list"); + if(!list) + { + return FALSE; + } + + //set all columns to resizable mode even if some columns will be empty + for(S32 column = 0; column < list->getNumColumns(); column++) + { + LLScrollListColumn* columnp = list->getColumn(column); + columnp->mHeader->setHasResizableElement(TRUE); + } + + return StartRequestChain(); +} + +BOOL LLPanelScriptLimitsRegionMemory::StartRequestChain() +{ + LLUUID region_id; + + LLFloaterLand* instance = LLFloaterLand::getInstance(); + if(!instance) + { + getChild("loading_text")->setValue(LLSD(std::string(""))); + //might have to do parent post build here + //if not logic below could use early outs + return FALSE; + } + LLParcel* parcel = instance->getCurrentSelectedParcel(); + LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); + if (!parcel) //Pretend we have the parcel we're on selected. + { + parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + region = gAgent.getRegion(); + } + + LLUUID current_region_id = gAgent.getRegion()->getRegionID(); + + if ((region) && (parcel)) + { + LLVector3 parcel_center = parcel->getCenterpoint(); + + region_id = region->getRegionID(); + + if(region_id != current_region_id) + { + std::string msg_wrong_region = LLTrans::getString("ScriptLimitsRequestWrongRegion"); + getChild("loading_text")->setValue(LLSD(msg_wrong_region)); + return FALSE; + } + + LLVector3d pos_global = region->getCenterGlobal(); + + LLSD body; + std::string url = region->getCapability("RemoteParcelRequest"); + if (!url.empty()) + { + body["location"] = ll_sd_from_vector3(parcel_center); + if (!region_id.isNull()) + { + body["region_id"] = region_id; + } + if (!pos_global.isExactlyZero()) + { + U64 region_handle = to_region_handle(pos_global); + body["region_handle"] = ll_sd_from_U64(region_handle); + } + LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(getObserverHandle())); + } + else + { + llwarns << "Can't get parcel info for script information request" << region_id + << ". Region: " << region->getName() + << " does not support RemoteParcelRequest" << llendl; + + std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestError"); + getChild("loading_text")->setValue(LLSD(msg_waiting)); + } + } + else + { + std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestNoParcelSelected"); + getChild("loading_text")->setValue(LLSD(msg_waiting)); + } + + return LLPanelScriptLimitsInfo::postBuild(); +} + +void LLPanelScriptLimitsRegionMemory::clearList() +{ + LLCtrlListInterface *list = childGetListInterface("scripts_list"); + + if (list) + { + list->operateOnAll(LLCtrlListInterface::OP_DELETE); + } + + mGotParcelMemoryUsed = false; + mGotParcelMemoryMax = false; + mGotParcelURLsUsed = false; + mGotParcelURLsMax = false; + + std::string msg_empty_string(""); + getChild("memory_used")->setValue(LLSD(msg_empty_string)); + getChild("urls_used")->setValue(LLSD(msg_empty_string)); + getChild("parcels_listed")->setValue(LLSD(msg_empty_string)); + + mObjectListItems.clear(); +} + +// static +void LLPanelScriptLimitsRegionMemory::onClickRefresh(void* userdata) +{ + LLFloaterScriptLimits* instance = LLFloaterScriptLimits::getInstance(); + if(instance) + { + LLTabContainer* tab = instance->getChild("scriptlimits_panels"); + if(tab) + { + LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild("script_limits_region_memory_panel"); + if(panel_memory) + { + //To stop people from hammering the refesh button and accidentally dosing themselves - enough requests can crash the viewer! + //turn the button off, then turn it on when we get a response + LLButton* btn = panel_memory->getChild("refresh_list_btn"); + if(btn) + { + btn->setEnabled(false); + } + panel_memory->clearList(); + + panel_memory->StartRequestChain(); + } + } + return; + } + else + { + llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after refresh button clicked" << llendl; + return; + } +} + +void LLPanelScriptLimitsRegionMemory::showBeacon() +{ + LLScrollListCtrl* list = getChild("scripts_list"); + if (!list) return; + + LLScrollListItem* first_selected = list->getFirstSelected(); + if (!first_selected) return; + + std::string name = first_selected->getColumn(2)->getValue().asString(); + std::string pos_string = first_selected->getColumn(5)->getValue().asString(); + + F32 x, y, z; + S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z); + if (matched != 3) return; + + LLVector3 pos_agent(x, y, z); + LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent); + + std::string tooltip(""); + LLTracker::trackLocation(pos_global, name, tooltip, LLTracker::LOCATION_ITEM); +} + +// static +void LLPanelScriptLimitsRegionMemory::onClickHighlight(void* userdata) +{ + LLFloaterScriptLimits* instance = LLFloaterScriptLimits::getInstance(); + if(instance) + { + LLTabContainer* tab = instance->getChild("scriptlimits_panels"); + if(tab) + { + LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild("script_limits_region_memory_panel"); + if(panel) + { + panel->showBeacon(); + } + } + return; + } + else + { + llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << llendl; + return; + } +} + +void LLPanelScriptLimitsRegionMemory::returnObjectsFromParcel(S32 local_id) +{ + LLMessageSystem *msg = gMessageSystem; + + LLViewerRegion* region = gAgent.getRegion(); + if (!region) return; + + LLCtrlListInterface *list = childGetListInterface("scripts_list"); + if (!list || list->getItemCount() == 0) return; + + std::vector::iterator id_itor; + + bool start_message = true; + + for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor) + { + LLSD element = *id_itor; + if (!list->isSelected(element["id"].asUUID())) + { + // Selected only + continue; + } + + if(element["local_id"].asInteger() != local_id) + { + // Not the parcel we are looking for + continue; + } + + if (start_message) + { + msg->newMessageFast(_PREHASH_ParcelReturnObjects); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ParcelData); + msg->addS32Fast(_PREHASH_LocalID, element["local_id"].asInteger()); + msg->addU32Fast(_PREHASH_ReturnType, RT_LIST); + start_message = false; + } + + msg->nextBlockFast(_PREHASH_TaskIDs); + msg->addUUIDFast(_PREHASH_TaskID, element["id"].asUUID()); + + if (msg->isSendFullFast(_PREHASH_TaskIDs)) + { + msg->sendReliable(region->getHost()); + start_message = true; + } + } + + if (!start_message) + { + msg->sendReliable(region->getHost()); + } +} + +void LLPanelScriptLimitsRegionMemory::returnObjects() +{ + if(!mContent.has("parcels")) + { + return; + } + + S32 number_parcels = mContent["parcels"].size(); + + // a message per parcel containing all objects to be returned from that parcel + for(S32 i = 0; i < number_parcels; i++) + { + S32 local_id = 0; + if(mContent["parcels"][i].has("local_id")) + { + local_id = mContent["parcels"][i]["local_id"].asInteger(); + returnObjectsFromParcel(local_id); + } + } + + onClickRefresh(NULL); +} + + +// static +void LLPanelScriptLimitsRegionMemory::onClickReturn(void* userdata) +{ + LLFloaterScriptLimits* instance = LLFloaterScriptLimits::getInstance(); + if(instance) + { + LLTabContainer* tab = instance->getChild("scriptlimits_panels"); + if(tab) + { + LLPanelScriptLimitsRegionMemory* panel = (LLPanelScriptLimitsRegionMemory*)tab->getChild("script_limits_region_memory_panel"); + if(panel) + { + panel->returnObjects(); + } + } + return; + } + else + { + llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after highlight button clicked" << llendl; + return; + } +} + +///---------------------------------------------------------------------------- +// Attachment Panel +///---------------------------------------------------------------------------- + +BOOL LLPanelScriptLimitsAttachment::requestAttachmentDetails() +{ + LLSD body; + std::string url = gAgent.getRegion()->getCapability("AttachmentResources"); + if (!url.empty()) + { + LLHTTPClient::get(url, body, new fetchScriptLimitsAttachmentInfoResponder()); + return TRUE; + } + else + { + return FALSE; + } +} + +void LLPanelScriptLimitsAttachment::setAttachmentDetails(LLSD content) +{ + LLScrollListCtrl *list = getChild("scripts_list"); + + if(!list) + { + return; + } + + S32 number_attachments = content["attachments"].size(); + + for(int i = 0; i < number_attachments; i++) + { + std::string humanReadableLocation = ""; + if(content["attachments"][i].has("location")) + { + std::string actualLocation = content["attachments"][i]["location"]; + humanReadableLocation = LLTrans::getString(actualLocation.c_str()); + } + + S32 number_objects = content["attachments"][i]["objects"].size(); + for(int j = 0; j < number_objects; j++) + { + LLUUID task_id = content["attachments"][i]["objects"][j]["id"].asUUID(); + S32 size = 0; + if(content["attachments"][i]["objects"][j]["resources"].has("memory")) + { + size = content["attachments"][i]["objects"][j]["resources"]["memory"].asInteger() / SIZE_OF_ONE_KB; + } + S32 urls = 0; + if(content["attachments"][i]["objects"][j]["resources"].has("urls")) + { + urls = content["attachments"][i]["objects"][j]["resources"]["urls"].asInteger(); + } + std::string name = content["attachments"][i]["objects"][j]["name"].asString(); + + LLSD element; + + element["id"] = task_id; + element["columns"][0]["column"] = "size"; + element["columns"][0]["value"] = llformat("%d", size); + element["columns"][0]["font"] = "SANSSERIF"; + + element["columns"][1]["column"] = "urls"; + element["columns"][1]["value"] = llformat("%d", urls); + element["columns"][1]["font"] = "SANSSERIF"; + + element["columns"][2]["column"] = "name"; + element["columns"][2]["value"] = name; + element["columns"][2]["font"] = "SANSSERIF"; + + element["columns"][3]["column"] = "location"; + element["columns"][3]["value"] = humanReadableLocation; + element["columns"][3]["font"] = "SANSSERIF"; + + list->addElement(element); + } + } + + setAttachmentSummary(content); + + getChild("loading_text")->setValue(LLSD(std::string(""))); + + LLButton* btn = getChild("refresh_list_btn"); + if(btn) + { + btn->setEnabled(true); + } +} + +BOOL LLPanelScriptLimitsAttachment::postBuild() +{ + childSetAction("refresh_list_btn", onClickRefresh, this); + + std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); + getChild("loading_text")->setValue(LLSD(msg_waiting)); + return requestAttachmentDetails(); +} + +void LLPanelScriptLimitsAttachment::clearList() +{ + LLCtrlListInterface *list = childGetListInterface("scripts_list"); + + if (list) + { + list->operateOnAll(LLCtrlListInterface::OP_DELETE); + } + + std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); + getChild("loading_text")->setValue(LLSD(msg_waiting)); +} + +void LLPanelScriptLimitsAttachment::setAttachmentSummary(LLSD content) +{ + if(content["summary"]["used"][0]["type"].asString() == std::string("memory")) + { + mAttachmentMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; + mAttachmentMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; + mGotAttachmentMemoryUsed = true; + } + else if(content["summary"]["used"][1]["type"].asString() == std::string("memory")) + { + mAttachmentMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; + mAttachmentMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; + mGotAttachmentMemoryUsed = true; + } + else + { + llwarns << "attachment details don't contain memory summary info" << llendl; + return; + } + + if(content["summary"]["used"][0]["type"].asString() == std::string("urls")) + { + mAttachmentURLsUsed = content["summary"]["used"][0]["amount"].asInteger(); + mAttachmentURLsMax = content["summary"]["available"][0]["amount"].asInteger(); + mGotAttachmentURLsUsed = true; + } + else if(content["summary"]["used"][1]["type"].asString() == std::string("urls")) + { + mAttachmentURLsUsed = content["summary"]["used"][1]["amount"].asInteger(); + mAttachmentURLsMax = content["summary"]["available"][1]["amount"].asInteger(); + mGotAttachmentURLsUsed = true; + } + else + { + llwarns << "attachment details don't contain urls summary info" << llendl; + return; + } + + if((mAttachmentMemoryUsed >= 0) && (mAttachmentMemoryMax >= 0)) + { + S32 attachment_memory_available = mAttachmentMemoryMax - mAttachmentMemoryUsed; + + LLStringUtil::format_map_t args_attachment_memory; + args_attachment_memory["[COUNT]"] = llformat ("%d", mAttachmentMemoryUsed); + args_attachment_memory["[MAX]"] = llformat ("%d", mAttachmentMemoryMax); + args_attachment_memory["[AVAILABLE]"] = llformat ("%d", attachment_memory_available); + std::string msg_attachment_memory = LLTrans::getString("ScriptLimitsMemoryUsed", args_attachment_memory); + getChild("memory_used")->setValue(LLSD(msg_attachment_memory)); + } + + if((mAttachmentURLsUsed >= 0) && (mAttachmentURLsMax >= 0)) + { + S32 attachment_urls_available = mAttachmentURLsMax - mAttachmentURLsUsed; + + LLStringUtil::format_map_t args_attachment_urls; + args_attachment_urls["[COUNT]"] = llformat ("%d", mAttachmentURLsUsed); + args_attachment_urls["[MAX]"] = llformat ("%d", mAttachmentURLsMax); + args_attachment_urls["[AVAILABLE]"] = llformat ("%d", attachment_urls_available); + std::string msg_attachment_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_attachment_urls); + getChild("urls_used")->setValue(LLSD(msg_attachment_urls)); + } +} + +// static +void LLPanelScriptLimitsAttachment::onClickRefresh(void* userdata) +{ + LLFloaterScriptLimits* instance = LLFloaterScriptLimits::getInstance(); + if(instance) + { + LLTabContainer* tab = instance->getChild("scriptlimits_panels"); + LLPanelScriptLimitsAttachment* panel_attachments = (LLPanelScriptLimitsAttachment*)tab->getChild("script_limits_my_avatar_panel"); + LLButton* btn = panel_attachments->getChild("refresh_list_btn"); + + //To stop people from hammering the refesh button and accidentally dosing themselves - enough requests can crash the viewer! + //turn the button off, then turn it on when we get a response + if(btn) + { + btn->setEnabled(false); + } + panel_attachments->clearList(); + panel_attachments->requestAttachmentDetails(); + + return; + } + else + { + llwarns << "could not find LLPanelScriptLimitsRegionMemory instance after refresh button clicked" << llendl; + return; + } +} + diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h new file mode 100644 index 000000000..a31d49629 --- /dev/null +++ b/indra/newview/llfloaterscriptlimits.h @@ -0,0 +1,271 @@ +/** + * @file llfloaterscriptlimits.h + * @author Gabriel Lee + * @brief Declaration of the region info and controls floater and panels. + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERSCRIPTLIMITS_H +#define LL_LLFLOATERSCRIPTLIMITS_H + +#include +#include "llfloater.h" +#include "llhost.h" +#include "llpanel.h" +#include "llremoteparcelrequest.h" + +class LLPanelScriptLimitsInfo; +class LLTabContainer; + +class LLPanelScriptLimitsRegionMemory; + +class LLFloaterScriptLimits : public LLFloater, public LLFloaterSingleton +{ + friend class LLUISingleton >; +public: + + /*virtual*/ BOOL postBuild(); + + // from LLPanel + virtual void refresh(); + +private: + + LLFloaterScriptLimits(const LLSD& seed); + ~LLFloaterScriptLimits(); + +protected: + + LLTabContainer* mTab; + typedef std::vector info_panels_t; + info_panels_t mInfoPanels; +}; + + +// Base class for all script limits information panels. +class LLPanelScriptLimitsInfo : public LLPanel +{ +public: + LLPanelScriptLimitsInfo(); + + virtual BOOL postBuild(); + virtual void updateChild(LLUICtrl* child_ctrl); + +protected: + void initCtrl(const std::string& name); + + typedef std::vector strings_t; + + LLHost mHost; +}; + +///////////////////////////////////////////////////////////////////////////// +// Responders +///////////////////////////////////////////////////////////////////////////// +class AIHTTPTimeoutPolicy; + +extern AIHTTPTimeoutPolicy fetchScriptLimitsRegionInfoResponder_timeout; +class fetchScriptLimitsRegionInfoResponder: public LLHTTPClient::ResponderWithResult +{ + public: + fetchScriptLimitsRegionInfoResponder(const LLSD& info) : mInfo(info) {}; + + void result(const LLSD& content); + void error(U32 status, const std::string& reason); + public: + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchScriptLimitsRegionInfoResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "fetchScriptLimitsRegionInfoResponder"; } + protected: + LLSD mInfo; +}; + +extern AIHTTPTimeoutPolicy fetchScriptLimitsRegionSummaryResponder_timeout; +class fetchScriptLimitsRegionSummaryResponder: public LLHTTPClient::ResponderWithResult +{ + public: + fetchScriptLimitsRegionSummaryResponder(const LLSD& info) : mInfo(info) {}; + + void result(const LLSD& content); + void error(U32 status, const std::string& reason); + public: + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchScriptLimitsRegionSummaryResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "fetchScriptLimitsRegionSummaryResponder"; } + protected: + LLSD mInfo; +}; + +extern AIHTTPTimeoutPolicy fetchScriptLimitsRegionDetailsResponder_timeout; +class fetchScriptLimitsRegionDetailsResponder: public LLHTTPClient::ResponderWithResult +{ + public: + fetchScriptLimitsRegionDetailsResponder(const LLSD& info) : mInfo(info) {}; + + void result(const LLSD& content); + void error(U32 status, const std::string& reason); + public: + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchScriptLimitsRegionDetailsResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "fetchScriptLimitsRegionDetailsResponder"; } + protected: + LLSD mInfo; +}; + +extern AIHTTPTimeoutPolicy fetchScriptLimitsAttachmentInfoResponder_timeout; +class fetchScriptLimitsAttachmentInfoResponder: public LLHTTPClient::ResponderWithResult +{ + public: + fetchScriptLimitsAttachmentInfoResponder() {}; + + void result(const LLSD& content); + void error(U32 status, const std::string& reason); + public: + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return fetchScriptLimitsAttachmentInfoResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "fetchScriptLimitsAttachmentInfoResponder"; } + protected: +}; + +///////////////////////////////////////////////////////////////////////////// +// Memory panel +///////////////////////////////////////////////////////////////////////////// + +class LLPanelScriptLimitsRegionMemory : public LLPanelScriptLimitsInfo, LLRemoteParcelInfoObserver +{ + +public: + LLPanelScriptLimitsRegionMemory() + : LLPanelScriptLimitsInfo(), LLRemoteParcelInfoObserver(), + + mParcelId(LLUUID()), + mGotParcelMemoryUsed(false), + mGotParcelMemoryMax(false), + mParcelMemoryMax(0), + mParcelMemoryUsed(0) {}; + + ~LLPanelScriptLimitsRegionMemory(); + + // LLPanel + virtual BOOL postBuild(); + + void setRegionDetails(LLSD content); + void setRegionSummary(LLSD content); + + BOOL StartRequestChain(); + + BOOL getLandScriptResources(); + void clearList(); + void showBeacon(); + void returnObjectsFromParcel(S32 local_id); + void returnObjects(); + +private: + void onNameCache(const LLUUID& id, + const std::string& name); + + LLSD mContent; + LLUUID mParcelId; + bool mGotParcelMemoryUsed; + bool mGotParcelMemoryUsedDetails; + bool mGotParcelMemoryMax; + S32 mParcelMemoryMax; + S32 mParcelMemoryUsed; + S32 mParcelMemoryUsedDetails; + + bool mGotParcelURLsUsed; + bool mGotParcelURLsUsedDetails; + bool mGotParcelURLsMax; + S32 mParcelURLsMax; + S32 mParcelURLsUsed; + S32 mParcelURLsUsedDetails; + + std::vector mObjectListItems; + +protected: + +// LLRemoteParcelInfoObserver interface: +/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); +/*virtual*/ void setParcelID(const LLUUID& parcel_id); +/*virtual*/ void setErrorStatus(U32 status, const std::string& reason); + + static void onClickRefresh(void* userdata); + static void onClickHighlight(void* userdata); + static void onClickReturn(void* userdata); +}; + +///////////////////////////////////////////////////////////////////////////// +// Attachment panel +///////////////////////////////////////////////////////////////////////////// + +class LLPanelScriptLimitsAttachment : public LLPanelScriptLimitsInfo +{ + +public: + LLPanelScriptLimitsAttachment() + : LLPanelScriptLimitsInfo(), + mGotAttachmentMemoryUsed(false), + mGotAttachmentMemoryUsedDetails(false), + mGotAttachmentMemoryMax(false), + mAttachmentMemoryMax(0), + mAttachmentMemoryUsed(0), + mAttachmentMemoryUsedDetails(0), + mGotAttachmentURLsUsed(false), + mGotAttachmentURLsUsedDetails(false), + mGotAttachmentURLsMax(false), + mAttachmentURLsMax(0), + mAttachmentURLsUsed(0), + mAttachmentURLsUsedDetails(0) + {}; + + ~LLPanelScriptLimitsAttachment() + { + }; + + // LLPanel + virtual BOOL postBuild(); + + void setAttachmentDetails(LLSD content); + + void setAttachmentSummary(LLSD content); + BOOL requestAttachmentDetails(); + void clearList(); + +private: + + bool mGotAttachmentMemoryUsed; + bool mGotAttachmentMemoryUsedDetails; + bool mGotAttachmentMemoryMax; + S32 mAttachmentMemoryMax; + S32 mAttachmentMemoryUsed; + S32 mAttachmentMemoryUsedDetails; + + bool mGotAttachmentURLsUsed; + bool mGotAttachmentURLsUsedDetails; + bool mGotAttachmentURLsMax; + S32 mAttachmentURLsMax; + S32 mAttachmentURLsUsed; + S32 mAttachmentURLsUsedDetails; + +protected: + + static void onClickRefresh(void* userdata); +}; + +#endif diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 3ce3eb188..051e5f7da 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -71,6 +71,7 @@ #include "lluistring.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" +#include "llenvmanager.h" namespace { @@ -253,6 +254,9 @@ void LLMuteList::loadUserVolumes() { mUserVolumeSettings.insert(std::make_pair(LLUUID(iter->first), (F32)iter->second.asReal())); } + + LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLMuteList::checkNewRegion, this)); + checkNewRegion(); } //----------------------------------------------------------------------------- @@ -280,8 +284,18 @@ LLMuteList::~LLMuteList() } } +bool LLMuteList::isLinden(const LLUUID& id) const +{ + std::string name; + gCacheName->getFullName(id, name); + return isLinden(name); +} + BOOL LLMuteList::isLinden(const std::string& name) const { + if (mGodFullNames.find(name) != mGodFullNames.end()) return true; + if (mGodLastNames.empty()) return false; + typedef boost::tokenizer > tokenizer; boost::char_separator sep(" "); tokenizer tokens(name, sep); @@ -292,7 +306,7 @@ BOOL LLMuteList::isLinden(const std::string& name) const if (token_iter == tokens.end()) return FALSE; std::string last_name = *token_iter; - return last_name == "Linden"; + return mGodLastNames.find(last_name) != mGodLastNames.end(); } static LLVOAvatar* find_avatar(const LLUUID& id) @@ -542,7 +556,7 @@ void notify_automute_callback(const LLUUID& agent_id, const std::string& full_na LLSD args; args["NAME"] = full_name; - + LLNotificationPtr notif_ptr = LLNotifications::instance().add(notif_name, args); if (notif_ptr) { @@ -878,3 +892,53 @@ void LLMuteList::notifyObservers() it = mObservers.upper_bound(observer); } } + +void LLMuteList::checkNewRegion() +{ + LLViewerRegion* regionp = gAgent.getRegion(); + if (!regionp) return; + + if (regionp->getFeaturesReceived()) + { + parseSimulatorFeatures(); + } + else + { + regionp->setFeaturesReceivedCallback(boost::bind(&LLMuteList::parseSimulatorFeatures, this)); + } +} + +void LLMuteList::parseSimulatorFeatures() +{ + LLViewerRegion* regionp = gAgent.getRegion(); + if (!regionp) return; + + LLSD info; + regionp->getSimulatorFeatures(info); + + mGodLastNames.clear(); + mGodFullNames.clear(); + + if (info.has("god_names")) + { + if (info["god_names"].has("last_names")) + { + LLSD godNames = info["god_names"]["last_names"]; + + for (LLSD::array_iterator godNames_it = godNames.beginArray(); godNames_it != godNames.endArray(); godNames_it++) + mGodLastNames.insert((*godNames_it).asString()); + } + + if (info["god_names"].has("full_names")) + { + LLSD godNames = info["god_names"]["full_names"]; + + for (LLSD::array_iterator godNames_it = godNames.beginArray(); godNames_it != godNames.endArray(); godNames_it++) + mGodFullNames.insert((*godNames_it).asString()); + } + } + else // Just use Linden + { + mGodLastNames.insert("Linden"); + } +} diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 11a20e015..10cb4842e 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -116,6 +116,7 @@ public: BOOL isMuted(const LLUUID& id, U32 flags) const { return isMuted(id, LLStringUtil::null, flags); }; BOOL isLinden(const std::string& name) const; + bool isLinden(const LLUUID& id) const; BOOL isLoaded() const { return mIsLoaded; } @@ -148,6 +149,9 @@ private: static void onFileMuteList(void** user_data, S32 code, LLExtStat ext_status); + void checkNewRegion(); + void parseSimulatorFeatures(); + private: struct compare_by_name { @@ -185,6 +189,9 @@ private: typedef std::map user_volume_map_t; user_volume_map_t mUserVolumeSettings; + + std::set mGodLastNames; + std::set mGodFullNames; }; class LLMuteListObserver diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 724b15c94..044f5b77e 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -409,7 +409,7 @@ void LLNetMap::draw() avColor = it->second; } //Lindens are always more Linden than your friend, make that take precedence - else if(LLMuteList::getInstance()->isLinden(avName)) + else if(LLMuteList::getInstance()->isLinden(id)) { avColor = linden_color; } diff --git a/indra/newview/llpaneldirclassified.cpp b/indra/newview/llpaneldirclassified.cpp index eaa83aff0..dbc2f8afa 100644 --- a/indra/newview/llpaneldirclassified.cpp +++ b/indra/newview/llpaneldirclassified.cpp @@ -121,6 +121,8 @@ BOOL LLPanelDirClassified::postBuild() // Don't do this every time we open find, it's expensive; require clicking 'search' //requestClassified(); + childSetVisible("filter_gaming", (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_CLASSIFIEDS)); + return TRUE; } @@ -206,6 +208,7 @@ void LLPanelDirClassified::performQuery() BOOL filter_auto_renew = FALSE; U32 query_flags = pack_classified_flags_request(filter_auto_renew, inc_pg, inc_mature, inc_adult); //if (gAgent.isTeen()) query_flags |= DFQ_PG_SIMS_ONLY; + if (childGetValue("filter_gaming")) query_flags |= DFQ_FILTER_GAMING; U32 category = childGetValue("Category").asInteger(); diff --git a/indra/newview/llpaneldirevents.cpp b/indra/newview/llpaneldirevents.cpp index 44bea8693..bded7d142 100644 --- a/indra/newview/llpaneldirevents.cpp +++ b/indra/newview/llpaneldirevents.cpp @@ -51,6 +51,7 @@ #include "llpanelevent.h" #include "llappviewer.h" #include "llnotificationsutil.h" +#include "llviewerregion.h" BOOL gDisplayEventHack = FALSE; @@ -94,6 +95,8 @@ BOOL LLPanelDirEvents::postBuild() } gDisplayEventHack = FALSE; + childSetVisible("filter_gaming", (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_EVENTS)); + return TRUE; } @@ -181,6 +184,7 @@ void LLPanelDirEvents::performQueryOrDelete(U32 event_id) if ( childGetValue("incpg").asBoolean() ) scope |= DFQ_INC_PG; if ( childGetValue("incmature").asBoolean() ) scope |= DFQ_INC_MATURE; if ( childGetValue("incadult").asBoolean() ) scope |= DFQ_INC_ADULT; + if (childGetValue("filter_gaming").asBoolean()) scope |= DFQ_FILTER_GAMING; // Add old query flags in case we are talking to an old server if ( childGetValue("incpg").asBoolean() && !childGetValue("incmature").asBoolean()) diff --git a/indra/newview/llpaneldirfind.cpp b/indra/newview/llpaneldirfind.cpp index 94edad4dd..2ba9aac2c 100644 --- a/indra/newview/llpaneldirfind.cpp +++ b/indra/newview/llpaneldirfind.cpp @@ -161,6 +161,8 @@ BOOL LLPanelDirFind::postBuild() navigateToDefaultPage(); } + childSetVisible("filter_gaming", (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_ALL)); + return TRUE; } @@ -309,9 +311,9 @@ void LLPanelDirFind::navigateToDefaultPage() mWebBrowser->navigateTo( start_url ); } } -// static -std::string LLPanelDirFind::buildSearchURL(const std::string& search_text, const std::string& collection, - bool inc_pg, bool inc_mature, bool inc_adult, bool is_web) + +const std::string LLPanelDirFind::buildSearchURL(const std::string& search_text, const std::string& collection, + bool inc_pg, bool inc_mature, bool inc_adult, bool is_web) const { std::string url; if (search_text.empty()) @@ -363,8 +365,8 @@ std::string LLPanelDirFind::buildSearchURL(const std::string& search_text, const llinfos << "web search url " << url << llendl; return url; } -// static -std::string LLPanelDirFind::getSearchURLSuffix(bool inc_pg, bool inc_mature, bool inc_adult, bool is_web) + +const std::string LLPanelDirFind::getSearchURLSuffix(bool inc_pg, bool inc_mature, bool inc_adult, bool is_web) const { std::string url = gHippoGridManager->getConnectedGrid()->getSearchUrl(HippoGridInfo::SEARCH_ALL_TEMPLATE, is_web); llinfos << "Suffix template " << url << llendl; @@ -426,6 +428,13 @@ std::string LLPanelDirFind::getSearchURLSuffix(bool inc_pg, bool inc_mature, boo std::string teen_string = gAgent.isTeen() ? "y" : "n"; std::string teen_tag = "[TEEN]"; url.replace( url.find( teen_tag ), teen_tag.length(), teen_string ); + + // and set the flag for gaming areas if not on SL Grid. + if (!gHippoGridManager->getConnectedGrid()->isSecondLife()) + { + substring = "[DICE]"; + url.replace(url.find(substring), substring.length(), childGetValue("filter_gaming").asBoolean() ? "y" : "n"); + } } } @@ -561,6 +570,8 @@ BOOL LLPanelDirFindAllOld::postBuild() childDisable("Search"); setDefaultBtn( "Search" ); + childSetVisible("filter_gaming", (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_ALL_CLASSIC)); + return TRUE; } @@ -623,6 +634,11 @@ void LLPanelDirFindAllOld::onClickSearch(void *userdata) scope |= DFQ_INC_ADULT; } + if (self->childGetValue("filter_gaming").asBoolean()) + { + scope |= DFQ_FILTER_GAMING; + } + // send the message LLMessageSystem *msg = gMessageSystem; S32 start_row = 0; diff --git a/indra/newview/llpaneldirfind.h b/indra/newview/llpaneldirfind.h index 670f30c7e..931ab0737 100644 --- a/indra/newview/llpaneldirfind.h +++ b/indra/newview/llpaneldirfind.h @@ -61,8 +61,8 @@ public: virtual void navigateToDefaultPage(); void focus(); - static std::string buildSearchURL(const std::string& search_text, const std::string& collection, bool inc_pg, bool inc_mature, bool inc_adult, bool is_web); - static std::string getSearchURLSuffix(bool inc_pg, bool inc_mature, bool inc_adult, bool is_web); + const std::string buildSearchURL(const std::string& search_text, const std::string& collection, bool inc_pg, bool inc_mature, bool inc_adult, bool is_web) const; + const std::string getSearchURLSuffix(bool inc_pg, bool inc_mature, bool inc_adult, bool is_web) const; private: static void onClickBack( void* data ); diff --git a/indra/newview/llpaneldirgroups.cpp b/indra/newview/llpaneldirgroups.cpp index 009e68367..ac7102a30 100644 --- a/indra/newview/llpaneldirgroups.cpp +++ b/indra/newview/llpaneldirgroups.cpp @@ -40,6 +40,7 @@ #include "message.h" #include "llqueryflags.h" #include "llviewercontrol.h" +#include "llviewerregion.h" #include "llviewerwindow.h" #include "llnotificationsutil.h" @@ -60,6 +61,8 @@ BOOL LLPanelDirGroups::postBuild() childDisable("Search"); setDefaultBtn( "Search" ); + childSetVisible("filter_gaming", (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_GROUPS)); + return TRUE; } @@ -130,6 +133,10 @@ void LLPanelDirGroups::performQuery() { scope |= DFQ_INC_ADULT; } + if (childGetValue("filter_gaming").asBoolean()) + { + scope |= DFQ_FILTER_GAMING; + } mCurrentSortColumn = "score"; mCurrentSortAscending = FALSE; diff --git a/indra/newview/llpaneldirland.cpp b/indra/newview/llpaneldirland.cpp index d89c049fa..199426a6d 100644 --- a/indra/newview/llpaneldirland.cpp +++ b/indra/newview/llpaneldirland.cpp @@ -52,6 +52,7 @@ #include "lltextbox.h" #include "llviewercontrol.h" #include "llviewermessage.h" +#include "llviewerregion.h" #include "hippogridmanager.h" @@ -125,6 +126,8 @@ BOOL LLPanelDirLand::postBuild() } } + childSetVisible("filter_gaming", (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_LAND)); + return TRUE; } @@ -213,6 +216,11 @@ void LLPanelDirLand::performQuery() { query_flags |= DFQ_INC_ADULT; } + + if (childGetValue("filter_gaming").asBoolean()) + { + query_flags |= DFQ_FILTER_GAMING; + } // Add old flags in case we are talking to an old dataserver if (inc_pg && !inc_mature) diff --git a/indra/newview/llpaneldirplaces.cpp b/indra/newview/llpaneldirplaces.cpp index 96070b4b0..43824da90 100644 --- a/indra/newview/llpaneldirplaces.cpp +++ b/indra/newview/llpaneldirplaces.cpp @@ -57,6 +57,7 @@ #include "lluiconstants.h" #include "llviewercontrol.h" #include "llviewermessage.h" +#include "llviewerregion.h" #include "llworldmap.h" LLPanelDirPlaces::LLPanelDirPlaces(const std::string& name, LLFloaterDirectory* floater) @@ -98,6 +99,8 @@ BOOL LLPanelDirPlaces::postBuild() childSetEnabled("Category", true); } + childSetVisible("filter_gaming", (gAgent.getRegion()->getGamingFlags() & REGION_GAMING_PRESENT) && !(gAgent.getRegion()->getGamingFlags() & REGION_GAMING_HIDE_FIND_SIMS)); + // Don't prepopulate the places list, as it hurts the database as of 2006-12-04. JC // initialQuery(); @@ -198,6 +201,11 @@ void LLPanelDirPlaces::performQuery() { flags |= DFQ_INC_ADULT; } + + if (childGetValue("filter_gaming").asBoolean()) + { + flags |= DFQ_FILTER_GAMING; + } // Pack old query flag in case we are talking to an old server if ( ((flags & DFQ_INC_PG) == DFQ_INC_PG) && !((flags & DFQ_INC_MATURE) == DFQ_INC_MATURE) ) diff --git a/indra/newview/llpanelplace.cpp b/indra/newview/llpanelplace.cpp index 4f687099f..2afff003e 100644 --- a/indra/newview/llpanelplace.cpp +++ b/indra/newview/llpanelplace.cpp @@ -39,7 +39,6 @@ #include "message.h" #include "llui.h" #include "llsecondlifeurls.h" -#include "llremoteparcelrequest.h" #include "llfloater.h" #include "llagent.h" @@ -62,9 +61,6 @@ #include "hippogridmanager.h" -//static -std::list LLPanelPlace::sAllPanels; - LLPanelPlace::LLPanelPlace() : LLPanel(std::string("Places Panel")), mParcelID(), @@ -74,14 +70,14 @@ LLPanelPlace::LLPanelPlace() mPosRegion(), mAuctionID(0), mLandmarkAssetID() -{ - sAllPanels.push_back(this); -} +{} LLPanelPlace::~LLPanelPlace() { - sAllPanels.remove(this); + if (mParcelID.isNull()) return; + + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelID, this); } @@ -179,8 +175,14 @@ void LLPanelPlace::resetName(const std::string& name) void LLPanelPlace::setParcelID(const LLUUID& parcel_id) { + if (parcel_id.isNull()) return; + + if(mParcelID.notNull()) + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelID, this); + mParcelID = parcel_id; - sendParcelInfoRequest(); + LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelID, this); + LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelID); } void LLPanelPlace::setSnapshot(const LLUUID& snapshot_id) @@ -199,23 +201,6 @@ void LLPanelPlace::setLandTypeString(const std::string& land_type) mLandTypeEditor->setText(land_type); } -void LLPanelPlace::sendParcelInfoRequest() -{ - LLMessageSystem *msg = gMessageSystem; - - if (mParcelID != mRequestedID) - { - msg->newMessage("ParcelInfoRequest"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - msg->addUUID("SessionID", gAgent.getSessionID()); - msg->nextBlock("Data"); - msg->addUUID("ParcelID", mParcelID); - gAgent.sendReliableMessage(); - mRequestedID = mParcelID; - } -} - void LLPanelPlace::setErrorStatus(U32 status, const std::string& reason) { // We only really handle 404 and 499 errors @@ -231,141 +216,94 @@ void LLPanelPlace::setErrorStatus(U32 status, const std::string& reason) mDescEditor->setText(error_text); } -//static -void LLPanelPlace::processParcelInfoReply(LLMessageSystem *msg, void **) +void LLPanelPlace::processParcelInfo(const LLParcelData& parcel_data) { - LLUUID agent_id; - LLUUID parcel_id; - LLUUID owner_id; - std::string name; - std::string desc; - S32 actual_area; - S32 billable_area; - U8 flags; - F32 global_x; - F32 global_y; - F32 global_z; - std::string sim_name; - LLUUID snapshot_id; - F32 dwell; - S32 sale_price; - S32 auction_id; + mAuctionID = parcel_data.auction_id; - msg->getUUID("AgentData", "AgentID", agent_id ); - msg->getUUID("Data", "ParcelID", parcel_id); - - // look up all panels which have this avatar - for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter) + if (parcel_data.snapshot_id.notNull()) { - LLPanelPlace* self = *iter; - if (self->mParcelID != parcel_id) - { - continue; - } - - msg->getUUID ("Data", "OwnerID", owner_id); - msg->getString ("Data", "Name", name); - msg->getString ("Data", "Desc", desc); - msg->getS32 ("Data", "ActualArea", actual_area); - msg->getS32 ("Data", "BillableArea", billable_area); - msg->getU8 ("Data", "Flags", flags); - msg->getF32 ("Data", "GlobalX", global_x); - msg->getF32 ("Data", "GlobalY", global_y); - msg->getF32 ("Data", "GlobalZ", global_z); - msg->getString ("Data", "SimName", sim_name); - msg->getUUID ("Data", "SnapshotID", snapshot_id); - msg->getF32 ("Data", "Dwell", dwell); - msg->getS32 ("Data", "SalePrice", sale_price); - msg->getS32 ("Data", "AuctionID", auction_id); - - - self->mAuctionID = auction_id; - - if(snapshot_id.notNull()) - { - self->mSnapshotCtrl->setImageAssetID(snapshot_id); - } - - // Only assign the name and description if they are not empty and there is not a - // value present (passed in from a landmark, e.g.) - - if( !name.empty() - && self->mNameEditor && self->mNameEditor->getText().empty()) - { - self->mNameEditor->setText(name); - } - - if( !desc.empty() - && self->mDescEditor && self->mDescEditor->getText().empty()) - { - self->mDescEditor->setText(desc); - } - - std::string info_text; - LLUIString traffic = self->getString("traffic_text"); - traffic.setArg("[TRAFFIC]", llformat("%d ", (int)dwell)); - info_text = traffic; - LLUIString area = self->getString("area_text"); - area.setArg("[AREA]", llformat("%d", actual_area)); - info_text += area; - if (flags & DFQ_FOR_SALE) - { - LLUIString forsale = self->getString("forsale_text"); - forsale.setArg("[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol()); - forsale.setArg("[PRICE]", llformat("%d", sale_price)); - info_text += forsale; - } - if (auction_id != 0) - { - LLUIString auction = self->getString("auction_text"); - auction.setArg("[ID]", llformat("%010d ", auction_id)); - info_text += auction; - } - if (self->mInfoEditor) - { - self->mInfoEditor->setText(info_text); - } - - // HACK: Flag 0x2 == adult region, - // Flag 0x1 == mature region, otherwise assume PG - std::string rating = LLViewerRegion::accessToString(SIM_ACCESS_PG); - if (flags & 0x2) - { - rating = LLViewerRegion::accessToString(SIM_ACCESS_ADULT); - } - else if (flags & 0x1) - { - rating = LLViewerRegion::accessToString(SIM_ACCESS_MATURE); - } - - // Just use given region position for display - S32 region_x = llround(self->mPosRegion.mV[0]); - S32 region_y = llround(self->mPosRegion.mV[1]); - S32 region_z = llround(self->mPosRegion.mV[2]); - - // If the region position is zero, grab position from the global - if(self->mPosRegion.isExactlyZero()) - { - region_x = llround(global_x) % REGION_WIDTH_UNITS; - region_y = llround(global_y) % REGION_WIDTH_UNITS; - region_z = llround(global_z); - } - - if(self->mPosGlobal.isExactlyZero()) - { - self->mPosGlobal.setVec(global_x, global_y, global_z); - } - - std::string location = llformat("%s %d, %d, %d (%s)", - sim_name.c_str(), region_x, region_y, region_z, rating.c_str()); - if (self->mLocationDisplay) - { - self->mLocationDisplay->setText(location); - } - - BOOL show_auction = (auction_id > 0); - self->mAuctionBtn->setVisible(show_auction); + setSnapshot(parcel_data.snapshot_id); } + + // Only assign the name and description if they are not empty and there is not a + // value present (passed in from a landmark, e.g.) + + if( !parcel_data.name.empty() + && mNameEditor && mNameEditor->getText().empty()) + { + mNameEditor->setText(parcel_data.name); + } + + if( !parcel_data.desc.empty() + && mDescEditor && mDescEditor->getText().empty()) + { + mDescEditor->setText(parcel_data.desc); + } + + std::string info_text; + LLUIString traffic = getString("traffic_text"); + traffic.setArg("[TRAFFIC]", llformat("%d ", (int)parcel_data.dwell)); + info_text = traffic; + LLUIString area = getString("area_text"); + area.setArg("[AREA]", llformat("%d", parcel_data.actual_area)); + info_text += area; + if (parcel_data.flags & DFQ_FOR_SALE) + { + LLUIString forsale = getString("forsale_text"); + forsale.setArg("[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol()); + forsale.setArg("[PRICE]", llformat("%d", parcel_data.sale_price)); + info_text += forsale; + } + if (parcel_data.auction_id != 0) + { + LLUIString auction = getString("auction_text"); + auction.setArg("[ID]", llformat("%010d ", parcel_data.auction_id)); + info_text += auction; + } + if (mInfoEditor) + { + mInfoEditor->setText(info_text); + } + + // HACK: Flag 0x2 == adult region, + // Flag 0x1 == mature region, otherwise assume PG + std::string rating = LLViewerRegion::accessToString(SIM_ACCESS_PG); + if (parcel_data.flags & 0x2) + { + rating = LLViewerRegion::accessToString(SIM_ACCESS_ADULT); + } + else if (parcel_data.flags & 0x1) + { + rating = LLViewerRegion::accessToString(SIM_ACCESS_MATURE); + } + + // Just use given region position for display + S32 region_x = llround(mPosRegion.mV[0]); + S32 region_y = llround(mPosRegion.mV[1]); + S32 region_z = llround(mPosRegion.mV[2]); + + // If the region position is zero, grab position from the global + if(mPosRegion.isExactlyZero()) + { + region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS; + region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS; + region_z = llround(parcel_data.global_z); + } + + if(mPosGlobal.isExactlyZero()) + { + mPosGlobal.setVec(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z); + } + + std::string location = llformat("%s %d, %d, %d (%s)", + parcel_data.sim_name.c_str(), region_x, region_y, region_z, rating.c_str()); + if (mLocationDisplay) + { + mLocationDisplay->setText(location); + } + + BOOL show_auction = (parcel_data.auction_id > 0); + mAuctionBtn->setVisible(show_auction); } @@ -391,7 +329,7 @@ void LLPanelPlace::displayParcelInfo(const LLVector3& pos_region, U64 region_handle = to_region_handle(pos_global); body["region_handle"] = ll_sd_from_U64(region_handle); } - LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(this->getHandle())); + LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(this->getObserverHandle())); } else { diff --git a/indra/newview/llpanelplace.h b/indra/newview/llpanelplace.h index b11290493..355c8f923 100644 --- a/indra/newview/llpanelplace.h +++ b/indra/newview/llpanelplace.h @@ -34,6 +34,7 @@ #define LL_LLPANELPLACE_H #include "llpanel.h" +#include "llremoteparcelrequest.h" #include "v3dmath.h" #include "lluuid.h" @@ -46,7 +47,7 @@ class LLTextureCtrl; class LLMessageSystem; class LLInventoryItem; -class LLPanelPlace : public LLPanel +class LLPanelPlace : public LLPanel, public LLRemoteParcelInfoObserver { public: LLPanelPlace(); @@ -58,7 +59,7 @@ public: // Ignore all old location information, useful if you are // recycling an existing dialog and need to clear it. - void setParcelID(const LLUUID& parcel_id); + /*virtual*/ void setParcelID(const LLUUID& parcel_id); // Sends a request for data about the given parcel, which will // only update the location if there is none already available. @@ -67,15 +68,14 @@ public: void setSnapshot(const LLUUID& snapshot_id); void setLocationString(const std::string& location); void setLandTypeString(const std::string& land_type); - void setErrorStatus(U32 status, const std::string& reason); + /*virtual*/ void setErrorStatus(U32 status, const std::string& reason); void resetName(const std::string& name); - void sendParcelInfoRequest(); void displayParcelInfo(const LLVector3& pos_region, const LLUUID& landmark_asset_id, const LLUUID& region_id, const LLVector3d& pos_global); - static void processParcelInfoReply(LLMessageSystem* msg, void**); + /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); LLTextureCtrl *getSnapshotCtrl() const { return mSnapshotCtrl; } @@ -113,9 +113,6 @@ protected: LLButton* mMapBtn; //LLButton* mLandmarkBtn; LLButton* mAuctionBtn; - - typedef std::list panel_list_t; - static panel_list_t sAllPanels; }; #endif // LL_LLPANELPLACE_H diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp index 8ff4dea2b..f8fbe5740 100644 --- a/indra/newview/llremoteparcelrequest.cpp +++ b/indra/newview/llremoteparcelrequest.cpp @@ -34,46 +34,172 @@ #include "llviewerprecompiledheaders.h" -#include "llagent.h" -#include "llremoteparcelrequest.h" +#include "message.h" -#include "llpanelplace.h" #include "llpanel.h" #include "llhttpclient.h" #include "llsdserialize.h" +//#include "llurlentry.h" #include "llviewerregion.h" #include "llview.h" -#include "message.h" -LLRemoteParcelRequestResponder::LLRemoteParcelRequestResponder(LLHandle place_panel_handle) -{ - mPlacePanelHandle = place_panel_handle; -} -/*virtual*/ +#include "llagent.h" +#include "llremoteparcelrequest.h" + + +LLRemoteParcelRequestResponder::LLRemoteParcelRequestResponder(LLHandle observer_handle) + : mObserverHandle(observer_handle) +{} + +//If we get back a normal response, handle it here +//virtual void LLRemoteParcelRequestResponder::result(const LLSD& content) { LLUUID parcel_id = content["parcel_id"]; - LLPanelPlace* place_panelp = (LLPanelPlace*)mPlacePanelHandle.get(); - - if(place_panelp) + // Panel inspecting the information may be closed and destroyed + // before this response is received. + LLRemoteParcelInfoObserver* observer = mObserverHandle.get(); + if (observer) { - place_panelp->setParcelID(parcel_id); + observer->setParcelID(parcel_id); } - } -/*virtual*/ +//If we get back an error (not found, etc...), handle it here +//virtual void LLRemoteParcelRequestResponder::error(U32 status, const std::string& reason) { llinfos << "LLRemoteParcelRequest::error(" << status << ": " << reason << ")" << llendl; - LLPanelPlace* place_panelp = (LLPanelPlace*)mPlacePanelHandle.get(); - if(place_panelp) + // Panel inspecting the information may be closed and destroyed + // before this response is received. + LLRemoteParcelInfoObserver* observer = mObserverHandle.get(); + if (observer) { - place_panelp->setErrorStatus(status, reason); + observer->setErrorStatus(status, reason); } - } +void LLRemoteParcelInfoProcessor::addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer) +{ + observer_multimap_t::iterator it; + observer_multimap_t::iterator start = mObservers.lower_bound(parcel_id); + observer_multimap_t::iterator end = mObservers.upper_bound(parcel_id); + + // Check if the observer is already in observers list for this UUID + for(it = start; it != end; ++it) + { + if (it->second.get() == observer) + { + return; + } + } + + mObservers.insert(std::make_pair(parcel_id, observer->getObserverHandle())); +} + +void LLRemoteParcelInfoProcessor::removeObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer) +{ + if (!observer) + { + return; + } + + observer_multimap_t::iterator it; + observer_multimap_t::iterator start = mObservers.lower_bound(parcel_id); + observer_multimap_t::iterator end = mObservers.upper_bound(parcel_id); + + for(it = start; it != end; ++it) + { + if (it->second.get() == observer) + { + mObservers.erase(it); + break; + } + } +} + +//static +void LLRemoteParcelInfoProcessor::processParcelInfoReply(LLMessageSystem* msg, void**) +{ + LLParcelData parcel_data; + + msg->getUUID ("Data", "ParcelID", parcel_data.parcel_id); + msg->getUUID ("Data", "OwnerID", parcel_data.owner_id); + msg->getString ("Data", "Name", parcel_data.name); + msg->getString ("Data", "Desc", parcel_data.desc); + msg->getS32 ("Data", "ActualArea", parcel_data.actual_area); + msg->getS32 ("Data", "BillableArea", parcel_data.billable_area); + msg->getU8 ("Data", "Flags", parcel_data.flags); + msg->getF32 ("Data", "GlobalX", parcel_data.global_x); + msg->getF32 ("Data", "GlobalY", parcel_data.global_y); + msg->getF32 ("Data", "GlobalZ", parcel_data.global_z); + msg->getString ("Data", "SimName", parcel_data.sim_name); + msg->getUUID ("Data", "SnapshotID", parcel_data.snapshot_id); + msg->getF32 ("Data", "Dwell", parcel_data.dwell); + msg->getS32 ("Data", "SalePrice", parcel_data.sale_price); + msg->getS32 ("Data", "AuctionID", parcel_data.auction_id); + + LLRemoteParcelInfoProcessor::observer_multimap_t & observers = LLRemoteParcelInfoProcessor::getInstance()->mObservers; + + typedef std::vector deadlist_t; + deadlist_t dead_iters; + + observer_multimap_t::iterator oi = observers.lower_bound(parcel_data.parcel_id); + observer_multimap_t::iterator end = observers.upper_bound(parcel_data.parcel_id); + + while (oi != end) + { + // increment the loop iterator now since it may become invalid below + observer_multimap_t::iterator cur_oi = oi++; + + LLRemoteParcelInfoObserver * observer = cur_oi->second.get(); + if(observer) + { + // may invalidate cur_oi if the observer removes itself + observer->processParcelInfo(parcel_data); + } + else + { + // the handle points to an expired observer, so don't keep it + // around anymore + dead_iters.push_back(cur_oi); + } + } + + deadlist_t::iterator i; + deadlist_t::iterator end_dead = dead_iters.end(); + for(i = dead_iters.begin(); i != end_dead; ++i) + { + observers.erase(*i); + } + +#ifdef LL_LLURLENTRY_H + LLUrlEntryParcel::LLParcelData url_data; + url_data.parcel_id = parcel_data.parcel_id; + url_data.name = parcel_data.name; + url_data.sim_name = parcel_data.sim_name; + url_data.global_x = parcel_data.global_x; + url_data.global_y = parcel_data.global_y; + url_data.global_z = parcel_data.global_z; + + // Pass the parcel data to LLUrlEntryParcel to render + // human readable parcel name. + LLUrlEntryParcel::processParcelInfo(url_data); +#endif //LL_LLURLENTRY_H +} + +void LLRemoteParcelInfoProcessor::sendParcelInfoRequest(const LLUUID& parcel_id) +{ + LLMessageSystem *msg = gMessageSystem; + + msg->newMessage("ParcelInfoRequest"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUID("SessionID", gAgent.getSessionID()); + msg->nextBlock("Data"); + msg->addUUID("ParcelID", parcel_id); + gAgent.sendReliableMessage(); +} diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h index 6d212e3e4..922a77a5b 100644 --- a/indra/newview/llremoteparcelrequest.h +++ b/indra/newview/llremoteparcelrequest.h @@ -38,22 +38,78 @@ #include "llhttpclient.h" #include "llpanel.h" +class LLRemoteParcelInfoObserver; + class AIHTTPTimeoutPolicy; extern AIHTTPTimeoutPolicy remoteParcelRequestResponder_timeout; class LLRemoteParcelRequestResponder : public LLHTTPClient::ResponderWithResult { public: - LLRemoteParcelRequestResponder(LLHandle place_panel_handle); + LLRemoteParcelRequestResponder(LLHandle observer_handle); + //If we get back a normal response, handle it here /*virtual*/ void result(const LLSD& content); + //If we get back an error (not found, etc...), handle it here /*virtual*/ void error(U32 status, const std::string& reason); /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return remoteParcelRequestResponder_timeout; } /*virtual*/ char const* getName(void) const { return "LLRemoteParcelRequestResponder"; } protected: - LLHandle mPlacePanelHandle; + LLHandle mObserverHandle; +}; + +struct LLParcelData +{ + LLUUID parcel_id; + LLUUID owner_id; + std::string name; + std::string desc; + S32 actual_area; + S32 billable_area; + U8 flags; + F32 global_x; + F32 global_y; + F32 global_z; + std::string sim_name; + LLUUID snapshot_id; + F32 dwell; + S32 sale_price; + S32 auction_id; +}; + +// An interface class for panels which display parcel information +// like name, description, area, snapshot etc. +class LLRemoteParcelInfoObserver +{ +public: + LLRemoteParcelInfoObserver() { mObserverHandle.bind(this); } + virtual ~LLRemoteParcelInfoObserver() {} + virtual void processParcelInfo(const LLParcelData& parcel_data) = 0; + virtual void setParcelID(const LLUUID& parcel_id) = 0; + virtual void setErrorStatus(U32 status, const std::string& reason) = 0; + LLHandle getObserverHandle() const { return mObserverHandle; } + +protected: + LLRootHandle mObserverHandle; +}; + +class LLRemoteParcelInfoProcessor : public LLSingleton +{ +public: + virtual ~LLRemoteParcelInfoProcessor() {} + + void addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer); + void removeObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer); + + void sendParcelInfoRequest(const LLUUID& parcel_id); + + static void processParcelInfoReply(LLMessageSystem* msg, void**); + +private: + typedef std::multimap > observer_multimap_t; + observer_multimap_t mObservers; }; #endif // LL_LLREMOTEPARCELREQUEST_H diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 521c5e4f0..1d3361f82 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -62,16 +62,16 @@ #include "statemachine/aifilepicker.h" #include "llares.h" +#include "llavatarnamecache.h" +#include "lllandmark.h" #include "llcachename.h" -#include "llviewercontrol.h" #include "lldir.h" #include "llerrorcontrol.h" #include "llfiltersd2xmlrpc.h" #include "llfocusmgr.h" #include "llhttpsender.h" -#include "imageids.h" #include "llimageworker.h" -#include "lllandmark.h" + #include "llloginflags.h" #include "llmd5.h" #include "llmemorystream.h" @@ -87,8 +87,10 @@ #include "llstring.h" #include "lluserrelations.h" #include "sgversion.h" +#include "llviewercontrol.h" #include "llvfs.h" #include "llxorcipher.h" // saved password, MAC address +#include "imageids.h" #include "message.h" #include "v3math.h" @@ -144,23 +146,24 @@ #include "llpanelevent.h" #include "llpanelclassified.h" #include "llpanelpick.h" -#include "llpanelplace.h" #include "llpanelgrouplandmoney.h" #include "llpanelgroupnotices.h" #include "llpreview.h" #include "llpreviewscript.h" +#include "llproxy.h" #include "llproductinforequest.h" +#include "llremoteparcelrequest.h" #include "llsecondlifeurls.h" #include "llselectmgr.h" #include "llsky.h" #include "llsrv.h" #include "llstatview.h" -#include "lltrans.h" #include "llstatusbar.h" // sendMoneyBalanceRequest(), owns L$ balance #include "llsurface.h" #include "lltexturecache.h" #include "lltexturefetch.h" #include "lltoolmgr.h" +#include "lltrans.h" #include "llui.h" #include "llurldispatcher.h" #include "llurlsimstring.h" @@ -205,7 +208,6 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llagentlanguage.h" -#include "llproxy.h" #include "llwearable.h" #include "llinventorybridge.h" #include "llappearancemgr.h" @@ -225,7 +227,6 @@ #include "llpathfindingmanager.h" -#include "llavatarnamecache.h" #include "lgghunspell_wrapper.h" // [RLVa:KB] @@ -457,8 +458,8 @@ bool idle_startup() // is using SOCKS for HTTP so we get the login // screen and HTTP tables via SOCKS. //------------------------------------------------- - LLStartUp::startLLProxy(); - + LLStartUp::startLLProxy(); + gSavedSettings.setS32("LastFeatureVersion", LLFeatureManager::getInstance()->getVersion()); std::string xml_file = LLUI::locateSkin("xui_version.xml"); @@ -518,7 +519,7 @@ bool idle_startup() #if LL_WINDOWS // On the windows dev builds, unpackaged, the message_template.msg - // file will be located in + // file will be located in: // indra/build-vc**/newview//app_settings. if (!found_template) { @@ -934,7 +935,6 @@ bool idle_startup() if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState()) { - // Post login screen, we should see if any settings have changed that may // require us to either start/stop or change the socks proxy. As various communications // past this point may require the proxy to be up. @@ -3391,9 +3391,9 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFunc("EventInfoReply", LLPanelEvent::processEventInfoReply); msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply); - //msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply); +// msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply); msg->setHandlerFunc("ClassifiedInfoReply", LLAvatarPropertiesProcessor::processClassifiedInfoReply); - msg->setHandlerFunc("ParcelInfoReply", LLPanelPlace::processParcelInfoReply); + msg->setHandlerFunc("ParcelInfoReply", LLRemoteParcelInfoProcessor::processParcelInfoReply); msg->setHandlerFunc("ScriptDialog", process_script_dialog); msg->setHandlerFunc("LoadURL", process_load_url); msg->setHandlerFunc("ScriptTeleportRequest", process_script_teleport_request); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index dde1a5950..7cd5efada 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -93,6 +93,7 @@ #include "lldrawable.h" #include "lldrawpoolalpha.h" #include "lldrawpooltree.h" +#include "llenvmanager.h" #include "llface.h" #include "llfirstuse.h" #include "llfloater.h" @@ -278,6 +279,8 @@ void init_client_menu(LLMenuGL* menu); void init_server_menu(LLMenuGL* menu); typedef LLPointer LLViewerObjectPtr; +typedef std::vector custom_menu_item_list_t; +custom_menu_item_list_t gCustomMenuItems; void init_debug_world_menu(LLMenuGL* menu); void init_debug_rendering_menu(LLMenuGL* menu); @@ -621,6 +624,10 @@ void menu_toggle_attached_particles(void* user_data); BOOL enable_dump_archetype_xm(void*); void handle_dump_archetype_xml(void *); +void region_change(); +void parse_simulator_features(); +void custom_selected(void* user_data); + class LLMenuParcelObserver : public LLParcelObserver { public: @@ -895,6 +902,18 @@ void init_menus() gLoginMenuBarView->setBackgroundColor( color ); gMenuHolder->addChild(gLoginMenuBarView); + + LLView* ins = gMenuBarView->getChildView("insert_world", true, false); + ins->setVisible(false); + ins = gMenuBarView->getChildView("insert_agent", true, false); + ins->setVisible(false); + ins = gMenuBarView->getChildView("insert_tools", true, false); + ins->setVisible(false); + /* Singu Note: When the advanced menu is made xml, this should be uncommented. + ins = gMenuBarView->getChildView("insert_advanced", true, false); + ins->setVisible(false);*/ + + LLEnvManagerNew::instance().setRegionChangeCallback(®ion_change); } @@ -1181,6 +1200,13 @@ void init_client_menu(LLMenuGL* menu) NULL, &menu_check_control, (void*) "MouseSmooth")); + + // Singu Note: When this menu is xml, handle this above, with the other insertion points + { + LLMenuItemCallGL* item = new LLMenuItemCallGL("insert_advanced", NULL); + item->setVisible(false); + menu->addChild(item); + } menu->addSeparator(); menu->addChild(new LLMenuItemCheckGL( "Console Window", @@ -1621,8 +1647,7 @@ void init_debug_avatar_menu(LLMenuGL* menu) { LLMenuGL* sub_menu = new LLMenuGL("Character Tests"); sub_menu->setCanTearOff(TRUE); - sub_menu->addChild(new LLMenuItemToggleGL("Go Away/AFK When Idle", - &gAllowIdleAFK)); + sub_menu->addChild(new LLMenuItemCheckGL("Go Away/AFK When Idle", menu_toggle_control, NULL, menu_check_control, (void*)"AllowIdleAFK")); sub_menu->addChild(new LLMenuItemCallGL("Appearance To XML", &handle_dump_archetype_xml,&enable_dump_archetype_xm)); @@ -9696,3 +9721,73 @@ void initialize_menus() LLToolMgr::getInstance()->initMenu(sMenus); } + +void region_change() +{ + // Remove current dynamic items + for (custom_menu_item_list_t::iterator i = gCustomMenuItems.begin(); i != gCustomMenuItems.end(); ++i) + { + LLMenuItemCallGL* item = (*i); + item->getParent()->removeChild(item); + delete item; + } + gCustomMenuItems.clear(); + + LLViewerRegion* regionp = gAgent.getRegion(); + if (!regionp) return; + + if (regionp->getFeaturesReceived()) + { + parse_simulator_features(); + } + else + { + regionp->setFeaturesReceivedCallback(boost::bind(&parse_simulator_features)); + } +} + +void parse_simulator_features() +{ + LLViewerRegion* regionp = gAgent.getRegion(); + if (!regionp) return; + + LLSD info; + regionp->getSimulatorFeatures(info); + if (!info.has("menus")) return; + + LLSD menus = info["menus"]; + for (LLSD::map_iterator i = menus.beginMap(); i != menus.endMap(); ++i) + { + std::string insertMarker = "insert_" + i->first; + + LLView* marker = gMenuBarView->getChildView(insertMarker, true, false); + if (!marker) continue; + + LLMenuGL* menu = dynamic_cast(marker->getParent()); + if (!menu) continue; + + for (LLSD::map_iterator j = i->second.beginMap(); j != i->second.endMap(); ++j) + { + LLMenuItemCallGL* custom = new LLMenuItemCallGL(j->second.asString(), j->first, custom_selected); + custom->setUserData(custom); + gCustomMenuItems.push_back(custom); + menu->addChild(custom, marker); + } + } +} + +void custom_selected(void* user_data) +{ + LLViewerRegion* regionp = gAgent.getRegion(); + if (!regionp) return; + + std::string url = regionp->getCapability("CustomMenuAction"); + if (url.empty()) return; + + LLMenuItemCallGL* custom = (LLMenuItemCallGL*)user_data; + + LLSD menuAction = LLSD::emptyMap(); + menuAction["action"] = LLSD(custom->getName()); + + LLHTTPClient::post(url, menuAction, new LLHTTPClient::ResponderIgnore); +} diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index ca71d11a8..d9dcf4384 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3577,7 +3577,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) sChatObjectAuth[from_id] = 1; return; } - else if (sChatObjectAuth.find(from_id) != sChatObjectAuth.end()) + else if (from_id.isNull() || sChatObjectAuth.find(from_id) != sChatObjectAuth.end()) { LLUUID key; if (key.set(mesg.substr(3, 36),false)) @@ -5756,7 +5756,6 @@ void process_money_balance_reply( LLMessageSystem* msg, void** ) LLNotificationsUtil::add("SystemMessage", args); // Also send notification to chat -- MC - LLChat chat(desc); LLFloaterChat::addChat(desc); } } @@ -5956,6 +5955,8 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) _1, _2, message, notification, args, payload)); } + + if (!no_transaction_clutter) LLFloaterChat::addChat(message); // Alerts won't automatically log to chat. } bool handle_prompt_for_maturity_level_change_callback(const LLSD& notification, const LLSD& response) diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index be87807f1..fcfbc2e77 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -84,6 +84,7 @@ class AIHTTPTimeoutPolicy; extern AIHTTPTimeoutPolicy baseCapabilitiesComplete_timeout; +extern AIHTTPTimeoutPolicy gamingDataReceived_timeout; extern AIHTTPTimeoutPolicy simulatorFeaturesReceived_timeout; const F32 WATER_TEXTURE_SCALE = 8.f; // Number of times to repeat the water texture across a region @@ -306,7 +307,9 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mCacheLoaded(FALSE), mCacheDirty(FALSE), mReleaseNotesRequested(FALSE), - mCapabilitiesReceived(false) + mCapabilitiesReceived(false), + mFeaturesReceived(false), + mGamingFlags(0) { mWidth = region_width_meters; mImpl->mOriginGlobal = from_region_handle(handle); @@ -1248,6 +1251,40 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) LLSDSerialize::toPrettyXML(sim_features, str); llinfos << str.str() << llendl; mSimulatorFeatures = sim_features; + + mFeaturesReceived = true; + mFeaturesReceivedSignal(getRegionID()); + mFeaturesReceivedSignal.disconnect_all_slots(); +} + +void LLViewerRegion::setGamingData(const LLSD& gaming_data) +{ + mGamingFlags = 0; + + if (!gaming_data.has("display")) + llerrs << "GamingData Capability requires \"display\"" << llendl; + if (gaming_data["display"].asBoolean()) + mGamingFlags |= REGION_GAMING_PRESENT; + if (gaming_data.has("hide_parcel") && gaming_data["hide_parcel"].asBoolean()) + mGamingFlags |= REGION_GAMING_HIDE_PARCEL; + if (gaming_data.has("hide_find_all") && gaming_data["hide_find_all"].asBoolean()) + mGamingFlags |= REGION_GAMING_HIDE_FIND_ALL; + if (gaming_data.has("hide_find_classifieds") && gaming_data["hide_find_classifieds"].asBoolean()) + mGamingFlags |= REGION_GAMING_HIDE_FIND_CLASSIFIEDS; + if (gaming_data.has("hide_find_events") && gaming_data["hide_find_events"].asBoolean()) + mGamingFlags |= REGION_GAMING_HIDE_FIND_EVENTS; + if (gaming_data.has("hide_find_land") && gaming_data["hide_find_land"].asBoolean()) + mGamingFlags |= REGION_GAMING_HIDE_FIND_LAND; + if (gaming_data.has("hide_find_sims") && gaming_data["hide_find_sims"].asBoolean()) + mGamingFlags |= REGION_GAMING_HIDE_FIND_SIMS; + if (gaming_data.has("hide_find_groups") && gaming_data["hide_find_groups"].asBoolean()) + mGamingFlags |= REGION_GAMING_HIDE_FIND_GROUPS; + if (gaming_data.has("hide_find_all_classic") && gaming_data["hide_find_all_classic"].asBoolean()) + mGamingFlags |= REGION_GAMING_HIDE_FIND_ALL_CLASSIC; + if (gaming_data.has("hide_god_floater") && gaming_data["hide_god_floater"].asBoolean()) + mGamingFlags |= REGION_GAMING_HIDE_GOD_FLOATER; + + llinfos << "Gaming flags are " << mGamingFlags << llendl; } LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp) @@ -1591,12 +1628,13 @@ void LLViewerRegion::unpackRegionHandshake() void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) { capabilityNames.append("AgentState"); - //capabilityNames.append("AttachmentResources"); //Script limits (llfloaterscriptlimits.cpp) + capabilityNames.append("AttachmentResources"); //capabilityNames.append("AvatarPickerSearch"); //Display name/SLID lookup (llfloateravatarpicker.cpp) capabilityNames.append("CharacterProperties"); capabilityNames.append("ChatSessionRequest"); capabilityNames.append("CopyInventoryFromNotecard"); capabilityNames.append("CreateInventoryCategory"); + capabilityNames.append("CustomMenuAction"); capabilityNames.append("DispatchRegionInfo"); capabilityNames.append("EnvironmentSettings"); capabilityNames.append("EstateChangeInfo"); @@ -1610,6 +1648,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("FetchInventoryDescendents2"); } + capabilityNames.append("GamingData"); //Used by certain grids. capabilityNames.append("GetDisplayNames"); capabilityNames.append("GetMesh"); capabilityNames.append("GetObjectCost"); @@ -1618,7 +1657,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("GroupMemberData"); capabilityNames.append("GroupProposalBallot"); capabilityNames.append("HomeLocation"); - //capabilityNames.append("LandResources"); //Script limits (llfloaterscriptlimits.cpp) + capabilityNames.append("LandResources"); capabilityNames.append("MapLayer"); capabilityNames.append("MapLayerGod"); capabilityNames.append("MeshUploadFlag"); @@ -1634,7 +1673,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("ProvisionVoiceAccountRequest"); capabilityNames.append("RemoteParcelRequest"); capabilityNames.append("RequestTextureDownload"); - capabilityNames.append("ResourceCostSelected"); //Unreferenced? + //capabilityNames.append("ResourceCostSelected"); //Object weights (llfloaterobjectweights.cpp) capabilityNames.append("RetrieveNavMeshSrc"); capabilityNames.append("SearchStatRequest"); capabilityNames.append("SearchStatTracking"); @@ -1781,6 +1820,46 @@ private: S32 mMaxAttempts; }; +class GamingDataReceived : public LLHTTPClient::ResponderWithResult +{ + LOG_CLASS(GamingDataReceived); +public: + GamingDataReceived(const std::string& retry_url, U64 region_handle, S32 attempt = 0, S32 max_attempts = MAX_CAP_REQUEST_ATTEMPTS) + : mRetryURL(retry_url), mRegionHandle(region_handle), mAttempt(attempt), mMaxAttempts(max_attempts) + {} + + /*virtual*/ void error(U32 statusNum, const std::string& reason) + { + LL_WARNS2("AppInit", "GamingData") << statusNum << ": " << reason << LL_ENDL; + retry(); + } + + /*virtual*/ void result(const LLSD& content) + { + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle); + if(regionp) regionp->setGamingData(content); + } + + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return gamingDataReceived_timeout; } + /*virtual*/ char const* getName(void) const { return "GamingDataReceived"; } + +private: + void retry() + { + if (mAttempt < mMaxAttempts) + { + mAttempt++; + LL_WARNS2("AppInit", "GamingData") << "Retrying '" << mRetryURL << "'. Retry #" << mAttempt << LL_ENDL; + LLHTTPClient::get(mRetryURL, new GamingDataReceived(*this)); + } + } + + std::string mRetryURL; + U64 mRegionHandle; + S32 mAttempt; + S32 mMaxAttempts; +}; + void LLViewerRegion::setCapability(const std::string& name, const std::string& url) { @@ -1796,9 +1875,18 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u } else if (name == "SimulatorFeatures") { + // although this is not needed later, add it so we can check if the sim supports it at all later + mImpl->mCapabilities[name] = url; + // kick off a request for simulator features LLHTTPClient::get(url, new SimulatorFeaturesReceived(url, getHandle())); } + else if (name == "GamingData") + { + LLSD gamingRequest = LLSD::emptyMap(); + // request settings from simulator + LLHTTPClient::post(url, gamingRequest, new GamingDataReceived(url, getHandle())); + } else { mImpl->mCapabilities[name] = url; @@ -1847,6 +1935,15 @@ void LLViewerRegion::setCapabilitiesReceived(bool received) // This is a single-shot signal. Forget callbacks to save resources. mCapabilitiesReceivedSignal.disconnect_all_slots(); + + // If we don't have this cap, send the changed signal to simplify code + // in consumers by allowing them to expect this signal, regardless. + if (getCapability("SimulatorFeatures").empty()) + { + mFeaturesReceived = true; + mFeaturesReceivedSignal(getRegionID()); + mFeaturesReceivedSignal.disconnect_all_slots(); + } } } @@ -1964,3 +2061,8 @@ bool LLViewerRegion::dynamicPathfindingEnabled() const mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean()); } +boost::signals2::connection LLViewerRegion::setFeaturesReceivedCallback(const features_received_signal_t::slot_type& cb) +{ + return mFeaturesReceivedSignal.connect(cb); +} + diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 3000d4d5e..821b87a5d 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -100,6 +100,7 @@ public: } eObjectPartitions; typedef boost::signals2::signal caps_received_signal_t; + typedef boost::signals2::signal features_received_signal_t; LLViewerRegion(const U64 &handle, const LLHost &host, @@ -262,6 +263,9 @@ public: static bool isSpecialCapabilityName(const std::string &name); void logActiveCapabilities() const; + boost::signals2::connection setFeaturesReceivedCallback(const features_received_signal_t::slot_type& cb); + bool getFeaturesReceived() const { return mFeaturesReceived; } + /// Get LLEventPump on which we listen for capability requests /// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities) LLEventPump& getCapAPI() const; @@ -350,6 +354,9 @@ public: void getNeighboringRegions( std::vector& uniqueRegions ); void getNeighboringRegionsStatus( std::vector& regions ); + void setGamingData(const LLSD& info); + const U32 getGamingFlags() const { return mGamingFlags; } + public: struct CompareDistance { @@ -439,11 +446,14 @@ private: bool mAlive; // can become false if circuit disconnects bool mCapabilitiesReceived; + bool mFeaturesReceived; caps_received_signal_t mCapabilitiesReceivedSignal; + features_received_signal_t mFeaturesReceivedSignal; BOOL mReleaseNotesRequested; LLSD mSimulatorFeatures; + U32 mGamingFlags; }; inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index b44870e21..fb3ccab1a 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1258,7 +1258,7 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated) else { mActive = FALSE; - if (gAllowIdleAFK) + if (gSavedSettings.getBOOL("AllowIdleAFK")) { gAgent.setAFK(); } diff --git a/indra/newview/skins/default/xui/en-us/floater_about.xml b/indra/newview/skins/default/xui/en-us/floater_about.xml index da3d8e7e4..6596f818f 100644 --- a/indra/newview/skins/default/xui/en-us/floater_about.xml +++ b/indra/newview/skins/default/xui/en-us/floater_about.xml @@ -12,7 +12,7 @@ -Singularity Viewer is developed and maintained by Siana Gearz, Shyotl Kuhr, Aleric Inglewood, Narv Czervik, Tigh MacFanatic, Inusaito Kanya, Sovereign Engineer and Latif Khalifa, with contributions by Damian Zhaoying, Fractured Crystal, Franxisco Romano, Fritigern Gothly, Henri Beauchamp, McCabe Maxsted, Kadah Coba, Kitty Barnett, nhede Core, Nomade Zhao, Revolution Smythe, Selvone Franizzi, Thickbrick Sleaford, Wolfspirit Magic, Zauber Parecelsus and others. Singularity is based upon Ascent source code. Credits for Ascent include Hg Beeks, Charley Levenque, Hazim Gazov, Zwagoth Klaar, Qarl Fizz, and others. Ascent is based upon the Inertia source code. +Singularity Viewer is developed and maintained by Siana Gearz, Shyotl Kuhr, Aleric Inglewood, Narv Czervik, Tigh MacFanatic, Inusaito Kanya, Sovereign Engineer and Latif Khalifa, with contributions by Damian Zhaoying, Fractured Crystal, Franxisco Romano, Fritigern Gothly, Henri Beauchamp, Knolan Falconer, Kadah Coba, Kitty Barnett, McCabe Maxsted, nhede Core, Nomade Zhao, Revolution Smythe, Selvone Franizzi, Thickbrick Sleaford, Wolfspirit Magic, Zauber Parecelsus and others. Singularity is based upon Ascent source code. Credits for Ascent include Hg Beeks, Charley Levenque, Hazim Gazov, Zwagoth Klaar, Qarl Fizz, and others. Ascent is based upon the Inertia source code. Singularity Viewer includes source code contributions of the following residents: Able Whitman, Adam Marker, Agathos Frascati, Aimee Trescothick, Alejandro Rosenthal, Aleric Inglewood, Alissa Sabre, Angus Boyd, Ann Congrejo, Argent Stonecutter, Asuka Neely, Balp Allen, Benja Kepler, Biancaluce Robbiani, Blakar Ogre, blino Nakamura, Boroondas Gupte, Bulli Schumann, bushing Spatula, Carjay McGinnis, Catherine Pfeffer, Celierra Darling, Cron Stardust, Dale Glass, Drewan Keats, Dylan Haskell, Dzonatas Sol, Eddy Stryker, EponymousDylan Ra, Eva Nowicka, Farallon Greyskin, Feep Larsson, Flemming Congrejo, Fluf Fredriksson, Fractured Crystal, Fremont Cunningham, Geneko Nemeth, Gigs Taggart, Ginko Bayliss, Grazer Kline, Gudmund Shepherd, Hamncheese Omlet, HappySmurf Papp, Henri Beauchamp, Hikkoshi Sakai, Hiro Sommambulist, Hoze Menges, Ian Kas, Irene Muni, Iskar Ariantho, Jacek Antonelli, JB Kraft, Joghert LeSabre, Kage Pixel, Ken March, Kerutsen Sellery, Khyota Wulluf, Kunnis Basiat, Lisa Lowe, Lockhart Cordoso, maciek marksman, Magnus Balczo, Malwina Dollinger, march Korda, Matthew Dowd, McCabe Maxsted, Michelle2 Zenovka, Mm Alder, Mr Greggan, Nicholaz Beresford, Nounouch Hapmouche, Patric Mills, Paul Churchill, Paula Innis, Peekay Semyorka, Peter Lameth, Pf Shan, princess niven, Renault Clio, Ringo Tuxing, Robin Cornelius, Ryozu Kojima, Salahzar Stenvaag, Sammy Frederix, Scrippy Scofield, Seg Baphomet, Sergen Davies, SignpostMarv Martin, Simon Nolan, SpacedOut Frye, Sporked Friis, Stevex Janus, Still Defiant, Strife Onizuka, Tayra Dagostino, TBBle Kurosawa, Teardrops Fall, tenebrous pau, Tharax Ferraris, Thickbrick Sleaford, Thraxis Epsilon, tiamat bingyi, TraductoresAnonimos Alter, Tue Torok, Vadim Bigbear, Vixen Heron, Whoops Babii, Wilton Lundquist, Zarkonnen Decosta, Zi Ree, and Zipherius Turas. diff --git a/indra/newview/skins/default/xui/en-us/floater_about_land.xml b/indra/newview/skins/default/xui/en-us/floater_about_land.xml index ae6c96de5..122ef6d05 100644 --- a/indra/newview/skins/default/xui/en-us/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en-us/floater_about_land.xml @@ -195,6 +195,7 @@ halign="center" height="20" label="Buy Land..." label_selected="Buy Land..." left="155" mouse_opaque="true" name="Buy Land..." scale_image="true" width="100" /> +