diff options
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); +} + |