diff options
author | Rider Linden <rider@lindenlab.com> | 2019-01-04 12:32:23 -0800 |
---|---|---|
committer | Rider Linden <rider@lindenlab.com> | 2019-01-04 12:32:23 -0800 |
commit | 0969632b11383e83a53bce3a10379945be7ad8c2 (patch) | |
tree | 84ef914b6e3f89d0d1cb102d4bd405c5d21e58a1 /indra/newview/llestateinfomodel.cpp | |
parent | d607d81dba25dfe7dd1ecdf123af656ca939924f (diff) |
Move some estate requests into the LLEstateInfoModel and out of the Region floater.
Fix issue where user could potentially be looking at one set of estate options and update the estate they were standing in by mistake.
Diffstat (limited to 'indra/newview/llestateinfomodel.cpp')
-rw-r--r-- | indra/newview/llestateinfomodel.cpp | 383 |
1 files changed, 345 insertions, 38 deletions
diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp index d5d8cda8ce..e8da458168 100644 --- a/indra/newview/llestateinfomodel.cpp +++ b/indra/newview/llestateinfomodel.cpp @@ -34,15 +34,101 @@ // viewer #include "llagent.h" -#include "llfloaterregioninfo.h" // for invoice id #include "llviewerregion.h" - #include "llcorehttputil.h" -LLEstateInfoModel::LLEstateInfoModel() -: mID(0) -, mFlags(0) -, mSunHour(0) +//========================================================================= +namespace +{ + class LLDispatchEstateUpdateInfo : public LLDispatchHandler + { + public: + LLDispatchEstateUpdateInfo() {} + virtual ~LLDispatchEstateUpdateInfo() {} + virtual bool operator()(const LLDispatcher* dispatcher, const std::string& key, + const LLUUID& invoice, const sparam_t& strings) + { + // key = "estateupdateinfo" + // strings[0] = estate name + // strings[1] = str(owner_id) + // strings[2] = str(estate_id) + // strings[3] = str(estate_flags) + // strings[4] = str((S32)(sun_hour * 1024)) + // strings[5] = str(parent_estate_id) + // strings[6] = str(covenant_id) + // strings[7] = str(covenant_timestamp) + // strings[8] = str(send_to_agent_only) + // strings[9] = str(abuse_email_addr) + + LL_DEBUGS("ESTATEINFOM") << "Received estate update" << LL_ENDL; + + // Update estate info model. + // This will call LLPanelEstateInfo::refreshFromEstate(). + // *TODO: Move estate message handling stuff to llestateinfomodel.cpp. + LLEstateInfoModel::instance().updateEstateInfo(strings); + + return true; + } + }; + + class LLDispatchSetEstateAccess : public LLDispatchHandler + { + public: + LLDispatchSetEstateAccess() {} + virtual ~LLDispatchSetEstateAccess() {} + virtual bool operator()( + const LLDispatcher* dispatcher, const std::string& key, + const LLUUID& invoice, const sparam_t& strings) + { + // key = "setaccess" + // strings[0] = str(estate_id) + // strings[1] = str(packed_access_lists) + // strings[2] = str(num allowed agent ids) + // strings[3] = str(num allowed group ids) + // strings[4] = str(num banned agent ids) + // strings[5] = str(num estate manager agent ids) + // strings[6] = bin(uuid) + // strings[7] = bin(uuid) + // strings[8] = bin(uuid) + // ... + + LLEstateInfoModel::instance().updateAccessInfo(strings); + + return true; + } + + }; + + class LLDispatchSetEstateExperience : public LLDispatchHandler + { + public: + virtual bool operator()(const LLDispatcher* dispatcher, const std::string& key, + const LLUUID& invoice, const sparam_t& strings) + { + // key = "setexperience" + // strings[0] = str(estate_id) + // strings[1] = str(send_to_agent_only) + // strings[2] = str(num blocked) + // strings[3] = str(num trusted) + // strings[4] = str(num allowed) + // strings[8] = bin(uuid) ... + // ... + + LLEstateInfoModel::instance().updateExperienceInfo(strings); + + return true; + } + + }; + +} + +//========================================================================= +LLEstateInfoModel::LLEstateInfoModel(): + mID(0), + mFlags(0), + mSunHour(0), + mRegion(nullptr) { } @@ -51,40 +137,52 @@ boost::signals2::connection LLEstateInfoModel::setUpdateCallback(const update_si return mUpdateSignal.connect(cb); } +boost::signals2::connection LLEstateInfoModel::setUpdateAccessCallback(const update_flaged_signal_t::slot_type& cb) +{ + return mUpdateAccess.connect(cb); +} + +boost::signals2::connection LLEstateInfoModel::setUpdateExperienceCallback(const update_signal_t::slot_type& cb) +{ + return mUpdateExperience.connect(cb); +} + boost::signals2::connection LLEstateInfoModel::setCommitCallback(const update_signal_t::slot_type& cb) { return mCommitSignal.connect(cb); } +void LLEstateInfoModel::setRegion(LLViewerRegion* region) +{ + if (region != mRegion) + { + mRegion = region; + + if (mRegion) + { + nextInvoice(); + sendEstateOwnerMessage("getinfo", strings_t()); + } + } +} + + +void LLEstateInfoModel::clearRegion() +{ + mRegion = nullptr; +} + void LLEstateInfoModel::sendEstateInfo() { if (!commitEstateInfoCaps()) { // the caps method failed, try the old way - LLFloaterRegionInfo::nextInvoice(); + nextInvoice(); commitEstateInfoDataserver(); } } -bool LLEstateInfoModel::getUseFixedSun() const { return getFlag(REGION_FLAGS_SUN_FIXED); } -bool LLEstateInfoModel::getIsExternallyVisible() const { return getFlag(REGION_FLAGS_EXTERNALLY_VISIBLE); } -bool LLEstateInfoModel::getAllowDirectTeleport() const { return getFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT); } -bool LLEstateInfoModel::getDenyAnonymous() const { return getFlag(REGION_FLAGS_DENY_ANONYMOUS); } -bool LLEstateInfoModel::getDenyAgeUnverified() const { return getFlag(REGION_FLAGS_DENY_AGEUNVERIFIED); } -bool LLEstateInfoModel::getAllowVoiceChat() const { return getFlag(REGION_FLAGS_ALLOW_VOICE); } -bool LLEstateInfoModel::getAllowAccessOverride() const { return getFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE); } -bool LLEstateInfoModel::getAllowEnvironmentOverride() const { return getFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE); } - -void LLEstateInfoModel::setUseFixedSun(bool val) { setFlag(REGION_FLAGS_SUN_FIXED, val); } -void LLEstateInfoModel::setIsExternallyVisible(bool val) { setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE, val); } -void LLEstateInfoModel::setAllowDirectTeleport(bool val) { setFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, val); } -void LLEstateInfoModel::setDenyAnonymous(bool val) { setFlag(REGION_FLAGS_DENY_ANONYMOUS, val); } -void LLEstateInfoModel::setDenyAgeUnverified(bool val) { setFlag(REGION_FLAGS_DENY_AGEUNVERIFIED, val); } -void LLEstateInfoModel::setAllowVoiceChat(bool val) { setFlag(REGION_FLAGS_ALLOW_VOICE, val); } -void LLEstateInfoModel::setAllowAccessOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE, val); } -void LLEstateInfoModel::setAllowEnvironmentOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE, val); } - -void LLEstateInfoModel::update(const strings_t& strings) +void LLEstateInfoModel::updateEstateInfo(const strings_t& strings) { // NOTE: LLDispatcher extracts strings with an extra \0 at the // end. If we pass the std::string direct to the UI/renderer @@ -95,10 +193,10 @@ void LLEstateInfoModel::update(const strings_t& strings) mFlags = strtoul(strings[3].c_str(), NULL, 10); mSunHour = ((F32)(strtod(strings[4].c_str(), NULL)))/1024.0f; - LL_DEBUGS("WindlightSync") << "Received estate info: " + LL_DEBUGS("ESTATEINFOM") << "Received estate info: " << "is_sun_fixed = " << getUseFixedSun() << ", sun_hour = " << getSunHour() << LL_ENDL; - LL_DEBUGS() << getInfoDump() << LL_ENDL; + LL_DEBUGS("ESTATEINFOM") << getInfoDump() << LL_ENDL; // Update region owner. LLViewerRegion* regionp = gAgent.getRegion(); @@ -108,20 +206,205 @@ void LLEstateInfoModel::update(const strings_t& strings) mUpdateSignal(); } +void LLEstateInfoModel::updateAccessInfo(const strings_t& strings) +{ + S32 index = 1; // skip estate_id + U32 access_flags = strtoul(strings[index++].c_str(), NULL, 10); + S32 num_allowed_agents = strtol(strings[index++].c_str(), NULL, 10); + S32 num_allowed_groups = strtol(strings[index++].c_str(), NULL, 10); + S32 num_banned_agents = strtol(strings[index++].c_str(), NULL, 10); + S32 num_estate_managers = strtol(strings[index++].c_str(), NULL, 10); + + // sanity ckecks + if (num_allowed_agents > 0 + && !(access_flags & ESTATE_ACCESS_ALLOWED_AGENTS)) + { + LL_WARNS("ESTATEINFOM") << "non-zero count for allowed agents, but no corresponding flag" << LL_ENDL; + } + if (num_allowed_groups > 0 + && !(access_flags & ESTATE_ACCESS_ALLOWED_GROUPS)) + { + LL_WARNS("ESTATEINFOM") << "non-zero count for allowed groups, but no corresponding flag" << LL_ENDL; + } + if (num_banned_agents > 0 + && !(access_flags & ESTATE_ACCESS_BANNED_AGENTS)) + { + LL_WARNS("ESTATEINFOM") << "non-zero count for banned agents, but no corresponding flag" << LL_ENDL; + } + if (num_estate_managers > 0 + && !(access_flags & ESTATE_ACCESS_MANAGERS)) + { + LL_WARNS("ESTATEINFOM") << "non-zero count for managers, but no corresponding flag" << LL_ENDL; + } + + // grab the UUID's out of the string fields + if (access_flags & ESTATE_ACCESS_ALLOWED_AGENTS) + { + mAllowedAgents.clear(); + + for (S32 i = 0; i < num_allowed_agents && i < ESTATE_MAX_ACCESS_IDS; i++) + { + LLUUID id; + memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ + mAllowedAgents.insert(id); + } + } + + if (access_flags & ESTATE_ACCESS_ALLOWED_GROUPS) + { + mAllowedGroups.clear(); + + for (S32 i = 0; i < num_allowed_groups && i < ESTATE_MAX_GROUP_IDS; i++) + { + LLUUID id; + memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ + mAllowedGroups.insert(id); + } + } + + if (access_flags & ESTATE_ACCESS_BANNED_AGENTS) + { + mBannedAgents.clear(); + + for (S32 i = 0; i < num_banned_agents && i < ESTATE_MAX_ACCESS_IDS; i++) + { + LLUUID id; + memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ + mBannedAgents.insert(id); + } + } + + if (access_flags & ESTATE_ACCESS_MANAGERS) + { + mEstateManagers.clear(); + + // There should be only ESTATE_MAX_MANAGERS people in the list, but if the database gets more (SL-46107) don't + // truncate the list unless it's really big. Go ahead and show the extras so the user doesn't get confused, + // and they can still remove them. + for (S32 i = 0; i < num_estate_managers && i < (ESTATE_MAX_MANAGERS * 4); i++) + { + LLUUID id; + memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ + mEstateManagers.insert(id); + } + } + + // Update the buttons which may change based on the list contents but also needs to account for general access features. + mUpdateAccess(access_flags); +} + +void LLEstateInfoModel::updateExperienceInfo(const strings_t& strings) +{ + strings_t::const_iterator it = strings.begin(); + ++it; // U32 estate_id = strtol((*it).c_str(), NULL, 10); + ++it; // U32 send_to_agent_only = strtoul((*(++it)).c_str(), NULL, 10); + + LLUUID id; + S32 num_blocked = strtol((*(it++)).c_str(), NULL, 10); + S32 num_trusted = strtol((*(it++)).c_str(), NULL, 10); + S32 num_allowed = strtol((*(it++)).c_str(), NULL, 10); + + mExperienceAllowed.clear(); + mExperienceTrusted.clear(); + mExperienceBlocked.clear(); + + while (num_blocked-- > 0) + { + memcpy(id.mData, (*(it++)).data(), UUID_BYTES); + mExperienceBlocked.insert(id); + } + + while (num_trusted-- > 0) + { + memcpy(id.mData, (*(it++)).data(), UUID_BYTES); + mExperienceTrusted.insert(id); + } + + while (num_allowed-- > 0) + { + memcpy(id.mData, (*(it++)).data(), UUID_BYTES); + mExperienceAllowed.insert(id); + } + + mUpdateExperience(); +} + void LLEstateInfoModel::notifyCommit() { mCommitSignal(); } +void LLEstateInfoModel::initSingleton() +{ + gMessageSystem->setHandlerFunc("EstateOwnerMessage", &processEstateOwnerRequest); + + // name.assign("setowner"); + // static LLDispatchSetEstateOwner set_owner; + // dispatch.addHandler(name, &set_owner); + + static LLDispatchEstateUpdateInfo estate_update_info; + mDispatch.addHandler("estateupdateinfo", &estate_update_info); + + static LLDispatchSetEstateAccess set_access; + mDispatch.addHandler("setaccess", &set_access); + + static LLDispatchSetEstateExperience set_experience; + mDispatch.addHandler("setexperience", &set_experience); + +} + +void LLEstateInfoModel::sendEstateOwnerMessage(const std::string& request, const strings_t& strings) +{ + if (!mRegion) + { + LL_WARNS("ESTATEINFOM") << "No selected region." << LL_ENDL; + return; + } + LLMessageSystem* msg(gMessageSystem); + LLUUID invoice(LLEstateInfoModel::instance().getLastInvoice()); + + LL_INFOS() << "Sending estate request '" << request << "'" << LL_ENDL; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + msg->nextBlock("MethodData"); + msg->addString("Method", request); + msg->addUUID("Invoice", invoice); + if (strings.empty()) + { + msg->nextBlock("ParamList"); + msg->addString("Parameter", NULL); + } + else + { + strings_t::const_iterator it = strings.begin(); + strings_t::const_iterator end = strings.end(); + for (; it != end; ++it) + { + msg->nextBlock("ParamList"); + msg->addString("Parameter", *it); + } + } + msg->sendReliable(mRegion->getHost()); +} + //== PRIVATE STUFF ============================================================ // tries to send estate info using a cap; returns true if it succeeded bool LLEstateInfoModel::commitEstateInfoCaps() { - std::string url = gAgent.getRegionCapability("EstateChangeInfo"); + if (!mRegion) + { + LL_WARNS("ESTATEINFOM") << "Attempt to update estate caps with no anchor region! Don't do that!" << LL_ENDL; + return false; + } + std::string url = mRegion->getCapability("EstateChangeInfo"); if (url.empty()) { + LL_WARNS("ESTATEINFOM") << "No EstateChangeInfo cap from region." << LL_ENDL; // whoops, couldn't find the cap, so bail out return false; } @@ -152,12 +435,12 @@ void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url) body["override_public_access"] = getAllowAccessOverride(); body["override_environment"] = getAllowEnvironmentOverride(); - body["invoice"] = LLFloaterRegionInfo::getLastInvoice(); + body["invoice"] = getLastInvoice(); - LL_DEBUGS("WindlightSync") << "Sending estate caps: " + LL_DEBUGS("ESTATEINFOM") << "Sending estate caps: " << "is_sun_fixed = " << getUseFixedSun() << ", sun_hour = " << getSunHour() << LL_ENDL; - LL_DEBUGS() << body << LL_ENDL; + LL_DEBUGS("ESTATEINFOM") << body << LL_ENDL; LLSD result = httpAdapter->postAndSuspend(httpRequest, url, body); @@ -166,12 +449,12 @@ void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url) if (status) { - LL_INFOS() << "Committed estate info" << LL_ENDL; + LL_INFOS("ESTATEINFOM") << "Committed estate info" << LL_ENDL; LLEstateInfoModel::instance().notifyCommit(); } else { - LL_WARNS() << "Failed to commit estate info " << LL_ENDL; + LL_WARNS("ESTATEINFOM") << "Failed to commit estate info " << LL_ENDL; } } @@ -184,10 +467,15 @@ void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url) // strings[3] = str((S32)(sun_hour * 1024.f)) void LLEstateInfoModel::commitEstateInfoDataserver() { - LL_DEBUGS("WindlightSync") << "Sending estate info: " + if (!mRegion) + { + LL_WARNS("ESTATEINFOM") << "No selected region." << LL_ENDL; + return; + } + LL_DEBUGS("ESTATEINFOM") << "Sending estate info: " << "is_sun_fixed = " << getUseFixedSun() << ", sun_hour = " << getSunHour() << LL_ENDL; - LL_DEBUGS() << getInfoDump() << LL_ENDL; + LL_DEBUGS("ESTATEINFOM") << getInfoDump() << LL_ENDL; LLMessageSystem* msg = gMessageSystem; msg->newMessage("EstateOwnerMessage"); @@ -198,7 +486,7 @@ void LLEstateInfoModel::commitEstateInfoDataserver() msg->nextBlock("MethodData"); msg->addString("Method", "estatechangeinfo"); - msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); + msg->addUUID("Invoice", getLastInvoice()); msg->nextBlock("ParamList"); msg->addString("Parameter", getName()); @@ -209,7 +497,7 @@ void LLEstateInfoModel::commitEstateInfoDataserver() msg->nextBlock("ParamList"); msg->addString("Parameter", llformat("%d", (S32) (getSunHour() * 1024.0f))); - gAgent.sendMessage(); + msg->sendReliable(mRegion->getHost()); } std::string LLEstateInfoModel::getInfoDump() @@ -231,3 +519,22 @@ std::string LLEstateInfoModel::getInfoDump() dump_str << dump; return dump_str.str(); } + +// static +void LLEstateInfoModel::processEstateOwnerRequest(LLMessageSystem* msg, void**) +{ + // unpack the message + std::string request; + LLUUID invoice; + LLDispatcher::sparam_t strings; + LLDispatcher::unpackMessage(msg, request, invoice, strings); + if (invoice != LLEstateInfoModel::instance().getLastInvoice()) + { + LL_WARNS("ESTATEINFOM") << "Mismatched Estate message: " << request << LL_ENDL; + return; + } + + //dispatch the message + LLEstateInfoModel::instance().mDispatch.dispatch(request, invoice, strings); +} + |